diff --git a/.circleci/config.yml b/.circleci/config.yml index 6d04a1de6c37..c23db1d2268f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,10 +25,6 @@ executors: resource_class: medium+ environment: NODE_OPTIONS: --max_old_space_size=4096 - shellcheck: - docker: - - image: koalaman/shellcheck-alpine@sha256:dfaf08fab58c158549d3be64fb101c626abc5f16f341b569092577ae207db199 - resource_class: small playwright: docker: - image: mcr.microsoft.com/playwright:v1.44.1-focal @@ -114,27 +110,6 @@ workflows: - master requires: - prep-deps - - test-deps-audit: - requires: - - prep-deps - - test-deps-depcheck: - requires: - - prep-deps - - test-yarn-dedupe: - requires: - - prep-deps - - validate-lavamoat-allow-scripts: - requires: - - prep-deps - - validate-lavamoat-policy-build: - requires: - - prep-deps - - validate-lavamoat-policy-webapp: - matrix: - parameters: - build-type: [main, beta, flask, mmi] - requires: - - prep-deps - prep-build: requires: - prep-deps @@ -160,7 +135,6 @@ workflows: requires: - prep-deps - prep-build-test-flask-mv2: - <<: *main_master_rc_only requires: - prep-deps - prep-build-storybook: @@ -169,16 +143,6 @@ workflows: - prep-build-ts-migration-dashboard: requires: - prep-deps - - test-lint: - requires: - - prep-deps - - test-lint-shellcheck - - test-lint-lockfile: - requires: - - prep-deps - - test-lint-changelog: - requires: - - prep-deps - test-e2e-chrome-webpack: <<: *main_master_rc_only requires: @@ -253,14 +217,6 @@ workflows: - prep-build-flask-mv2 - all-tests-pass: requires: - - test-deps-depcheck - - validate-lavamoat-allow-scripts - - validate-lavamoat-policy-build - - validate-lavamoat-policy-webapp - - test-lint - - test-lint-shellcheck - - test-lint-lockfile - - test-lint-changelog - validate-source-maps - validate-source-maps-beta - validate-source-maps-flask @@ -280,7 +236,7 @@ workflows: - user-actions-benchmark: requires: - prep-build-test - - stats-module-load-init: + - bundle-size: requires: - prep-build-test - job-publish-prerelease: @@ -288,14 +244,18 @@ workflows: - prep-deps - prep-build - prep-build-mv2 - - trigger-beta-build - prep-build-flask - prep-build-flask-mv2 + - prep-build-test + - prep-build-test-mv2 + - prep-build-test-flask + - prep-build-test-flask-mv2 + - trigger-beta-build - prep-build-storybook - prep-build-ts-migration-dashboard - benchmark - user-actions-benchmark - - stats-module-load-init + - bundle-size - all-tests-pass - job-publish-release: filters: @@ -466,51 +426,6 @@ jobs: at: . - run: yarn tsx .circleci/scripts/validate-locales-only.ts - validate-lavamoat-allow-scripts: - executor: node-browsers-small - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: Validate allow-scripts config - command: yarn allow-scripts auto - - run: - name: Check working tree - command: .circleci/scripts/check-working-tree.sh - - validate-lavamoat-policy-build: - executor: node-browsers-medium - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: Validate LavaMoat build policy - command: yarn lavamoat:build:auto - - run: - name: Check working tree - command: .circleci/scripts/check-working-tree.sh - - validate-lavamoat-policy-webapp: - executor: node-browsers-medium-plus - parameters: - build-type: - type: string - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: Validate LavaMoat << parameters.build-type >> policy - command: yarn lavamoat:webapp:auto:ci '--build-types=<< parameters.build-type >>' - - run: - name: Check working tree - command: .circleci/scripts/check-working-tree.sh - prep-build: executor: node-linux-medium steps: @@ -706,10 +621,10 @@ jobs: name: Build extension for testing command: yarn build:test:flask:mv2 - run: - name: Move test build to 'dist-test-flask' to avoid conflict with production build + name: Move test build to 'dist-test-flask-mv2' to avoid conflict with production build command: mv ./dist ./dist-test-flask-mv2 - run: - name: Move test zips to 'builds-test-flask' to avoid conflict with production build + name: Move test zips to 'builds-test-flask-mv2' to avoid conflict with production build command: mv ./builds ./builds-test-flask-mv2 - persist_to_workspace: root: . @@ -826,31 +741,6 @@ jobs: name: Rerun workflows from failed command: yarn ci-rerun-from-failed - test-yarn-dedupe: - executor: node-browsers-small - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: Detect yarn lock deduplications - command: yarn dedupe --check - - test-lint: - executor: node-browsers-medium - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: Lint - command: yarn lint - - run: - name: Verify locales - command: yarn verify-locales --quiet - test-storybook: executor: node-browsers-medium-plus steps: @@ -865,78 +755,6 @@ jobs: name: Test Storybook command: yarn test-storybook:ci - test-lint-shellcheck: - executor: shellcheck - steps: - - checkout - - run: apk add --no-cache bash jq yarn - - run: - name: ShellCheck Lint - command: ./development/shellcheck.sh - - test-lint-lockfile: - executor: node-browsers-medium-plus - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: lockfile-lint - command: yarn lint:lockfile - - run: - name: check yarn resolutions - command: yarn --check-resolutions - - test-lint-changelog: - executor: node-browsers-small - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - when: - condition: - not: - matches: - pattern: /^Version-v(\d+)[.](\d+)[.](\d+)$/ - value: << pipeline.git.branch >> - steps: - - run: - name: Validate changelog - command: yarn lint:changelog - - when: - condition: - matches: - pattern: /^Version-v(\d+)[.](\d+)[.](\d+)$/ - value: << pipeline.git.branch >> - steps: - - run: - name: Validate release candidate changelog - command: .circleci/scripts/validate-changelog-in-rc.sh - - test-deps-audit: - executor: node-browsers-small - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: yarn audit - command: yarn audit - - test-deps-depcheck: - executor: node-browsers-small - steps: - - run: *shallow-git-clone-and-enable-vnc - - run: sudo corepack enable - - attach_workspace: - at: . - - run: - name: depcheck - command: yarn depcheck - test-e2e-chrome-webpack: executor: node-browsers-medium-plus parallelism: 20 @@ -1228,7 +1046,7 @@ jobs: paths: - test-artifacts - stats-module-load-init: + bundle-size: executor: node-browsers-small steps: - run: *shallow-git-clone-and-enable-vnc @@ -1242,16 +1060,8 @@ jobs: name: Move test zips to builds command: mv ./builds-test ./builds - run: - name: Run page load benchmark - command: | - mkdir -p test-artifacts/chrome/ - cp -R development/charts/flamegraph test-artifacts/chrome/initialisation - cp -R development/charts/flamegraph/chart test-artifacts/chrome/initialisation/background - cp -R development/charts/flamegraph/chart test-artifacts/chrome/initialisation/ui - cp -R development/charts/table test-artifacts/chrome/load_time - - run: - name: Run page load benchmark - command: yarn mv3:stats:chrome --out test-artifacts/chrome + name: Measure bundle size + command: yarn bundle-size --out test-artifacts/chrome - run: name: Install jq command: sudo apt install jq -y @@ -1303,8 +1113,12 @@ jobs: destination: builds-mv2 - store_artifacts: path: builds-test + - store_artifacts: + path: builds-test-mv2 - store_artifacts: path: builds-test-flask + - store_artifacts: + path: builds-test-flask-mv2 - store_artifacts: path: test-artifacts destination: test-artifacts @@ -1321,14 +1135,6 @@ jobs: - store_artifacts: path: development/ts-migration-dashboard/build/final destination: ts-migration-dashboard - - run: - name: Set branch parent commit env var - command: | - echo "export PARENT_COMMIT=$(git merge-base origin/HEAD HEAD)" >> $BASH_ENV - source $BASH_ENV - - run: - name: build:announce - command: ./development/metamaskbot-build-announce.js job-publish-release: executor: node-browsers-small diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ad36b9b96efd..bb1055ada8f9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,7 +13,7 @@ # audit these changes on their own, and leave their analysis in a comment. # These codeowners will review this analysis, and review the policy changes in # further detail if warranted. -lavamoat/ @MetaMask/extension-devs @MetaMask/supply-chain +lavamoat/ @MetaMask/extension-devs @MetaMask/policy-reviewers @MetaMask/supply-chain # The offscreen.ts script file that is included in the offscreen document html # file is responsible, at present, for loading the snaps execution environment diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c7907455701d..3b31cb2c9266 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,6 +5,7 @@ on: branches: - main - master + - Version-v* pull_request: types: - opened @@ -13,20 +14,49 @@ on: merge_group: jobs: - check-workflows: - name: Check workflows - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + lint-workflows: + name: Lint workflows + uses: metamask/github-tools/.github/workflows/lint-workflows.yml@c534f265e02af2f2422a3c686bb09a11bfbf4cc2 + + test-lint-shellcheck: + name: Test lint shellcheck + uses: ./.github/workflows/test-lint-shellcheck.yml + + test-lint: + name: Test lint + uses: ./.github/workflows/test-lint.yml + + test-lint-changelog: + name: Test lint changelog + uses: ./.github/workflows/test-lint-changelog.yml + + test-lint-lockfile: + name: Test lint lockfile + uses: ./.github/workflows/test-lint-lockfile.yml + + test-deps-audit: + name: Test deps audit + uses: ./.github/workflows/test-deps-audit.yml + + test-yarn-dedupe: + name: Test yarn dedupe + uses: ./.github/workflows/test-yarn-dedupe.yml + + test-deps-depcheck: + name: Test deps depcheck + uses: ./.github/workflows/test-deps-depcheck.yml - - name: Download actionlint - id: download-actionlint - run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash) 1.6.23 - shell: bash + validate-lavamoat-allow-scripts: + name: Validate lavamoat allow scripts + uses: ./.github/workflows/validate-lavamoat-allow-scripts.yml - - name: Check workflow files - run: ${{ steps.download-actionlint.outputs.executable }} -color - shell: bash + validate-lavamoat-policy-build: + name: Validate lavamoat policy build + uses: ./.github/workflows/validate-lavamoat-policy-build.yml + + validate-lavamoat-policy-webapp: + name: Validate lavamoat policy webapp + uses: ./.github/workflows/validate-lavamoat-policy-webapp.yml run-tests: name: Run tests @@ -36,11 +66,38 @@ jobs: name: Wait for CircleCI workflow status uses: ./.github/workflows/wait-for-circleci-workflow-status.yml + runway: + name: Runway + # For a `pull_request` event, the branch is `github.head_ref``. + # For a `push` event, the branch is `github.ref_name`. + if: ${{ startsWith(github.head_ref || github.ref_name, 'Version-v') }} + needs: + - wait-for-circleci-workflow-status + uses: ./.github/workflows/runway.yml + + publish-prerelease: + name: Publish prerelease + if: ${{ github.event_name == 'pull_request' }} + needs: + - wait-for-circleci-workflow-status + uses: ./.github/workflows/publish-prerelease.yml + secrets: + PR_COMMENT_TOKEN: ${{ secrets.PR_COMMENT_TOKEN }} + all-jobs-completed: name: All jobs completed runs-on: ubuntu-latest needs: - - check-workflows + - lint-workflows + - test-lint-shellcheck + - test-lint + - test-lint-changelog + - test-lint-lockfile + - test-yarn-dedupe + - test-deps-depcheck + - validate-lavamoat-allow-scripts + - validate-lavamoat-policy-build + - validate-lavamoat-policy-webapp - run-tests - wait-for-circleci-workflow-status outputs: diff --git a/.github/workflows/publish-prerelease.yml b/.github/workflows/publish-prerelease.yml new file mode 100644 index 000000000000..2674b8565eff --- /dev/null +++ b/.github/workflows/publish-prerelease.yml @@ -0,0 +1,75 @@ +name: Publish prerelease + +on: + workflow_call: + secrets: + PR_COMMENT_TOKEN: + required: true + +jobs: + publish-prerelease: + name: Publish prerelease + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # This is needed to get merge base to calculate bundle size diff + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Get merge base commit hash + id: get-merge-base + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: | + merge_base="$(git merge-base "origin/${BASE_REF}" HEAD)" + echo "MERGE_BASE=${merge_base}" >> "$GITHUB_OUTPUT" + echo "Merge base is '${merge_base}'" + + - name: Get CircleCI job details + id: get-circleci-job-details + env: + OWNER: ${{ github.repository_owner }} + REPOSITORY: ${{ github.event.repository.name }} + # For a `pull_request` event, the branch is `github.head_ref``. + BRANCH: ${{ github.head_ref }} + # For a `pull_request` event, the head commit hash is `github.event.pull_request.head.sha`. + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + JOB_NAME: job-publish-prerelease + run: | + pipeline_id=$(curl --silent "https://circleci.com/api/v2/project/gh/$OWNER/$REPOSITORY/pipeline?branch=$BRANCH" | jq --arg head_commit_hash "${HEAD_COMMIT_HASH}" -r '.items | map(select(.vcs.revision == $head_commit_hash)) | first | .id') + workflow_id=$(curl --silent "https://circleci.com/api/v2/pipeline/$pipeline_id/workflow" | jq -r ".items[0].id") + job_details=$(curl --silent "https://circleci.com/api/v2/workflow/$workflow_id/job" | jq --arg job_name "${JOB_NAME}" -r '.items[] | select(.name == $job_name)') + + build_num=$(echo "$job_details" | jq -r '.job_number') + echo 'CIRCLE_BUILD_NUM='"$build_num" >> "$GITHUB_OUTPUT" + + job_id=$(echo "$job_details" | jq -r '.id') + echo 'CIRCLE_WORKFLOW_JOB_ID='"$job_id" >> "$GITHUB_OUTPUT" + + echo "Getting artifacts from pipeline '${pipeline_id}', workflow '${workflow_id}', build number '${build_num}', job id '${job_id}'" + + - name: Get CircleCI job artifacts + env: + CIRCLE_WORKFLOW_JOB_ID: ${{ steps.get-circleci-job-details.outputs.CIRCLE_WORKFLOW_JOB_ID }} + run: | + mkdir -p test-artifacts/chrome/benchmark + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/test-artifacts/chrome/benchmark/pageload.json" > "test-artifacts/chrome/benchmark/pageload.json" + + mkdir -p test-artifacts/chrome + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/test-artifacts/chrome/bundle_size.json" > "test-artifacts/chrome/bundle_size.json" + + mkdir storybook-build + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/storybook/stories.json" > "storybook-build/stories.json" + + - name: Publish prerelease + env: + PR_COMMENT_TOKEN: ${{ secrets.PR_COMMENT_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + MERGE_BASE_COMMIT_HASH: ${{ steps.get-merge-base.outputs.MERGE_BASE }} + CIRCLE_BUILD_NUM: ${{ steps.get-circleci-job-details.outputs.CIRCLE_BUILD_NUM }} + CIRCLE_WORKFLOW_JOB_ID: ${{ steps.get-circleci-job-details.outputs.CIRCLE_WORKFLOW_JOB_ID }} + run: ./development/metamaskbot-build-announce.js diff --git a/.github/workflows/runway.yml b/.github/workflows/runway.yml new file mode 100644 index 000000000000..98f738c69154 --- /dev/null +++ b/.github/workflows/runway.yml @@ -0,0 +1,71 @@ +name: Runway + +on: + workflow_call: + +jobs: + runway: + name: Runway + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Get build version + id: get-build-version + run: | + build_version=$(jq -r '.version' package.json) + echo 'BUILD_VERSION='"$build_version" >> "$GITHUB_OUTPUT" + echo "Build version is '${build_version}'" + + - name: Get CircleCI job details + id: get-circleci-job-details + env: + OWNER: ${{ github.repository_owner }} + REPOSITORY: ${{ github.event.repository.name }} + # For a `pull_request` event, the branch is `github.head_ref``. + # For a `push` event, the branch is `github.ref_name`. + BRANCH: ${{ github.head_ref || github.ref_name }} + # For a `pull_request` event, the head commit hash is `github.event.pull_request.head.sha`. + # For a `push` event, the head commit hash is `github.sha`. + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }} + JOB_NAME: job-publish-prerelease + run: | + pipeline_id=$(curl --silent "https://circleci.com/api/v2/project/gh/$OWNER/$REPOSITORY/pipeline?branch=$BRANCH" | jq --arg head_commit_hash "${HEAD_COMMIT_HASH}" -r '.items | map(select(.vcs.revision == $head_commit_hash)) | first | .id') + workflow_id=$(curl --silent "https://circleci.com/api/v2/pipeline/$pipeline_id/workflow" | jq -r ".items[0].id") + job_details=$(curl --silent "https://circleci.com/api/v2/workflow/$workflow_id/job" | jq --arg job_name "${JOB_NAME}" -r '.items[] | select(.name == $job_name)') + + job_id=$(echo "$job_details" | jq -r '.id') + echo 'CIRCLE_WORKFLOW_JOB_ID='"$job_id" >> "$GITHUB_OUTPUT" + + echo "Getting artifacts from pipeline '${pipeline_id}', workflow '${workflow_id}', job id '${job_id}'" + + - name: Download builds from CircleCI + env: + BUILD_VERSION: ${{ steps.get-build-version.outputs.BUILD_VERSION }} + CIRCLE_WORKFLOW_JOB_ID: ${{ steps.get-circleci-job-details.outputs.CIRCLE_WORKFLOW_JOB_ID }} + run: | + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/builds/metamask-chrome-${BUILD_VERSION}.zip" > "metamask-chrome-${BUILD_VERSION}.zip" + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/builds-mv2/metamask-firefox-${BUILD_VERSION}.zip" > "metamask-firefox-${BUILD_VERSION}.zip" + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/builds-flask/metamask-flask-chrome-${BUILD_VERSION}-flask.0.zip" > "metamask-flask-chrome-${BUILD_VERSION}-flask.0.zip" + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/builds-flask-mv2/metamask-flask-firefox-${BUILD_VERSION}-flask.0.zip" > "metamask-flask-firefox-${BUILD_VERSION}-flask.0.zip" + + - uses: actions/upload-artifact@v4 + with: + name: metamask-chrome-${{ steps.get-build-version.outputs.BUILD_VERSION }} + path: metamask-chrome-${{ steps.get-build-version.outputs.BUILD_VERSION }}.zip + + - uses: actions/upload-artifact@v4 + with: + name: metamask-firefox-${{ steps.get-build-version.outputs.BUILD_VERSION }} + path: metamask-firefox-${{ steps.get-build-version.outputs.BUILD_VERSION }}.zip + + - uses: actions/upload-artifact@v4 + with: + name: metamask-flask-chrome-${{ steps.get-build-version.outputs.BUILD_VERSION }}-flask.0 + path: metamask-flask-chrome-${{ steps.get-build-version.outputs.BUILD_VERSION }}-flask.0.zip + + - uses: actions/upload-artifact@v4 + with: + name: metamask-flask-firefox-${{ steps.get-build-version.outputs.BUILD_VERSION }}-flask.0 + path: metamask-flask-firefox-${{ steps.get-build-version.outputs.BUILD_VERSION }}-flask.0.zip diff --git a/.github/workflows/test-deps-audit.yml b/.github/workflows/test-deps-audit.yml new file mode 100644 index 000000000000..271746da2429 --- /dev/null +++ b/.github/workflows/test-deps-audit.yml @@ -0,0 +1,18 @@ +name: Test deps audit + +on: + workflow_call: + +jobs: + test-deps-audit: + name: Test deps audit + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Run audit + run: yarn audit diff --git a/.github/workflows/test-deps-depcheck.yml b/.github/workflows/test-deps-depcheck.yml new file mode 100644 index 000000000000..3860c485f25b --- /dev/null +++ b/.github/workflows/test-deps-depcheck.yml @@ -0,0 +1,18 @@ +name: Test deps depcheck + +on: + workflow_call: + +jobs: + test-deps-depcheck: + name: Test deps depcheck + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Run depcheck + run: yarn depcheck diff --git a/.github/workflows/test-lint-changelog.yml b/.github/workflows/test-lint-changelog.yml new file mode 100644 index 000000000000..9e8ee0e992c8 --- /dev/null +++ b/.github/workflows/test-lint-changelog.yml @@ -0,0 +1,27 @@ +name: Test lint changelog + +on: + workflow_call: + +jobs: + test-lint-changelog: + name: Test lint changelog + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Validate changelog + # For a `pull_request` event, the branch is `github.head_ref``. + # For a `push` event, the branch is `github.ref_name`. + if: ${{ !startsWith(github.head_ref || github.ref_name, 'Version-v') }} + run: yarn lint:changelog + + - name: Validate release candidate changelog + # For a `pull_request` event, the branch is `github.head_ref``. + # For a `push` event, the branch is `github.ref_name`. + if: ${{ startsWith(github.head_ref || github.ref_name, 'Version-v') }} + run: .circleci/scripts/validate-changelog-in-rc.sh diff --git a/.github/workflows/test-lint-lockfile.yml b/.github/workflows/test-lint-lockfile.yml new file mode 100644 index 000000000000..cc84318624ce --- /dev/null +++ b/.github/workflows/test-lint-lockfile.yml @@ -0,0 +1,21 @@ +name: Test lint lockfile + +on: + workflow_call: + +jobs: + test-lint-lockfile: + name: Test lint lockfile + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Lint lockfile + run: yarn lint:lockfile + + - name: Check yarn resolutions + run: yarn --check-resolutions diff --git a/.github/workflows/test-lint-shellcheck.yml b/.github/workflows/test-lint-shellcheck.yml new file mode 100644 index 000000000000..c4127902a2f4 --- /dev/null +++ b/.github/workflows/test-lint-shellcheck.yml @@ -0,0 +1,15 @@ +name: Test lint shellcheck + +on: + workflow_call: + +jobs: + test-lint-shellcheck: + name: Test lint shellcheck + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: ShellCheck Lint + run: ./development/shellcheck.sh diff --git a/.github/workflows/test-lint.yml b/.github/workflows/test-lint.yml new file mode 100644 index 000000000000..df40a3a7ef27 --- /dev/null +++ b/.github/workflows/test-lint.yml @@ -0,0 +1,21 @@ +name: Test lint + +on: + workflow_call: + +jobs: + test-lint: + name: Test lint + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Lint + run: yarn lint + + - name: Verify locales + run: yarn verify-locales --quiet diff --git a/.github/workflows/test-yarn-dedupe.yml b/.github/workflows/test-yarn-dedupe.yml new file mode 100644 index 000000000000..40bda1dfb3d2 --- /dev/null +++ b/.github/workflows/test-yarn-dedupe.yml @@ -0,0 +1,18 @@ +name: Test yarn dedupe + +on: + workflow_call: + +jobs: + test-yarn-dedupe: + name: Test yarn dedupe + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Detect yarn lock deduplications + run: yarn dedupe --check diff --git a/.github/workflows/validate-lavamoat-allow-scripts.yml b/.github/workflows/validate-lavamoat-allow-scripts.yml new file mode 100644 index 000000000000..637a2d9aeb54 --- /dev/null +++ b/.github/workflows/validate-lavamoat-allow-scripts.yml @@ -0,0 +1,25 @@ +name: Validate lavamoat allow scripts + +on: + workflow_call: + +jobs: + validate-lavamoat-allow-scripts: + name: Validate lavamoat allow scripts + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Validate allow-scripts config + run: yarn allow-scripts auto + + - name: Check working tree + run: | + if ! git diff --exit-code; then + echo "::error::Working tree dirty." + exit 1 + fi diff --git a/.github/workflows/validate-lavamoat-policy-build.yml b/.github/workflows/validate-lavamoat-policy-build.yml new file mode 100644 index 000000000000..4524cc26a546 --- /dev/null +++ b/.github/workflows/validate-lavamoat-policy-build.yml @@ -0,0 +1,27 @@ +name: Validate lavamoat policy build + +on: + workflow_call: + +jobs: + validate-lavamoat-policy-build: + name: Validate lavamoat policy build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Validate lavamoat build policy + run: yarn lavamoat:build:auto + env: + INFURA_PROJECT_ID: 00000000000 + + - name: Check working tree + run: | + if ! git diff --exit-code; then + echo "::error::Working tree dirty." + exit 1 + fi diff --git a/.github/workflows/validate-lavamoat-policy-webapp.yml b/.github/workflows/validate-lavamoat-policy-webapp.yml new file mode 100644 index 000000000000..37ff9ede00fc --- /dev/null +++ b/.github/workflows/validate-lavamoat-policy-webapp.yml @@ -0,0 +1,30 @@ +name: Validate lavamoat policy webapp + +on: + workflow_call: + +jobs: + validate-lavamoat-policy-webapp: + name: Validate lavamoat policy webapp + runs-on: ubuntu-latest + strategy: + matrix: + build-type: [main, beta, flask, mmi] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Validate lavamoat ${{ matrix.build-type }} policy + run: yarn lavamoat:webapp:auto:ci --build-types=${{ matrix.build-type }} + env: + INFURA_PROJECT_ID: 00000000000 + + - name: Check working tree + run: | + if ! git diff --exit-code; then + echo "::error::Working tree dirty." + exit 1 + fi diff --git a/.github/workflows/wait-for-circleci-workflow-status.yml b/.github/workflows/wait-for-circleci-workflow-status.yml index 18e5ef7825d5..30efc6d35776 100644 --- a/.github/workflows/wait-for-circleci-workflow-status.yml +++ b/.github/workflows/wait-for-circleci-workflow-status.yml @@ -12,9 +12,15 @@ jobs: env: OWNER: ${{ github.repository_owner }} REPOSITORY: ${{ github.event.repository.name }} + # For a `pull_request` event, the branch is `github.head_ref``. + # For a `push` event, the branch is `github.ref_name`. BRANCH: ${{ github.head_ref || github.ref_name }} + # For a `pull_request` event, the head commit hash is `github.event.pull_request.head.sha`. + # For a `push` event, the head commit hash is `github.sha`. + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }} run: | - pipeline_id=$(curl --silent "https://circleci.com/api/v2/project/gh/$OWNER/$REPOSITORY/pipeline?branch=$BRANCH" | jq -r ".items[0].id") + pipeline_id=$(curl --silent "https://circleci.com/api/v2/project/gh/$OWNER/$REPOSITORY/pipeline?branch=$BRANCH" | jq --arg head_commit_hash "${HEAD_COMMIT_HASH}" -r '.items | map(select(.vcs.revision == $head_commit_hash)) | first | .id') + echo "Waiting for pipeline '${pipeline_id}', commit hash '${HEAD_COMMIT_HASH}'" workflow_status=$(curl --silent "https://circleci.com/api/v2/pipeline/$pipeline_id/workflow" | jq -r ".items[0].status") if [ "$workflow_status" == "running" ]; then diff --git a/.metamask/cache/07ccf8df409d659150ced82aa8cbe71abb88816001365729a8ca79d5f26e12f5/anvil b/.metamask/cache/07ccf8df409d659150ced82aa8cbe71abb88816001365729a8ca79d5f26e12f5/anvil new file mode 100755 index 000000000000..232086a9afc0 Binary files /dev/null and b/.metamask/cache/07ccf8df409d659150ced82aa8cbe71abb88816001365729a8ca79d5f26e12f5/anvil differ diff --git a/.prettierignore b/.prettierignore index d8d8cfe4a15c..6f500515e7c6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,7 +6,6 @@ node_modules/**/* /app/vendor/** /builds/**/* /coverage/**/* -/development/charts/** /development/chromereload.js /development/ts-migration-dashboard/filesToConvert.json /development/ts-migration-dashboard/build/** diff --git a/.storybook/test-data.js b/.storybook/test-data.js index 6e4eb2265b98..8ff5c0bea3db 100644 --- a/.storybook/test-data.js +++ b/.storybook/test-data.js @@ -310,7 +310,6 @@ const state = { connectedAccounts: ['0x64a845a5b02460acf8a3d84503b0d68d028b4bb4'], isInitialized: true, isUnlocked: true, - isAccountMenuOpen: false, rpcUrl: 'https://rawtestrpc.metamask.io/', internalAccounts: { accounts: { @@ -677,8 +676,6 @@ const state = { ], }, ], - pendingTokens: {}, - customNonceValue: '', send: { gasLimit: '0xcb28', gasPrice: null, @@ -702,7 +699,6 @@ const state = { }, useBlockie: false, featureFlags: {}, - welcomeScreenSeen: false, slides: [], currentLocale: 'en', preferences: { @@ -731,7 +727,6 @@ const state = { }, }, participateInMetaMetrics: true, - nextNonce: 71, connectedStatusPopoverHasBeenShown: true, swapsWelcomeMessageHasBeenShown: true, defaultHomeActiveTabName: 'Tokens', @@ -1630,6 +1625,12 @@ const state = { openSeaEnabled: true, }, appState: { + isAccountMenuOpen: false, + welcomeScreenSeen: false, + pendingTokens: {}, + confirmationExchangeRates: {}, + customNonceValue: '', + nextNonce: 71, shouldClose: false, menuOpen: false, modal: { @@ -1665,7 +1666,6 @@ const state = { isLoading: false, warning: null, buyView: {}, - gasIsLoading: false, defaultHdPaths: { trezor: "m/44'/60'/0'/0", ledger: "m/44'/60'/0'/0/0", diff --git a/.vscode/cspell.json b/.vscode/cspell.json index f962a85ef3ad..20c4fdd8c3ca 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -47,10 +47,10 @@ "devcontainers", "endregion", "ensdomains", - "flamegraph", "FONTCONFIG", "hardfork", "hexstring", + "Interactable", "jazzicon", "keccak", "lavadome", @@ -70,6 +70,7 @@ "pipefail", "quickstart", "recompiles", + "retryable", "shellcheck", "SIWE", "sourcemaps", diff --git a/.yarn/patches/@ledgerhq-evm-tools-npm-1.2.3-414f44baa9.patch b/.yarn/patches/@ledgerhq-evm-tools-npm-1.3.0-57435278f6.patch similarity index 73% rename from .yarn/patches/@ledgerhq-evm-tools-npm-1.2.3-414f44baa9.patch rename to .yarn/patches/@ledgerhq-evm-tools-npm-1.3.0-57435278f6.patch index 15335a88e494..19002b9ed7ab 100644 --- a/.yarn/patches/@ledgerhq-evm-tools-npm-1.2.3-414f44baa9.patch +++ b/.yarn/patches/@ledgerhq-evm-tools-npm-1.3.0-57435278f6.patch @@ -1,11 +1,11 @@ diff --git a/lib/message/EIP712/index.js b/lib/message/EIP712/index.js -index 5443ac06d4ef29028e3acce98210949da2ef9263..57ec8615340a9285290ad5d2c2522ed19af2d0fc 100644 +index a5c677ebf53ab6c22987cebf1c92b21c6245b5db..f5a5580df74100d5e1725bb783038c4c60ae1dbc 100644 --- a/lib/message/EIP712/index.js +++ b/lib/message/EIP712/index.js -@@ -28,8 +28,8 @@ const ethers_1 = require("ethers"); - const axios_1 = __importDefault(require("axios")); - const sha224_1 = __importDefault(require("crypto-js/sha224")); +@@ -29,8 +29,8 @@ const sha224_1 = __importDefault(require("crypto-js/sha224")); const live_env_1 = require("@ledgerhq/live-env"); + const constants_1 = require("@ethersproject/constants"); + const hash_1 = require("@ethersproject/hash"); -const eip712_1 = __importDefault(require("@ledgerhq/cryptoassets-evm-signatures/data/eip712")); -const eip712_v2_1 = __importDefault(require("@ledgerhq/cryptoassets-evm-signatures/data/eip712_v2")); +const eip712_1 = __importDefault(require("@ledgerhq/cryptoassets-evm-signatures/lib/data/eip712")); diff --git a/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.39.0-866309bbbe.patch b/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.42.2-46a44bfbf5.patch similarity index 74% rename from .yarn/patches/@ledgerhq-hw-app-eth-npm-6.39.0-866309bbbe.patch rename to .yarn/patches/@ledgerhq-hw-app-eth-npm-6.42.2-46a44bfbf5.patch index cfefcca767a7..bc0e13b93194 100644 --- a/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.39.0-866309bbbe.patch +++ b/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.42.2-46a44bfbf5.patch @@ -1,5 +1,5 @@ diff --git a/lib/modules/EIP712/index.js b/lib/modules/EIP712/index.js -index bbca23c9a596b2b300aca0f323bad277a4190def..c85cb18c3d6ff049c442d358b4d834c04a49951f 100644 +index 24251b4584b04fd138b8892f027ccad60b14fc9e..4b99b94cf2327042b53687b4e2b076bd0cb8fba1 100644 --- a/lib/modules/EIP712/index.js +++ b/lib/modules/EIP712/index.js @@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); @@ -12,7 +12,7 @@ index bbca23c9a596b2b300aca0f323bad277a4190def..c85cb18c3d6ff049c442d358b4d834c0 const utils_1 = require("../../utils"); const loadConfig_1 = require("../../services/ledger/loadConfig"); diff --git a/lib/modules/EIP712/utils.js b/lib/modules/EIP712/utils.js -index 4f09ea8a24ae4f175f1a4d2d40999d36ffa2a915..1cc7de0d5ffd2b980741ad6d85a75792085c031b 100644 +index 4f09ea8a24ae4f175f1a4d2d40999d36ffa2a915..38225b98bc124d8648d1ff110570293f165bd2a6 100644 --- a/lib/modules/EIP712/utils.js +++ b/lib/modules/EIP712/utils.js @@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { @@ -25,7 +25,7 @@ index 4f09ea8a24ae4f175f1a4d2d40999d36ffa2a915..1cc7de0d5ffd2b980741ad6d85a75792 /** * @ignore for the README diff --git a/lib/services/ledger/erc20.js b/lib/services/ledger/erc20.js -index 8fdedf8037b2684ab6d48fd279a0c014b074b676..c10cea22504a4d3cd72bfac51463e5664639d20e 100644 +index 8fdedf8037b2684ab6d48fd279a0c014b074b676..90ce6589407c1b8719550c21251f3f247fcef085 100644 --- a/lib/services/ledger/erc20.js +++ b/lib/services/ledger/erc20.js @@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); @@ -38,26 +38,26 @@ index 8fdedf8037b2684ab6d48fd279a0c014b074b676..c10cea22504a4d3cd72bfac51463e566 const asContractAddress = (addr) => { const a = addr.toLowerCase(); diff --git a/lib/services/ledger/index.js b/lib/services/ledger/index.js -index 8385537236dfc98902376b29f712e9f7b605091a..6641b951b0c7e477fe5622c724ee22b9e5272213 100644 +index 86db9973e63e1ac7c0e7f67e53ca8f05aa809805..29ebceeab40cdad75092d8af747d770411f8a605 100644 --- a/lib/services/ledger/index.js +++ b/lib/services/ledger/index.js @@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); - // This implements the resolution of a Transaction using Ledger's own API - const logs_1 = require("@ledgerhq/logs"); + const transactions_1 = require("@ethersproject/transactions"); const abi_1 = require("@ethersproject/abi"); + const logs_1 = require("@ledgerhq/logs"); -const index_1 = require("@ledgerhq/domain-service/signers/index"); +const index_1 = require("@ledgerhq/domain-service/lib/signers/index"); + const constants_1 = require("../../modules/Uniswap/constants"); const erc20_1 = require("./erc20"); - const contracts_1 = require("./contracts"); - const nfts_1 = require("./nfts"); + const Uniswap_1 = require("../../modules/Uniswap"); diff --git a/lib/utils.js b/lib/utils.js -index 027089bf09c047b34af79e3dea253d5335d336f3..1c5da628db47a33099532973de9ea634a1ee65df 100644 +index 6c5f58439116b2c6b5844f5e17d0eb876a436f41..e719e9840d33721ef79bb12232991621c828b501 100644 --- a/lib/utils.js +++ b/lib/utils.js -@@ -2,7 +2,7 @@ - Object.defineProperty(exports, "__esModule", { value: true }); - exports.mergeResolutions = exports.nftSelectors = exports.tokenSelectors = exports.intAsHexBytes = exports.decodeTxInfo = exports.maybeHexBuffer = exports.hexBuffer = exports.splitPath = exports.padHexString = exports.ERC1155_CLEAR_SIGNED_SELECTORS = exports.ERC721_CLEAR_SIGNED_SELECTORS = exports.ERC20_CLEAR_SIGNED_SELECTORS = void 0; +@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); + exports.safeChunkTransaction = exports.getV = exports.getChainIdAsUint32 = exports.getParity = exports.mergeResolutions = exports.nftSelectors = exports.tokenSelectors = exports.intAsHexBytes = exports.maybeHexBuffer = exports.hexBuffer = exports.splitPath = exports.padHexString = exports.ERC1155_CLEAR_SIGNED_SELECTORS = exports.ERC721_CLEAR_SIGNED_SELECTORS = exports.ERC20_CLEAR_SIGNED_SELECTORS = void 0; const bignumber_js_1 = require("bignumber.js"); + const rlp = __importStar(require("@ethersproject/rlp")); -const index_1 = require("@ledgerhq/evm-tools/selectors/index"); +const index_1 = require("@ledgerhq/evm-tools/lib/selectors/index"); Object.defineProperty(exports, "ERC20_CLEAR_SIGNED_SELECTORS", { enumerable: true, get: function () { return index_1.ERC20_CLEAR_SIGNED_SELECTORS; } }); diff --git a/.yarn/patches/@metamask-network-controller-npm-22.1.0-621c281f70.patch b/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch similarity index 85% rename from .yarn/patches/@metamask-network-controller-npm-22.1.0-621c281f70.patch rename to .yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch index 027c44b96395..a1a3e7401c0c 100644 --- a/.yarn/patches/@metamask-network-controller-npm-22.1.0-621c281f70.patch +++ b/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch @@ -1,6 +1,6 @@ diff --git a/PATCH.txt b/PATCH.txt new file mode 100644 -index 0000000000000000000000000000000000000000..ce3b18534f055ee00aa5821793f855fd300fb72c +index 0000000000000000000000000000000000000000..376255036ca54b83a3f3c3e0277c2666473df30e --- /dev/null +++ b/PATCH.txt @@ -0,0 +1,4 @@ @@ -8,9 +8,8 @@ index 0000000000000000000000000000000000000000..ce3b18534f055ee00aa5821793f855fd +The network lookup is done after onboarding is completed, and when the extension reloads if onboarding has been completed. +This patch is part of a temporary fix that will be reverted soon to make way for a more permanent solution. https://github.com/MetaMask/metamask-extension/pull/23005 +You can see the changes before compilation on this branch: https://github.com/MetaMask/core/compare/pnf/ext-23622-review?expand=1 -\ No newline at end of file diff --git a/dist/NetworkController.cjs b/dist/NetworkController.cjs -index cc9793f576eb39a51ab141b7d03de57cf99e5570..c573b5134d40f522217a6ab6df129040d02e9660 100644 +index cc9793f576eb39a51ab141b7d03de57cf99e5570..184153067f2bbd58ea76d7db33c2af56245cd8c0 100644 --- a/dist/NetworkController.cjs +++ b/dist/NetworkController.cjs @@ -422,7 +422,6 @@ class NetworkController extends base_controller_1.BaseController { @@ -22,7 +21,7 @@ index cc9793f576eb39a51ab141b7d03de57cf99e5570..c573b5134d40f522217a6ab6df129040 /** * Refreshes the network meta with EIP-1559 support and the network status diff --git a/dist/NetworkController.mjs b/dist/NetworkController.mjs -index 806f32edeffaad9f7eb1cafa4184368ec95f63e7..9268947cbed4bf717729ca6ac8ea83a8b91b6e8a 100644 +index 806f32edeffaad9f7eb1cafa4184368ec95f63e7..7ba60e613ec8de7d273c32282be564f36873cbd2 100644 --- a/dist/NetworkController.mjs +++ b/dist/NetworkController.mjs @@ -397,7 +397,6 @@ export class NetworkController extends BaseController { diff --git a/.yarn/patches/@metamask-nonce-tracker-npm-5.0.0-d81478218e.patch b/.yarn/patches/@metamask-nonce-tracker-npm-5.0.0-d81478218e.patch deleted file mode 100644 index fb9a5c1ef5f6..000000000000 --- a/.yarn/patches/@metamask-nonce-tracker-npm-5.0.0-d81478218e.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/dist/NonceTracker.js b/dist/NonceTracker.js -index 7cfa1e1962c930a425b3dbf6e1520450f0bf1747..2f4ff77a678fe0501e96a92d16f63a8e5f299401 100644 ---- a/dist/NonceTracker.js -+++ b/dist/NonceTracker.js -@@ -12,7 +12,6 @@ class NonceTracker { - constructor(opts) { - this.provider = opts.provider; - this.blockTracker = opts.blockTracker; -- this.web3 = new Web3Provider(opts.provider); - this.getPendingTransactions = opts.getPendingTransactions; - this.getConfirmedTransactions = opts.getConfirmedTransactions; - this.lockMap = {}; -@@ -96,7 +95,7 @@ class NonceTracker { - // we need to make sure our base count - // and pending count are from the same block - const blockNumber = await this.blockTracker.getLatestBlock(); -- const baseCount = await this.web3.getTransactionCount(address, blockNumber); -+ const baseCount = await new Web3Provider(this.provider).getTransactionCount(address, blockNumber); - assert_1.default(Number.isInteger(baseCount), `nonce-tracker - baseCount is not an integer - got: (${typeof baseCount}) "${baseCount}"`); - return { - name: 'network', -diff --git a/dist/NonceTracker.js.map b/dist/NonceTracker.js.map -index 70e16afc468187dddb2ba1a6752e60c0aadb0f82..0e9d43aed1f7c5ccc2e16f91318aaab88da104ea 100644 ---- a/dist/NonceTracker.js.map -+++ b/dist/NonceTracker.js.map -@@ -1 +1 @@ --{"version":3,"file":"NonceTracker.js","sourceRoot":"","sources":["../src/NonceTracker.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,6CAAoC;AAGpC,qGAAqG;AACrG,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAqF7D,MAAa,YAAY;IAavB,YAAY,IAAyB;QACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,CAAC;QAC1D,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,wBAAwB,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,WAAW,GAAU,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvD,0BAA0B;QAC1B,MAAM,WAAW,GAAiB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC9D,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,0BAA0B;QAC1B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,kCAAkC;QAClC,MAAM,WAAW,GAAiB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjE,IAAI;YACF,yCAAyC;YACzC,MAAM,kBAAkB,GACtB,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,uBAAuB,GAC3B,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,gBAAgB,GAAW,kBAAkB,CAAC,KAAK,CAAC;YAC1D,MAAM,gBAAgB,GAAW,IAAI,CAAC,GAAG,CACvC,gBAAgB,EAChB,uBAAuB,CACxB,CAAC;YAEF,MAAM,UAAU,GAAkB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACvE,MAAM,gBAAgB,GACpB,IAAI,CAAC,yBAAyB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;YAE/D,MAAM,YAAY,GAAiB;gBACjC,MAAM,EAAE;oBACN,uBAAuB;oBACvB,gBAAgB;oBAChB,gBAAgB;iBACjB;gBACD,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,kBAAkB;aAC5B,CAAC;YAEF,MAAM,SAAS,GAAW,IAAI,CAAC,GAAG,CAChC,kBAAkB,CAAC,KAAK,EACxB,gBAAgB,CAAC,KAAK,CACvB,CAAC;YACF,gBAAM,CACJ,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAC3B,uDAAuD,OAAO,SAAS,MAAM,SAAS,GAAG,CAC1F,CAAC;YAEF,8BAA8B;YAC9B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;SACjD;QAAC,OAAO,GAAG,EAAE;YACZ,wCAAwC;YACxC,WAAW,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;SACX;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,WAAW,GAAU,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,WAAW,GAAiB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC9D,WAAW,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,MAAM,KAAK,GAAU,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAiB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACxD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,IAAI,KAAK,GAAU,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE;YACV,KAAK,GAAG,IAAI,mBAAK,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;SAC9B;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,oBAAoB,CAAC,OAAe;QACxC,uBAAuB;QACvB,sCAAsC;QACtC,4CAA4C;QAC5C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAW,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAC3D,OAAO,EACP,WAAW,CACZ,CAAC;QACF,gBAAM,CACJ,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAC3B,uDAAuD,OAAO,SAAS,MAAM,SAAS,GAAG,CAC1F,CAAC;QACF,OAAO;YACL,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;SACpC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,2BAA2B,CAAC,OAAe;QACzC,MAAM,qBAAqB,GACzB,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,OAAO,GAAW,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QACrE,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,MAAqB;QACpC,MAAM,MAAM,GAAa,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;YAClC,gBAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,8BAA8B,CAAC,CAAC;YAClE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,MAAM,YAAY,GAAW,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,yBAAyB,CACvB,MAAqB,EACrB,UAAkB;QAElB,MAAM,MAAM,GAAa,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;YAClC,gBAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,8BAA8B,CAAC,CAAC;YAClE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,GAAW,UAAU,CAAC;QACjC,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,CAAC;SACd;QAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;IAC7E,CAAC;CACF;AA3LD,oCA2LC"} -\ No newline at end of file -+{"version":3,"file":"NonceTracker.js","sourceRoot":"","sources":["../src/NonceTracker.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,6CAAoC;AAGpC,qGAAqG;AACrG,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAqF7D,MAAa,YAAY;IAavB,YAAY,IAAyB;QACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,CAAC;QAC1D,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,wBAAwB,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,WAAW,GAAU,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvD,0BAA0B;QAC1B,MAAM,WAAW,GAAiB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC9D,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,0BAA0B;QAC1B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,kCAAkC;QAClC,MAAM,WAAW,GAAiB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjE,IAAI;YACF,yCAAyC;YACzC,MAAM,kBAAkB,GACtB,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,uBAAuB,GAC3B,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,gBAAgB,GAAW,kBAAkB,CAAC,KAAK,CAAC;YAC1D,MAAM,gBAAgB,GAAW,IAAI,CAAC,GAAG,CACvC,gBAAgB,EAChB,uBAAuB,CACxB,CAAC;YAEF,MAAM,UAAU,GAAkB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACvE,MAAM,gBAAgB,GACpB,IAAI,CAAC,yBAAyB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;YAE/D,MAAM,YAAY,GAAiB;gBACjC,MAAM,EAAE;oBACN,uBAAuB;oBACvB,gBAAgB;oBAChB,gBAAgB;iBACjB;gBACD,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,kBAAkB;aAC5B,CAAC;YAEF,MAAM,SAAS,GAAW,IAAI,CAAC,GAAG,CAChC,kBAAkB,CAAC,KAAK,EACxB,gBAAgB,CAAC,KAAK,CACvB,CAAC;YACF,gBAAM,CACJ,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAC3B,uDAAuD,OAAO,SAAS,MAAM,SAAS,GAAG,CAC1F,CAAC;YAEF,8BAA8B;YAC9B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;SACjD;QAAC,OAAO,GAAG,EAAE;YACZ,wCAAwC;YACxC,WAAW,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;SACX;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,WAAW,GAAU,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,WAAW,GAAiB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC9D,WAAW,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,MAAM,KAAK,GAAU,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAiB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACxD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,IAAI,KAAK,GAAU,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE;YACV,KAAK,GAAG,IAAI,mBAAK,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;SAC9B;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,oBAAoB,CAAC,OAAe;QACxC,uBAAuB;QACvB,sCAAsC;QACtC,4CAA4C;QAC5C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAW,MAAM,IAAI,YAAY,CAC9C,IAAI,CAAC,QAAQ,CACd,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC5C,gBAAM,CACJ,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAC3B,uDAAuD,OAAO,SAAS,MAAM,SAAS,GAAG,CAC1F,CAAC;QACF,OAAO;YACL,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;SACpC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,2BAA2B,CAAC,OAAe;QACzC,MAAM,qBAAqB,GACzB,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,OAAO,GAAW,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QACrE,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,MAAqB;QACpC,MAAM,MAAM,GAAa,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;YAClC,gBAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,8BAA8B,CAAC,CAAC;YAClE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,MAAM,YAAY,GAAW,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,yBAAyB,CACvB,MAAqB,EACrB,UAAkB;QAElB,MAAM,MAAM,GAAa,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;YAClC,gBAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,8BAA8B,CAAC,CAAC;YAClE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,GAAW,UAAU,CAAC;QACjC,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YAC/B,OAAO,IAAI,CAAC,CAAC;SACd;QAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;IAC7E,CAAC;CACF;AAzLD,oCAyLC"} -\ No newline at end of file diff --git a/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch b/.yarn/patches/@metamask-transaction-controller-npm-42.1.0-5e103c5a07.patch similarity index 87% rename from .yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch rename to .yarn/patches/@metamask-transaction-controller-npm-42.1.0-5e103c5a07.patch index d6c286a1ed56..b02f6b683173 100644 --- a/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch +++ b/.yarn/patches/@metamask-transaction-controller-npm-42.1.0-5e103c5a07.patch @@ -18,22 +18,34 @@ index 7764cca7fd50be8eb1d4cf0a8a4a5d7f6430c8bc..905258c7f8a107dd3b95a10e7241b42c isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled, getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({ diff --git a/dist/helpers/MultichainTrackingHelper.cjs b/dist/helpers/MultichainTrackingHelper.cjs -index 3e1204fc775639e07f617dd455907ef68f1764eb..442c32d95eee884aa97aea11e84aff87db3b5cb4 100644 +index 3e1204fc775639e07f617dd455907ef68f1764eb..f1098c16f5bd93f244f54a538b588b8954faf2d7 100644 --- a/dist/helpers/MultichainTrackingHelper.cjs +++ b/dist/helpers/MultichainTrackingHelper.cjs @@ -191,6 +191,7 @@ _MultichainTrackingHelper_findNetworkClientIdByChainId = new WeakMap(), _Multich provider, blockTracker, chainId, -+ networkClientId, ++ networkClientId }); __classPrivateFieldGet(this, _MultichainTrackingHelper_trackingMap, "f").set(networkClientId, { nonceTracker, +diff --git a/dist/helpers/MultichainTrackingHelper.d.cts b/dist/helpers/MultichainTrackingHelper.d.cts +index 81c2c3307dc40414084358e0929d7fa2e1e91243..80e711e79caf2882b5cad65cf4c41dc826157658 100644 +--- a/dist/helpers/MultichainTrackingHelper.d.cts ++++ b/dist/helpers/MultichainTrackingHelper.d.cts +@@ -16,6 +16,7 @@ export type MultichainTrackingHelperOptions = { + provider: Provider; + blockTracker: BlockTracker; + chainId: Hex; ++ networkClientId: NetworkClientId; + }) => PendingTransactionTracker; + onNetworkStateChange: (listener: (...payload: NetworkControllerStateChangeEvent['payload']) => void) => void; + }; diff --git a/dist/helpers/PendingTransactionTracker.cjs b/dist/helpers/PendingTransactionTracker.cjs -index 0b88c6d6df8dac03c4704051345f8c03ca7e97af..97e46f0494788f114b018ef66f5b4c0b1738fc20 100644 +index 0b88c6d6df8dac03c4704051345f8c03ca7e97af..51636e1f8b94ced1aa392e862383170aa1c8bc57 100644 --- a/dist/helpers/PendingTransactionTracker.cjs +++ b/dist/helpers/PendingTransactionTracker.cjs -@@ -13,17 +13,17 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( +@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -42,18 +54,6 @@ index 0b88c6d6df8dac03c4704051345f8c03ca7e97af..97e46f0494788f114b018ef66f5b4c0b Object.defineProperty(exports, "__esModule", { value: true }); exports.PendingTransactionTracker = void 0; const controller_utils_1 = require("@metamask/controller-utils"); - // This package purposefully relies on Node's EventEmitter module. --// eslint-disable-next-line import/no-nodejs-modules -+// eslint-disable-next-line import-x/no-nodejs-modules - const events_1 = __importDefault(require("events")); - const lodash_1 = require("lodash"); -+const TransactionPoller_1 = require("./TransactionPoller.cjs"); - const logger_1 = require("../logger.cjs"); - const types_1 = require("../types.cjs"); --const TransactionPoller_1 = require("./TransactionPoller.cjs"); - /** - * We wait this many blocks before emitting a 'transaction-dropped' event - * This is because we could be talking to a node that is out of sync @@ -42,11 +42,12 @@ const KNOWN_TRANSACTION_ERRORS = [ ]; const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'pending-transactions'); @@ -128,3 +128,20 @@ index 0b88c6d6df8dac03c4704051345f8c03ca7e97af..97e46f0494788f114b018ef66f5b4c0b }; //# sourceMappingURL=PendingTransactionTracker.cjs.map \ No newline at end of file +diff --git a/dist/helpers/PendingTransactionTracker.d.cts b/dist/helpers/PendingTransactionTracker.d.cts +index 52bed3ddb950e404ee71d86ce3dd008c95165a8d..2531132adbdbd9cdf4622cae84a0b5f83a161655 100644 +--- a/dist/helpers/PendingTransactionTracker.d.cts ++++ b/dist/helpers/PendingTransactionTracker.d.cts +@@ -16,10 +16,11 @@ export interface PendingTransactionTrackerEventEmitter extends EventEmitter { + export declare class PendingTransactionTracker { + #private; + hub: PendingTransactionTrackerEventEmitter; +- constructor({ blockTracker, getChainId, getEthQuery, getTransactions, isResubmitEnabled, getGlobalLock, publishTransaction, hooks, }: { ++ constructor({ blockTracker, getChainId, getEthQuery, getNetworkClientId, getTransactions, isResubmitEnabled, getGlobalLock, publishTransaction, hooks, }: { + blockTracker: BlockTracker; + getChainId: () => string; + getEthQuery: (networkClientId?: NetworkClientId) => EthQuery; ++ getNetworkClientId: () => string; + getTransactions: () => TransactionMeta[]; + isResubmitEnabled?: () => boolean; + getGlobalLock: () => Promise<() => void>; diff --git a/.yarn/patches/eth-query-npm-2.1.2-7c6adc825f.patch b/.yarn/patches/eth-query-npm-2.1.2-7c6adc825f.patch deleted file mode 100644 index e801e600534c..000000000000 --- a/.yarn/patches/eth-query-npm-2.1.2-7c6adc825f.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/index.js b/index.js -index 13e9f3c25e7d3bee6a4ec3c2c5e1eea31e86a377..18b050ded27baf3603708fd6d595a554ea3c19c8 100644 ---- a/index.js -+++ b/index.js -@@ -1,9 +1,9 @@ - const extend = require('xtend') - const createRandomId = require('json-rpc-random-id')() -+const debug = require('debug')('eth-query') - - module.exports = EthQuery - -- - function EthQuery(provider){ - const self = this - self.currentProvider = provider -@@ -63,7 +63,10 @@ EthQuery.prototype.submitHashrate = generateFnFor('eth_subm - - EthQuery.prototype.sendAsync = function(opts, cb){ - const self = this -- self.currentProvider.sendAsync(createPayload(opts), function(err, response){ -+ const payload = createPayload(opts) -+ debug('making request %o', payload) -+ self.currentProvider.sendAsync(payload, function(err, response){ -+ debug('got err = %o, response = %o', err, response) - if (!err && response.error) err = new Error('EthQuery - RPC Error - '+response.error.message) - if (err) return cb(err) - cb(null, response.result) diff --git a/.yarn/patches/lavamoat-core-npm-16.2.2-e361ff1f8a.patch b/.yarn/patches/lavamoat-core-npm-16.2.2-e361ff1f8a.patch new file mode 100644 index 000000000000..d3b14fd157ca --- /dev/null +++ b/.yarn/patches/lavamoat-core-npm-16.2.2-e361ff1f8a.patch @@ -0,0 +1,48 @@ +diff --git a/src/loadPolicy.js b/src/loadPolicy.js +index b3053356c739a5f351fd4e271b67e31ee00bb4dc..7daebe4104ce5d799f90068516b1d0aaa58546c0 100644 +--- a/src/loadPolicy.js ++++ b/src/loadPolicy.js +@@ -101,10 +101,9 @@ async function loadPolicyAndApplyOverrides({ + + const finalPolicy = mergePolicy(policy, policyOverride) + +- // TODO: Only write if merge results in changes. +- // Would have to make a deep equal check on whole policy, which is a waste of time. +- // mergePolicy() should be able to do it in one pass. +- await fs.writeFile(policyPath, jsonStringifySortedPolicy(finalPolicy)) ++ // Skip policy write step to prevent intermittent build failures ++ // The extension validates the policy in a separate step, we don't need it ++ // to be written to disk here. + + return finalPolicy + } +diff --git a/src/scuttle.js b/src/scuttle.js +index c096a1fbf0bfe8a8f22290852881598f74fff4b1..b7438881be5e25b48ea18919a4b642a0b14cc317 100644 +--- a/src/scuttle.js ++++ b/src/scuttle.js +@@ -77,6 +77,8 @@ function generateScuttleOpts(globalRef, originalOpts = create(null)) { + exceptions: [], + scuttlerName: '', + } ++ // cache regular expressions to work around https://github.com/MetaMask/metamask-extension/issues/21006 ++ const regexCache = new Map() + const opts = assign( + create(null), + originalOpts === true ? defaultOpts : originalOpts, +@@ -109,10 +111,15 @@ function generateScuttleOpts(globalRef, originalOpts = create(null)) { + if (!except.startsWith('/')) { + return except + } ++ if (regexCache.has(except)) { ++ return regexCache.get(except) ++ } + const parts = except.split('/') + const pattern = parts.slice(1, -1).join('/') + const flags = parts[parts.length - 1] +- return new RegExp(pattern, flags) ++ const re = new RegExp(pattern, flags) ++ regexCache.set(except, re) ++ return re + } + } + diff --git a/.yarn/patches/luxon-npm-3.2.1-56f8d97395.patch b/.yarn/patches/luxon-npm-3.2.1-56f8d97395.patch deleted file mode 100644 index 20ee46808781..000000000000 --- a/.yarn/patches/luxon-npm-3.2.1-56f8d97395.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/build/cjs-browser/luxon.js b/build/cjs-browser/luxon.js -index 776c38ae1679eaed97ef5fa9a666e37e48747df6..336fb0ddfffd12604b5ab1609ba0685755739c9c 100644 ---- a/build/cjs-browser/luxon.js -+++ b/build/cjs-browser/luxon.js -@@ -4226,7 +4226,7 @@ var Interval = /*#__PURE__*/function () { - * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> Mon, Nov 07, 6:00 – 8:00 p - * @return {string} - */; -- _proto.toLocaleString = function toLocaleString(formatOpts, opts) { -+ Reflect.defineProperty(_proto, 'toLocaleString', { value: function toLocaleString(formatOpts, opts) { - if (formatOpts === void 0) { - formatOpts = DATE_SHORT; - } -@@ -4234,7 +4234,7 @@ var Interval = /*#__PURE__*/function () { - opts = {}; - } - return this.isValid ? Formatter.create(this.s.loc.clone(opts), formatOpts).formatInterval(this) : INVALID$1; -- } -+ }}) - - /** - * Returns an ISO 8601-compliant string representation of this Interval. -@@ -6598,7 +6598,7 @@ var DateTime = /*#__PURE__*/function () { - * @example DateTime.now().toLocaleString({ hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); //=> '11:32' - * @return {string} - */; -- _proto.toLocaleString = function toLocaleString(formatOpts, opts) { -+ Reflect.defineProperty(_proto, 'toLocaleString', { value: function toLocaleString(formatOpts, opts) { - if (formatOpts === void 0) { - formatOpts = DATE_SHORT; - } -@@ -6606,7 +6606,7 @@ var DateTime = /*#__PURE__*/function () { - opts = {}; - } - return this.isValid ? Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this) : INVALID; -- } -+ }}) - - /** - * Returns an array of format "parts", meaning individual tokens along with metadata. This is allows callers to post-process individual sections of the formatted output. diff --git a/CHANGELOG.md b/CHANGELOG.md index 45e26db728d3..e67884bd77ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,97 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [12.11.0] +### Added +- Added Lisk network logos for mainnet and testnet, visible in the network selector ([#29762](https://github.com/MetaMask/metamask-extension/pull/29762)) +- Added Soneium Mainnet and Testnet logos for network integration ([#29713](https://github.com/MetaMask/metamask-extension/pull/29713)) +- Added logos for Ink network and Ink Sepolia ([#29493](https://github.com/MetaMask/metamask-extension/pull/29493)) +- Added ETH native token icon for the Zora network ([#29257](https://github.com/MetaMask/metamask-extension/pull/29257)) +- Added quote timeout handling and refresh functionality to bridge interface ([#29172](https://github.com/MetaMask/metamask-extension/pull/29172)) +- Made nonce always editable in the advanced details view, independent of settings toggle ([#29627](https://github.com/MetaMask/metamask-extension/pull/29627)) +- Added clickable cursor on hover for the petname component in confirmation screens ([#29477](https://github.com/MetaMask/metamask-extension/pull/29477)) +- Added validation to prevent invalid primary types in types sign requests ([#29379](https://github.com/MetaMask/metamask-extension/pull/29379)) +- Introduced a feature to display "Unlimited" for very large spending caps on permits ([#29102](https://github.com/MetaMask/metamask-extension/pull/29102)). +- Enabled Smart Transactions (STX) by default for users without prior STX activity, with a migration alert to inform users of the change ([#28854](https://github.com/MetaMask/metamask-extension/pull/28854)) +- Enhanced error messaging for failed transactions in the activity details view ([#29338](https://github.com/MetaMask/metamask-extension/pull/29338)) +- Added an auto sign-in feature for existing users ([#29654](https://github.com/MetaMask/metamask-extension/pull/29654)) +- Updated Solana Snap to version 1.0.4 ([#29350](https://github.com/MetaMask/metamask-extension/pull/29350)) +- Enhanced xchain swaps slippage settings to allow decimal inputs and added warnings for low slippage settings ([#29617](https://github.com/MetaMask/metamask-extension/pull/29617)) +- Implemented persistence of bridge state through ToS click ([#29366](https://github.com/MetaMask/metamask-extension/pull/29366)) +- Added network name to the asset details page ([#29211](https://github.com/MetaMask/metamask-extension/pull/29211)) +- Centered the backup warning toast for improved visual alignment ([#29200](https://github.com/MetaMask/metamask-extension/pull/29200)) +- Added conditional disabling of nonce editing when smart transactions are enabled ([#29897](https://github.com/MetaMask/metamask-extension/pull/29897)) +- Upgraded Ledger keyring to resolve EIP-712 signing issues ([#29874](https://github.com/MetaMask/metamask-extension/pull/29874)) + +### Changed +- Refactored NFT display into a grid view for a cleaner and more organized layout, with privacy mode support and collection-based sorting ([#29445](https://github.com/MetaMask/metamask-extension/pull/29445)) +- Improved UX by automatically importing detected tokens for users with token autodetection enabled ([#29357](https://github.com/MetaMask/metamask-extension/pull/29357)) +- Updated Klaytn network details to reflect rebranding as Kaia ([#29494](https://github.com/MetaMask/metamask-extension/pull/29494)) +- Simplified Activity empty state by removing placeholder text ([#29318](https://github.com/MetaMask/metamask-extension/pull/29318)) +- Enhanced bridge interface low return warning ([#29171](https://github.com/MetaMask/metamask-extension/pull/29171)) +- Removed legacy transaction requests toggle as new design is now default ([#29695](https://github.com/MetaMask/metamask-extension/pull/29695)) +- Improved display of ENS domains in the UI by converting them to their readable form ([#29231](https://github.com/MetaMask/metamask-extension/pull/29231)) +- Added an "Origin Pill" to the Add Ethereum Chain confirmation screen ([#29317](https://github.com/MetaMask/metamask-extension/pull/29317)) +- Increased the gas limit validation threshold to 30 million to accommodate larger transactions ([#29264](https://github.com/MetaMask/metamask-extension/pull/29264)) +- Improved accessibility by adding a visible focus indicator to the swaps input field, aiding users with vision impairments and keyboard navigation ([#29252](https://github.com/MetaMask/metamask-extension/pull/29252)) +- Design tweaks for network badge: updated border color and width based on design quality feedback ([#29324](https://github.com/MetaMask/metamask-extension/pull/29324)) +- Improved helper text for sending NFTs to accurately reflect balance ([#29296](https://github.com/MetaMask/metamask-extension/pull/29296)) +- Enabled Ledger clear signing feature in MetaMask extension ([#28909](https://github.com/MetaMask/metamask-extension/pull/28909)) +- Adjusted Snaps custom UI to ensure adjacent form elements take up to 50% width ([#29436](https://github.com/MetaMask/metamask-extension/pull/29436)) +- Increased the minimum height of the Snaps UI selector component ([#29496](https://github.com/MetaMask/metamask-extension/pull/29496)) +- Improved text wrapping in Snaps UI ([#29387](https://github.com/MetaMask/metamask-extension/pull/29387)) +- Adjusted Snaps UI Container to use margin instead of padding ([#29385](https://github.com/MetaMask/metamask-extension/pull/29385)) +- Removed the "details" option for permissions without descriptions ([#29313](https://github.com/MetaMask/metamask-extension/pull/29313)) +- Updated xchain transaction details to use short network names for improved spacing ([#29413](https://github.com/MetaMask/metamask-extension/pull/29413)) +- Removed the second inner scrollbar from Bridge transaction details ([#29412](https://github.com/MetaMask/metamask-extension/pull/29412)) +- Removed the "Select networks for each site" toggle from the experimental settings page ([#29301](https://github.com/MetaMask/metamask-extension/pull/29301)) +- Updated margins for the import token banner to improve layout consistency ([#29283](https://github.com/MetaMask/metamask-extension/pull/29283)) + +### Fixed +- Fixed snap tags to display localized snap names ([#29049](https://github.com/MetaMask/metamask-extension/pull/29049)) +- Fixed ERC20 token balances incorrectly showing as 0 ([#29361](https://github.com/MetaMask/metamask-extension/pull/29361)) +- Fixed token details to omit fiat values for tokens without market data ([#29299](https://github.com/MetaMask/metamask-extension/pull/29299)) +- Fixed an issue where the asset picker search field would repeatedly auto-focus and scroll to the top of the modal in the Bridge interface ([#29676](https://github.com/MetaMask/metamask-extension/pull/29676)) +- Fixed an issue where closing the notification window didn't properly reject pending signature approvals ([#29673](https://github.com/MetaMask/metamask-extension/pull/29673)) +- Fixed an issue where multiple pending connection requests would incorrectly display duplicate content ([#29653](https://github.com/MetaMask/metamask-extension/pull/29653)) +- Updated alert modal copy to improve clarity of warning messages ([#29475](https://github.com/MetaMask/metamask-extension/pull/29475)) +- Fixed NFT listing display issues: corrected state change order, updated label to "Listing price," and added gray background for received value ([#29046](https://github.com/MetaMask/metamask-extension/pull/29046)) +- Fixed issue where first-time interaction alert was incorrectly shown for token transfers to internal accounts ([#29389](https://github.com/MetaMask/metamask-extension/pull/29389)) +- Fixed navigation issue by ignoring additional watch token and NFT approvals in confirmation screens ([#29279](https://github.com/MetaMask/metamask-extension/pull/29279)) +- Removed reliance on advanced transaction decoding in confirmations when the "Decode smart contracts" toggle is disabled ([#29341](https://github.com/MetaMask/metamask-extension/pull/29341)) +- Fixed issue where the UI did not display the correct gas limit set by dapp, defaulting to 21000 ([#29352](https://github.com/MetaMask/metamask-extension/pull/29352)) +- Corrected the icon display for ETH on Layer 2 networks during transfer confirmations ([#29353](https://github.com/MetaMask/metamask-extension/pull/29353)) +- Fixed display issue where petnames were unnecessarily truncated with ellipses ([#29282](https://github.com/MetaMask/metamask-extension/pull/29282)) +- Improved personal sign message handling ([#29232](https://github.com/MetaMask/metamask-extension/pull/29232)) +- Fixed flickering issue in spending cap display during token approval ([#29206](https://github.com/MetaMask/metamask-extension/pull/29206)) +- Improved the alignment of icons in the message section of signature pages ([#29284](https://github.com/MetaMask/metamask-extension/pull/29284)) +- Fixed an issue where an undefined label appeared in the speed-up modal ([#29277](https://github.com/MetaMask/metamask-extension/pull/29277)) +- Fixed an error that occurred when sending non-ERC721 NFTs ([#29386](https://github.com/MetaMask/metamask-extension/pull/29386)) +- Fixed an issue where account syncing was not working after upgrading from a previous version ([#29701](https://github.com/MetaMask/metamask-extension/pull/29701)) +- Fixed scroll behavior on Snaps home pages to prevent footer overlap ([#29660](https://github.com/MetaMask/metamask-extension/pull/29660)) +- Fixed an issue where the scrollbar in Snap dialogs was partially hidden behind the footer ([#29435](https://github.com/MetaMask/metamask-extension/pull/29435)) +- Fixed an issue with the Snap UI Avatar component where the size property was not applied correctly ([#29466](https://github.com/MetaMask/metamask-extension/pull/29466)) +- Fixed a crash issue in Firefox that occurred after submitting a bridge transaction ([#29631](https://github.com/MetaMask/metamask-extension/pull/29631)) +- Fixed an issue where the "You Received" row in bridge transactions was displayed prematurely ([#29411](https://github.com/MetaMask/metamask-extension/pull/29411)) +- Fixed xchain Linea bugs by adding a loading spinner to the Bridge button and optimizing transaction submission timing ([#29409](https://github.com/MetaMask/metamask-extension/pull/29409)) +- Fixed truncation issue for long help text in the send flow by limiting decimal values to 4 digits ([#29269](https://github.com/MetaMask/metamask-extension/pull/29269)) +- Fixed an issue where network/accounts toasts persisted after navigating to the Edit page in the Permissions modal ([#29239](https://github.com/MetaMask/metamask-extension/pull/29239)) +- Updated the onboarding screen message to include proper punctuation ([#29286](https://github.com/MetaMask/metamask-extension/pull/29286)) +- Fixed NFT list wrapping within the send modal ([#30039](https://github.com/MetaMask/metamask-extension/pull/30039)) +- Fixed explicit data addition to gas estimation parameters ([#30014](https://github.com/MetaMask/metamask-extension/pull/30014)) +- Fixed handling of null STX status containing pre-enabled state ([#30010](https://github.com/MetaMask/metamask-extension/pull/30010)) +- Fixed incorrect native token display in insufficient funds error messages ([#30009](https://github.com/MetaMask/metamask-extension/pull/30009)) +- Fixed transaction flow component issues for ERC-1155 tokens ([#29975](https://github.com/MetaMask/metamask-extension/pull/29975)) +- Updated STX banner alert to include chain support check ([#29947](https://github.com/MetaMask/metamask-extension/pull/29947)) +- Reapplied fix for premature display of "You Received" in bridge transactions ([#29950](https://github.com/MetaMask/metamask-extension/pull/29950)) +- Fixed ERC-1155 token send flow in transaction component ([#29973](https://github.com/MetaMask/metamask-extension/pull/29973)) +- Updated undici dependency to address security audit (5.28.4 → 5.28.5) ([#29976](https://github.com/MetaMask/metamask-extension/pull/29976)) + ## [12.10.4] ## [12.10.3] ### Fixed -- fix: ensure recipient address is shown on when sending erc 1155 tokens ([#29775](https://github.com/MetaMask/metamask-extension/pull/29775)) +- Ensure recipient address is shown on when sending erc 1155 tokens ([#29775](https://github.com/MetaMask/metamask-extension/pull/29775)) ## [12.10.2] ### Fixed @@ -5569,7 +5655,8 @@ Update styles and spacing on the critical error page ([#20350](https://github.c - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v12.10.4...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v12.11.0...HEAD +[12.11.0]: https://github.com/MetaMask/metamask-extension/compare/v12.10.4...v12.11.0 [12.10.4]: https://github.com/MetaMask/metamask-extension/compare/v12.10.3...v12.10.4 [12.10.3]: https://github.com/MetaMask/metamask-extension/compare/v12.10.2...v12.10.3 [12.10.2]: https://github.com/MetaMask/metamask-extension/compare/v12.10.1...v12.10.2 diff --git a/README.md b/README.md index 85d1b3f91ba3..f76e913a6b6c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ MetaMask supports Firefox, Google Chrome, and Chromium-based browsers. We recomm For up to the minute news, follow us on [X](https://x.com/MetaMask). -To learn how to develop MetaMask-compatible applications, visit our [Developer Docs](https://metamask.github.io/metamask-docs/). +To learn how to develop MetaMask-compatible applications, visit our [Developer Docs](https://docs.metamask.io/). To learn how to contribute to the MetaMask codebase, visit our [Contributor Docs](https://github.com/MetaMask/contributor-docs). diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index f118bc17df41..fac85861828c 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -369,9 +369,6 @@ "loading": { "message": "በመጫን ላይ…" }, - "loadingTokens": { - "message": "ተለዋጭ ስሞችን በመጫን ላይ..." - }, "lock": { "message": "ዘግተህ ውጣ" }, @@ -431,9 +428,6 @@ "noConversionRateAvailable": { "message": "ምንም የልወጣ ተመን አይገኝም" }, - "noTransactions": { - "message": "ግብይቶች የሉዎትም" - }, "noWebcamFound": { "message": "የኮምፒዩተርዎ ካሜራ አልተገኘም። እባክዎ እንደገና ይሞክሩ።" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index d9717df6b190..33585243d016 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -385,9 +385,6 @@ "loading": { "message": "جارٍ التحميل..." }, - "loadingTokens": { - "message": "جارِ تحميل العملات الرمزية ..." - }, "localhost": { "message": "المضيف المحلي 8545" }, @@ -447,9 +444,6 @@ "noConversionRateAvailable": { "message": "لا يوجد معدل تحويل متاح" }, - "noTransactions": { - "message": "لا توجد لديك معاملات" - }, "noWebcamFound": { "message": "لم يتم العثور على كاميرا ويب للكمبيوتر الخاص بك. حاول مرة اخرى." }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 749b1561dafe..a6dbac690242 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Зарежда се..." }, - "loadingTokens": { - "message": "Зареждане на жетони..." - }, "localhost": { "message": "Локален хост 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "Няма наличен процент на преобръщане" }, - "noTransactions": { - "message": "Нямате транзакции" - }, "noWebcamFound": { "message": "Уеб камерата на компютърa Ви не беше намерена. Моля, опитайте отново." }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index 15acaa2e6765..1df74dc0e941 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -375,9 +375,6 @@ "loading": { "message": "লোড হচ্ছে..." }, - "loadingTokens": { - "message": "টোকেনগুলি লোড করছে..." - }, "localhost": { "message": "লোকালহোস্ট 8545" }, @@ -440,9 +437,6 @@ "noConversionRateAvailable": { "message": "কোনো বিনিময় হার উপলভ্য নয়" }, - "noTransactions": { - "message": "আপনার কোনো লেনদেন নেই" - }, "noWebcamFound": { "message": "আপনার কম্পিউটারের ওয়েবক্যাম খুঁজে পাওয়া যায়নি। অনুগ্রহ করে আবার চেষ্টা করুন।" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index fc9e2afb41e6..b988ae488143 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -372,9 +372,6 @@ "loading": { "message": "S'està carregant..." }, - "loadingTokens": { - "message": "Carregant els tokens..." - }, "localhost": { "message": "Host local 8545" }, @@ -434,9 +431,6 @@ "noConversionRateAvailable": { "message": "No hi ha cap tarifa de conversió disponible" }, - "noTransactions": { - "message": "No tens transaccions" - }, "noWebcamFound": { "message": "No s'ha trovat la webcam del teu ordinador. Si us plau prova de nou." }, diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json index 4113f8c5cc42..adf67dbda77d 100644 --- a/app/_locales/cs/messages.json +++ b/app/_locales/cs/messages.json @@ -175,9 +175,6 @@ "loading": { "message": "Načítám..." }, - "loadingTokens": { - "message": "Načítám tokeny..." - }, "lock": { "message": "Odhlásit" }, @@ -213,9 +210,6 @@ "next": { "message": "Další" }, - "noTransactions": { - "message": "Žádné transakce" - }, "passwordNotLongEnough": { "message": "Heslo není dost dlouhé" }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index 37e4663523cf..080dd75f22d6 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -375,9 +375,6 @@ "loading": { "message": "Indlæser..." }, - "loadingTokens": { - "message": "Indlæser tokens..." - }, "lock": { "message": "Log ud" }, @@ -434,9 +431,6 @@ "noConversionRateAvailable": { "message": "Ingen tilgængelig omregningskurs" }, - "noTransactions": { - "message": "Du har ingen transaktioner" - }, "noWebcamFound": { "message": "Din computers webkamera blev ikke fundet. Prøv venligst igen." }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 50fd55d9ee78..06335a79da2a 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Netzwerk wird hinzugefügt" }, - "addingTokens": { - "message": "Hinzufügen von Token" - }, "additionalNetworks": { "message": "Zusätzliche Netzwerke" }, @@ -398,9 +395,6 @@ "alert": { "message": "Warnhinweis" }, - "alertActionBuy": { - "message": "EHT kaufen" - }, "alertActionUpdateGas": { "message": "Gas-Limit aktualisieren" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Um mit dieser Transaktion fortzufahren, müssen Sie das Gas-Limit auf 21.000 oder mehr erhöhen." }, - "alertMessageInsufficientBalance2": { - "message": "Sie haben nicht genug ETH auf Ihrem Konto, um die Netzwerk-Gebühren zu bezahlen." - }, "alertMessageNetworkBusy": { "message": "Die Gas-Preise sind hoch und die Schätzungen sind weniger genau." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Automatische Erkennung von Tokens in Ihrer Wallet, Anzeige von NFTs und stapelweise Aktualisierung des Kontostands" }, - "attemptSendingAssets": { - "message": "Wenn Sie versuchen, Assets direkt von einem Netzwerk in ein anderes zu senden, kann dies zu einem dauerhaften Asset-Verlust führen. Verwenden Sie unbedingt eine Bridge." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Sie können Ihre Assets verlieren, wenn Sie versuchen, sie von einem anderen Netzwerk zu versenden. Übertragen Sie Gelder sicher zwischen den Netzwerken, indem Sie eine Bridge wie $1 verwenden." - }, "attemptToCancelSwapForFree": { "message": "Versuch, den Swap kostenlos zu stornieren" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Berechnen ..." }, - "bridgeDontSend": { - "message": "Bridge, nicht senden" - }, "bridgeEnterAmount": { "message": "Betrag eingeben" }, @@ -954,9 +936,6 @@ "message": "Klicken Sie hier, um Ihren Ledger über WebHID zu verbinden.", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Sie können Tokens jederzeit manuell hinzufügen." - }, "close": { "message": "Schließen" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Transaktionsanfrage" }, - "confirmationAlertModalDetails": { - "message": "Um Ihre Assets und Anmeldedaten zu schützen, empfehlen wir die Ablehnung der Anfrage." - }, "confirmationAlertModalTitle": { "message": "Diese Anfrage scheint verdächtig" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Gas-Gebühr" }, - "gasIsETH": { - "message": "Gas ist $1" - }, "gasLimit": { "message": "Gas-Limit" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "Betrügereien und Sicherheitsrisiken." }, - "learnToBridge": { - "message": "Lernen Sie zu bridgen" - }, "leaveMetaMask": { "message": "MetaMask verlassen?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Bitte schließen Sie die Transaktion im Snap ab." }, - "loadingTokens": { - "message": "Tokens werden geladen ..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Wallet-Benachrichtigungen sind momentan nicht aktiv." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps wird gewartet. Bitte versuchen Sie es später erneut." }, @@ -3047,10 +3011,6 @@ "message": "$1 bittet um Ihre Zustimmung zu:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Das native Token dieses Netzwerks ist $1. Dieses Token wird für die Gas-Gebühr verwendet. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Netzwerkdetails bearbeiten" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "Nein, danke!" }, - "noTransactions": { - "message": "Keine Transaktionen" - }, "noWebcamFound": { "message": "Die Webcam Ihres Computers wurde nicht gefunden. Bitte versuchen Sie es erneut." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Schalten Sie dies ein, um sich Unterschriftsanfragen in einem erweiterten Format anzeigen zu lassen." }, - "redesignedTransactionsEnabledToggle": { - "message": "Verbesserte Transaktionsanfragen" - }, - "redesignedTransactionsToggleDescription": { - "message": "Schalten Sie dies ein, um sich Transaktionsanfragen in einem erweiterten Format anzeigen zu lassen." - }, "refreshList": { "message": "Liste aktualisieren" }, @@ -5940,9 +5891,6 @@ "message": "$1 ist jetzt aktiv bei $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Sie verwenden jetzt" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Das Wechseln der Netzwerke wird alle ausstehenden Bestätigungen stornieren." }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Wählen Sie Ihr bevorzugtes MetaMask-Motiv aus." }, - "thingsToKeep": { - "message": "Was Sie beachten sollten:" - }, "thirdPartySoftware": { "message": "Mitteilung bzgl. Drittanbieter-Software", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "An: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Dadurch können Sie ein Netzwerk für jede Website auswählen, anstatt ein einziges Netzwerk für alle Websites auszuwählen. Diese Funktion verhindert, dass Sie manuell zwischen den Netzwerken wechseln müssen, was die Benutzerfreundlichkeit auf bestimmten Websites beeinträchtigen könnte." - }, - "toggleRequestQueueField": { - "message": "Wählen Sie Netzwerke für jede Website" - }, - "toggleRequestQueueOff": { - "message": "Aus" - }, - "toggleRequestQueueOn": { - "message": "An" - }, "token": { "message": "Token" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "Token-Betrügereien und Sicherheitsrisiken" }, - "tokenShowUp": { - "message": "Ihre Tokens werden möglicherweise nicht automatisch in Ihrer Wallet angezeigt. " - }, "tokenStandard": { "message": "Token-Standard" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 34962464e64a..a1c071a1486b 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Προσθήκη δικτύου" }, - "addingTokens": { - "message": "Προσθήκη tokens" - }, "additionalNetworks": { "message": "Επιπλέον δίκτυα" }, @@ -398,9 +395,6 @@ "alert": { "message": "Ειδοποίηση" }, - "alertActionBuy": { - "message": "Αγορά ETH" - }, "alertActionUpdateGas": { "message": "Ενημέρωση ορίου των τελών συναλλαγών" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Για να συνεχίσετε με αυτή τη συναλλαγή, θα πρέπει να αυξήσετε το όριο των τελών συναλλαγών σε 21000 ή περισσότερο." }, - "alertMessageInsufficientBalance2": { - "message": "Δεν έχετε αρκετά ETH στον λογαριασμό σας για να πληρώσετε τα τέλη δικτύου." - }, "alertMessageNetworkBusy": { "message": "Οι τιμές των τελών συναλλαγών είναι υψηλές και οι εκτιμήσεις είναι λιγότερο ακριβείς." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Αυτόματος εντοπισμός tokens στο πορτοφόλι σας, εμφάνιση NFT και ομαδοποιημένες ενημερώσεις υπολοίπων λογαριασμών" }, - "attemptSendingAssets": { - "message": "Ενδέχεται να χάσετε τα περιουσιακά σας στοιχεία εάν προσπαθήσετε να τα στείλετε από άλλο δίκτυο. Μεταφέρετε κεφάλαια με ασφάλεια μεταξύ δικτύων χρησιμοποιώντας μια διασύνδεση." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Μπορεί να χάσετε τα περιουσιακά σας στοιχεία αν προσπαθήσετε να τα στείλετε από άλλο δίκτυο. Μεταφέρετε χρήματα με ασφάλεια μεταξύ δικτύων χρησιμοποιώντας μια διασύνδεση, όπως το $1" - }, "attemptToCancelSwapForFree": { "message": "Προσπάθεια ακύρωσης των ανταλλαγών δωρεάν" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Υπολογισμός..." }, - "bridgeDontSend": { - "message": "Μην στείλετε χωρίς διασύνδεση" - }, "bridgeEnterAmount": { "message": "Πληκτρολογήστε το ποσό" }, @@ -954,9 +936,6 @@ "message": "Κάντε κλικ εδώ για να συνδέσετε το Ledger σας μέσω WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Μπορείτε πάντα να προσθέσετε τα tokens χειροκίνητα." - }, "close": { "message": "Κλείσιμο" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Αίτημα συναλλαγής" }, - "confirmationAlertModalDetails": { - "message": "Για να προστατεύσετε τα περιουσιακά σας στοιχεία και τις πληροφορίες σύνδεσης, σας προτείνουμε να απορρίψετε το αίτημα." - }, "confirmationAlertModalTitle": { "message": "Αυτό το αίτημα είναι ύποπτο" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Τέλη συναλλαγών" }, - "gasIsETH": { - "message": "Τέλη συναλλαγής $1 " - }, "gasLimit": { "message": "Όριο τέλους συναλλαγής" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "απάτες και κίνδυνοι ασφάλειας." }, - "learnToBridge": { - "message": "Μάθετε για την διασύνδεση" - }, "leaveMetaMask": { "message": "Αποχώρηση από το MetaMask;" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Ολοκληρώστε τη συναλλαγή στο Snap." }, - "loadingTokens": { - "message": "Φόρτωση των tokens..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Οι ειδοποιήσεις του πορτοφολιού δεν είναι προς το παρόν ενεργές." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "Το MetaMask Swaps είναι υπό συντήρηση. Παρακαλείστε να επιστρέψετε αργότερα." }, @@ -3047,10 +3011,6 @@ "message": "Το $1 ζητάει την έγκρισή σας για:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Το αρχικό token σε αυτό το δίκτυο είναι το $1. Είναι το token που χρησιμοποιείται για τα τέλη συναλλαγών.", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Επεξεργασία λεπτομερειών δικτύου" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "Όχι, ευχαριστώ" }, - "noTransactions": { - "message": "Δεν έχετε καμιά συναλλαγή" - }, "noWebcamFound": { "message": "Η κάμερα του υπολογιστή σας δεν βρέθηκε. Προσπαθήστε ξανά." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Ενεργοποιήστε το για να δείτε αιτήματα υπογραφών σε βελτιωμένη μορφή." }, - "redesignedTransactionsEnabledToggle": { - "message": "Βελτιωμένα αιτήματα συναλλαγών" - }, - "redesignedTransactionsToggleDescription": { - "message": "Ενεργοποιήστε το για να δείτε τα αιτήματα συναλλαγών σε βελτιωμένη μορφή." - }, "refreshList": { "message": "Ανανέωση λίστας" }, @@ -5940,9 +5891,6 @@ "message": "Το $1 είναι τώρα ενεργό στο $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Τώρα χρησιμοποιείτε το" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Η αλλαγή δικτύων θα ακυρώσει όλες τις εκκρεμείς επιβεβαιώσεις" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Επιλέξτε το προτιμώμενο θέμα σας για το MetaMask." }, - "thingsToKeep": { - "message": "Πράγματα που πρέπει να έχετε υπόψη σας:" - }, "thirdPartySoftware": { "message": "Ειδοποίηση για λογισμικό τρίτων", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "Προς: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Αυτό σας επιτρέπει να επιλέξετε ένα δίκτυο για κάθε ιστότοπο αντί για ένα μόνο επιλεγμένο δίκτυο για όλους τους ιστότοπους. Αυτή η λειτουργία θα σας αποτρέψει από το να αλλάζετε δίκτυα χειροκίνητα, το οποίο μπορεί να διαταράξει την εμπειρία του χρήστη σε ορισμένους ιστότοπους." - }, - "toggleRequestQueueField": { - "message": "Επιλογή δικτύων για κάθε ιστότοπο" - }, - "toggleRequestQueueOff": { - "message": "Απενεργοποίηση" - }, - "toggleRequestQueueOn": { - "message": "Ενεργοποίηση" - }, "token": { "message": "Token" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "απάτες με token και κίνδυνοι ασφάλειας" }, - "tokenShowUp": { - "message": "Τα tokens σας ενδέχεται να μην εμφανιστούν αυτόματα στο πορτοφόλι σας." - }, "tokenStandard": { "message": "Πρότυπο Token" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index f435cd4a1eea..9604de0bc335 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Adding Network" }, - "addingTokens": { - "message": "Adding tokens" - }, "additionalNetworks": { "message": "Additional networks" }, @@ -398,8 +395,8 @@ "alert": { "message": "Alert" }, - "alertActionBuy": { - "message": "Buy ETH" + "alertActionBuyWithNativeCurrency": { + "message": "Buy $1" }, "alertActionUpdateGas": { "message": "Update gas limit" @@ -431,8 +428,8 @@ "alertMessageGasTooLow": { "message": "To continue with this transaction, you’ll need to increase the gas limit to 21000 or higher." }, - "alertMessageInsufficientBalance2": { - "message": "You do not have enough ETH in your account to pay for network fees." + "alertMessageInsufficientBalanceWithNativeCurrency": { + "message": "You do not have enough $1 in your account to pay for network fees." }, "alertMessageNetworkBusy": { "message": "Gas prices are high and estimates are less accurate." @@ -633,21 +630,21 @@ "asset": { "message": "Asset" }, + "assetMultipleNFTsBalance": { + "message": "$1 NFTs" + }, "assetOptions": { "message": "Asset options" }, + "assetSingleNFTBalance": { + "message": "$1 NFT" + }, "assets": { "message": "Assets" }, "assetsDescription": { "message": "Autodetect tokens in your wallet, display NFTs, and get batched account balance updates" }, - "attemptSendingAssets": { - "message": "You may lose your assets if you try to send them from another network. Transfer funds safely between networks by using a bridge." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "You may lose your assets if you try to send them from another network. Transfer funds safely between networks by using a bridge, like $1" - }, "attemptToCancelSwapForFree": { "message": "Attempt to cancel swap for free" }, @@ -874,15 +871,15 @@ "bridgeConfirmTwoTransactions": { "message": "You'll need to confirm 2 transactions on your hardware wallet:" }, - "bridgeDontSend": { - "message": "Bridge, don't send" - }, "bridgeEnterAmount": { "message": "Select amount" }, "bridgeExplorerLinkViewOn": { "message": "View on $1" }, + "bridgeFetchNewQuotes": { + "message": "Fetch a new one?" + }, "bridgeFrom": { "message": "Bridge from" }, @@ -897,7 +894,7 @@ "message": "Net cost" }, "bridgeQuoteExpired": { - "message": "Quotes expired - please request again" + "message": "Your quote timed out." }, "bridgeSelectNetwork": { "message": "Select network" @@ -1080,9 +1077,6 @@ "message": "Click here to connect your Ledger via WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "You can always add tokens manually." - }, "close": { "message": "Close" }, @@ -1189,8 +1183,8 @@ "confirmTitleTransaction": { "message": "Transaction request" }, - "confirmationAlertModalDetails": { - "message": "To protect your assets and login information, we suggest you reject the request." + "confirmationAlertDetails": { + "message": "To protect your assets, we suggest you reject the request." }, "confirmationAlertModalTitle": { "message": "This request is suspicious" @@ -2290,9 +2284,6 @@ "gasFee": { "message": "Gas fee" }, - "gasIsETH": { - "message": "Gas is $1 " - }, "gasLimit": { "message": "Gas limit" }, @@ -2378,7 +2369,9 @@ "gotIt": { "message": "Got it" }, - "grantExactAccess": { "message": "Grant exact access" }, + "grantExactAccess": { + "message": "Grant exact access" + }, "grantedToWithColon": { "message": "Granted to:" }, @@ -2861,9 +2854,6 @@ "learnScamRisk": { "message": "scams and security risks." }, - "learnToBridge": { - "message": "Learn to bridge" - }, "leaveMetaMask": { "message": "Leave MetaMask?" }, @@ -2958,9 +2948,6 @@ "loadingTokenList": { "message": "Loading token list" }, - "loadingTokens": { - "message": "Loading tokens..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2981,10 +2968,10 @@ "message": "Low" }, "lowEstimatedReturnTooltipMessage": { - "message": "Either your rate or your fees are less favorable than usual. It looks like you'll get back less than $1% of the amount you’re bridging." + "message": "You’ll pay more than $1% of your starting amount in fees. Check your receiving amount and network fees." }, "lowEstimatedReturnTooltipTitle": { - "message": "Low estimated return" + "message": "High cost" }, "lowGasSettingToolTipMessage": { "message": "Use $1 to wait for a cheaper price. Time estimates are much less accurate as prices are somewhat unpredictable.", @@ -3068,9 +3055,6 @@ "metamaskNotificationsAreOff": { "message": "Wallet notifications are currently not active." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps is undergoing maintenance. Please check back later." }, @@ -3221,10 +3205,6 @@ "message": "$1 is asking for your approval to:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "The native token on this network is $1. It is the token used for gas fees. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Edit network details" }, @@ -3518,16 +3498,6 @@ "noThanks": { "message": "No thanks" }, - "noTransactions": { - "message": "You have no transactions" - }, - "noTransactionsChainIdMismatch": { - "message": "Please switch network to view transactions" - }, - "noTransactionsNetworkName": { - "message": "Please switch to $1 network to view transactions", - "description": "$1 represents the network name" - }, "noWebcamFound": { "message": "Your computer's webcam was not found. Please try again." }, @@ -4300,6 +4270,9 @@ "permitSimulationChange_listing": { "message": "You list" }, + "permitSimulationChange_nft_listing": { + "message": "Listing price" + }, "permitSimulationChange_receive": { "message": "You receive" }, @@ -4518,7 +4491,9 @@ "quotedReceiveAmount": { "message": "$1 receive amount" }, - "quotedTotalCost": { "message": "$1 total cost" }, + "quotedTotalCost": { + "message": "$1 total cost" + }, "rank": { "message": "Rank" }, @@ -4576,12 +4551,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Turn this on to see signature requests in an enhanced format." }, - "redesignedTransactionsEnabledToggle": { - "message": "Improved transaction requests" - }, - "redesignedTransactionsToggleDescription": { - "message": "Turn this on to see transactions requests in an enhanced format." - }, "refreshList": { "message": "Refresh list" }, @@ -5316,6 +5285,15 @@ "smartTransactions": { "message": "Smart Transactions" }, + "smartTransactionsEnabledDescription": { + "message": " and MEV protection. Now on by default." + }, + "smartTransactionsEnabledLink": { + "message": "Higher success rates" + }, + "smartTransactionsEnabledTitle": { + "message": "Transactions just got smarter" + }, "snapAccountCreated": { "message": "Account created" }, @@ -6221,9 +6199,6 @@ "message": "You're now using $1", "description": "$1 represents the network name" }, - "switchedTo": { - "message": "You're now using" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Switching networks will cancel all pending confirmations" }, @@ -6260,9 +6235,6 @@ "themeDescription": { "message": "Choose your preferred MetaMask theme." }, - "thingsToKeep": { - "message": "Keep in mind:" - }, "thirdPartySoftware": { "message": "Third-party software notice", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6296,18 +6268,6 @@ "toggleDecodeDescription": { "message": "We use 4byte.directory and Sourcify services to decode and display more readable transaction data. This helps you understand the outcome of pending and past transactions, but can result in your IP address being shared." }, - "toggleRequestQueueDescription": { - "message": "This allows you to select a network for each site instead of a single selected network for all sites. This feature will prevent you from switching networks manually, which may break your user experience on certain sites." - }, - "toggleRequestQueueField": { - "message": "Select networks for each site" - }, - "toggleRequestQueueOff": { - "message": "Off" - }, - "toggleRequestQueueOn": { - "message": "On" - }, "token": { "message": "Token" }, @@ -6347,9 +6307,6 @@ "tokenScamSecurityRisk": { "message": "token scams and security risks" }, - "tokenShowUp": { - "message": "Your tokens may not automatically show up in your wallet. " - }, "tokenStandard": { "message": "Token standard" }, @@ -6444,6 +6401,9 @@ "transactionFailed": { "message": "Transaction Failed" }, + "transactionFailedBannerMessage": { + "message": "This transaction would have cost you extra fees, so we stopped it. Your money is still in your wallet." + }, "transactionFee": { "message": "Transaction fee" }, @@ -6825,7 +6785,7 @@ "message": "Welcome back!" }, "welcomeExploreDescription": { - "message": "Store, send and spend crypto currencies and assets." + "message": "Store, send, and spend crypto currencies and assets." }, "welcomeExploreTitle": { "message": "Explore decentralized apps" @@ -6867,7 +6827,9 @@ "you": { "message": "You" }, - "youDeclinedTheTransaction": { "message": "You declined the transaction." }, + "youDeclinedTheTransaction": { + "message": "You declined the transaction." + }, "youNeedToAllowCameraAccess": { "message": "You need to allow camera access to use this feature." }, diff --git a/app/_locales/en_GB/messages.json b/app/_locales/en_GB/messages.json index 2548f8bf0cfb..a915059f262f 100644 --- a/app/_locales/en_GB/messages.json +++ b/app/_locales/en_GB/messages.json @@ -2641,9 +2641,6 @@ "loadingScreenSnapMessage": { "message": "Please complete the transaction on the Snap." }, - "loadingTokens": { - "message": "Loading tokens..." - }, "localhost": { "message": "Localhost 8545" }, @@ -3144,9 +3141,6 @@ "noThanks": { "message": "No thanks" }, - "noTransactions": { - "message": "You have no transactions" - }, "noWebcamFound": { "message": "Your computer's webcam was not found. Please try again." }, @@ -5750,18 +5744,6 @@ "toggleEthSignOn": { "message": "ON (Not recommended)" }, - "toggleRequestQueueDescription": { - "message": "This allows you to select a network for each site instead of a single selected network for all sites. This feature will prevent you from switching networks manually, which may break your user experience on certain sites." - }, - "toggleRequestQueueField": { - "message": "Select networks for each site" - }, - "toggleRequestQueueOff": { - "message": "Off" - }, - "toggleRequestQueueOn": { - "message": "On" - }, "token": { "message": "Token" }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index d32128e8ca43..4e97dd79750b 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Agregando red" }, - "addingTokens": { - "message": "Agregando tokens" - }, "additionalNetworks": { "message": "Redes adicionales" }, @@ -398,9 +395,6 @@ "alert": { "message": "Alerta" }, - "alertActionBuy": { - "message": "Comprar ETH" - }, "alertActionUpdateGas": { "message": "Actualizar el límite de gas" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Para continuar con esta transacción, deberá aumentar el límite de gas a 21000 o más." }, - "alertMessageInsufficientBalance2": { - "message": "No tiene suficiente ETH en su cuenta para pagar las tarifas de red." - }, "alertMessageNetworkBusy": { "message": "Los precios del gas son altos y las estimaciones son menos precisas." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Detectar automáticamente tokens en su monedero, mostrar NFT y recibir actualizaciones de saldo de cuenta por lotes" }, - "attemptSendingAssets": { - "message": "Puede perder sus activos si intenta enviarlos desde otra red. Transfiera fondos de forma segura entre redes mediante el uso de un puente." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Puede perder sus activos si intenta enviarlos desde otra red. Transfiera fondos de forma segura entre redes usando un puente, como $1" - }, "attemptToCancelSwapForFree": { "message": "Intente cancelar el intercambio de forma gratuita" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Calculando..." }, - "bridgeDontSend": { - "message": "Puente, no enviar" - }, "bridgeEnterAmount": { "message": "Ingrese el monto" }, @@ -954,9 +936,6 @@ "message": "Haga clic aquí para conectar su Ledger a través de WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Siempre puede agregar tókenes manualmente." - }, "close": { "message": "Cerrar" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Solicitud de transacción" }, - "confirmationAlertModalDetails": { - "message": "Para proteger sus activos e información de inicio de sesión, le sugerimos que rechace la solicitud." - }, "confirmationAlertModalTitle": { "message": "Esta solicitud es sospechosa" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Tarifa de gas" }, - "gasIsETH": { - "message": "El gas es $1 " - }, "gasLimit": { "message": "Límite de gas" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "estafas y riesgos en seguridad." }, - "learnToBridge": { - "message": "Aprenda a puentear" - }, "leaveMetaMask": { "message": "¿Dejar MetaMask?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Por favor, complete la transacción en el Snap." }, - "loadingTokens": { - "message": "Cargando tokens..." - }, "localhost": { "message": "Host local 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Las notificaciones del monedero no están activas actualmente." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps está en mantenimiento. Vuelva a comprobarlo más tarde." }, @@ -3047,10 +3011,6 @@ "message": "$1 solicita su aprobación para:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "El token nativo en esta red es de $1. Es el token utilizado para las tarifas de gas. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Editar detalles de la red" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "No, gracias" }, - "noTransactions": { - "message": "No tiene transacciones" - }, "noWebcamFound": { "message": "No se encontró la cámara web del equipo. Vuelva a intentarlo." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Active esta opción para ver las solicitudes de firma en un formato mejorado." }, - "redesignedTransactionsEnabledToggle": { - "message": "Solicitudes de transacción mejoradas" - }, - "redesignedTransactionsToggleDescription": { - "message": "Active esta opción para ver las solicitudes de transacciones en un formato mejorado." - }, "refreshList": { "message": "Actualizar lista" }, @@ -5940,9 +5891,6 @@ "message": "$1 ahora está activo en $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Ahora está usando" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Cambiar de red cancelará todas las confirmaciones pendientes" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Elija su tema MetaMask preferido." }, - "thingsToKeep": { - "message": "Tenga en cuenta:" - }, "thirdPartySoftware": { "message": "Aviso de software de terceros", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "Para: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Esto le permite seleccionar una red para cada sitio en lugar de una única red seleccionada para todos los sitios. Esta función evitará que cambie de red manualmente, lo que puede afectar su experiencia de usuario en ciertos sitios." - }, - "toggleRequestQueueField": { - "message": "Seleccionar redes para cada sitio" - }, - "toggleRequestQueueOff": { - "message": "Desactivado" - }, - "toggleRequestQueueOn": { - "message": "Activado" - }, "token": { "message": "Token" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "estafas de tokens y riesgos de seguridad" }, - "tokenShowUp": { - "message": "Es posible que sus tókenes no aparezcan automáticamente en su monedero. " - }, "tokenStandard": { "message": "Estándar de tokenes" }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 8006ca4405be..4e82c875c760 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -1086,9 +1086,6 @@ "loading": { "message": "Cargando..." }, - "loadingTokens": { - "message": "Cargando tokens..." - }, "localhost": { "message": "Host local 8545" }, @@ -1276,9 +1273,6 @@ "noConversionRateAvailable": { "message": "No hay tasa de conversión disponible" }, - "noTransactions": { - "message": "No tiene transacciones" - }, "noWebcamFound": { "message": "No se encontró la cámara web del equipo. Vuelva a intentarlo." }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 38125572b8ec..a2a85b36d987 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Laadimine..." }, - "loadingTokens": { - "message": "Lubade laadimine..." - }, "lock": { "message": "Logi välja" }, @@ -440,9 +437,6 @@ "noConversionRateAvailable": { "message": "Ühtegi vahetuskurssi pole saadaval" }, - "noTransactions": { - "message": "Teil ei ole tehinguid" - }, "noWebcamFound": { "message": "Teie arvuti veebikaamerat ei leitud. Proovige uuesti." }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index c1a4deb11ce4..3ec5211c2dfb 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "در حال بارکردن…" }, - "loadingTokens": { - "message": "در حال بارگیری رمزیاب ها..." - }, "localhost": { "message": "Localhost 8545 " }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "هیچ نرخ تغییر موجود نمیباشد" }, - "noTransactions": { - "message": "شما هیچ معامله ندارید" - }, "noWebcamFound": { "message": "وب کم کمپیوتر تان پیدا نشد. لطفًا دوباره کوشش کنید." }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index 89e274dd4466..c49ea583598d 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Ladataan..." }, - "loadingTokens": { - "message": "Käyttötunnuksia ladataan..." - }, "localhost": { "message": "Paikallisjoukko 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "Vaihtokurssi ei saatavilla" }, - "noTransactions": { - "message": "Sinulla ei ole tapahtumia" - }, "noWebcamFound": { "message": "Tietokoneesi verkkokameraa ei löytynyt. Ole hyvä ja yritä uudestaan." }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 498c1878fd10..14f91bc5c16a 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -335,9 +335,6 @@ "loading": { "message": "Naglo-load..." }, - "loadingTokens": { - "message": "Naglo-load ng Mga Token..." - }, "lock": { "message": "Mag-log out" }, @@ -384,9 +381,6 @@ "noConversionRateAvailable": { "message": "Walang Presyo ng Palitan na Available" }, - "noTransactions": { - "message": "Wala kang mga transaksyon" - }, "noWebcamFound": { "message": "Hindi nakita ang webcam ng iyong computer. Pakisubukang muli." }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 728dd0a8bf2d..1fe58e2b0f37 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Ajout de réseau" }, - "addingTokens": { - "message": "Ajouter des jetons" - }, "additionalNetworks": { "message": "Réseaux supplémentaires" }, @@ -398,9 +395,6 @@ "alert": { "message": "Alerte" }, - "alertActionBuy": { - "message": "Acheter de l’ETH" - }, "alertActionUpdateGas": { "message": "Mettre à jour la limite de gaz" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Pour effectuer cette transaction, vous devez augmenter la limite de gaz à 21 000 ou plus." }, - "alertMessageInsufficientBalance2": { - "message": "Vous n’avez pas assez d’ETH sur votre compte pour payer les frais de réseau." - }, "alertMessageNetworkBusy": { "message": "Les prix du gaz sont élevés et les estimations sont moins précises." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Détection automatique des jetons dans votre portefeuille, affichage des NFT et mise à jour du solde de plusieurs comptes" }, - "attemptSendingAssets": { - "message": "Si vous essayez d’envoyer des actifs directement d’un réseau à un autre, une perte permanente des actifs pourrait en résulter. Assurez-vous d’utiliser une passerelle." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Si vous essayez d’envoyer des actifs directement d’un réseau à un autre, vous pourriez les perdre définitivement. Utilisez une passerelle comme $1 pour transférer en toute sécurité des fonds d’un réseau à un autre" - }, "attemptToCancelSwapForFree": { "message": "Tentative d’annuler gratuitement le swap" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Calcul en cours…" }, - "bridgeDontSend": { - "message": "Passerelle, ne pas envoyer" - }, "bridgeEnterAmount": { "message": "Saisissez le montant" }, @@ -954,9 +936,6 @@ "message": "Cliquez ici pour connecter votre Ledger via WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Vous pouvez ajouter des jetons manuellement." - }, "close": { "message": "Fermer" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Demande de transaction" }, - "confirmationAlertModalDetails": { - "message": "Pour protéger vos actifs et vos informations de connexion, nous vous suggérons de rejeter la demande." - }, "confirmationAlertModalTitle": { "message": "Cette demande est suspecte" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Frais de gaz" }, - "gasIsETH": { - "message": "Le gaz est $1 " - }, "gasLimit": { "message": "Montant maximal des frais de transaction" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "hameçonnages et risques de sécurité." }, - "learnToBridge": { - "message": "Apprenez à établir une passerelle" - }, "leaveMetaMask": { "message": "Voulez-vous quitter MetaMask ?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Veuillez conclure la transaction sur le snap." }, - "loadingTokens": { - "message": "Chargement des jetons..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Les notifications du portefeuille ne sont actuellement pas activées." }, - "metamaskPortfolio": { - "message": "Portfolio MetaMask." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps est en cours de maintenance. Nous vous invitons à revenir plus tard." }, @@ -3047,10 +3011,6 @@ "message": "$1 vous demande votre approbation pour :", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Le jeton natif de ce réseau est $1. C’est le jeton utilisé pour les frais de gaz. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Modifier les détails du réseau" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "Non merci" }, - "noTransactions": { - "message": "Aucune transaction" - }, "noWebcamFound": { "message": "La caméra de votre ordinateur n’a pas été trouvée. Veuillez réessayer." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Activez cette option pour afficher les demandes de signature dans un format amélioré." }, - "redesignedTransactionsEnabledToggle": { - "message": "Demandes de transaction améliorées" - }, - "redesignedTransactionsToggleDescription": { - "message": "Activez cette option pour afficher les demandes de transaction dans un format amélioré." - }, "refreshList": { "message": "Rafraîchir la liste" }, @@ -5940,9 +5891,6 @@ "message": "$1 est maintenant actif sur $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Vous êtes en train d’utiliser" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Le changement de réseau annulera toutes les confirmations en attente" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Choisissez votre thème MetaMask préféré." }, - "thingsToKeep": { - "message": "Les choses que vous devez garder à l’esprit :" - }, "thirdPartySoftware": { "message": "Avis sur les logiciels développés par des tiers", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "Vers : $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Cette fonction vous permet de sélectionner un réseau pour chaque site au lieu d’un seul réseau pour tous les sites. Vous n’aurez donc pas à changer manuellement de réseau, ce qui pourrait nuire à l’expérience utilisateur sur certains sites." - }, - "toggleRequestQueueField": { - "message": "Sélectionnez les réseaux pour chaque site" - }, - "toggleRequestQueueOff": { - "message": "Désactiver" - }, - "toggleRequestQueueOn": { - "message": "Activer" - }, "token": { "message": "Jeton" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "les arnaques et les risques de piratage informatique" }, - "tokenShowUp": { - "message": "Il se peut que vos jetons n’apparaissent pas automatiquement dans votre portefeuille. " - }, "tokenStandard": { "message": "Jeton standard" }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index 413bf21d586b..c9360ff612de 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "טוען..." }, - "loadingTokens": { - "message": "טוען טוקנים..." - }, "lock": { "message": "התנתקות" }, @@ -443,9 +440,6 @@ "noConversionRateAvailable": { "message": "אין שער המרה זמין" }, - "noTransactions": { - "message": "אין לך עסקאות" - }, "noWebcamFound": { "message": "מצלמת הרשת של מחשבך לא נמצאה. נא לנסות שוב." }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 863257ee1178..885c167be951 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "नेटवर्क जोड़ रहे हैं" }, - "addingTokens": { - "message": "टोकन जोड़ना" - }, "additionalNetworks": { "message": "अतिरिक्त नेटवर्क" }, @@ -398,9 +395,6 @@ "alert": { "message": "एलर्ट" }, - "alertActionBuy": { - "message": "ETH खरीदें" - }, "alertActionUpdateGas": { "message": "गैस लिमिट को अपग्रेड करें" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "इस ट्रांसेक्शन को जारी रखने के लिए, आपको गैस लिमिट को 21000 या अधिक तक बढ़ाना होगा।" }, - "alertMessageInsufficientBalance2": { - "message": "नेटवर्क फीस का भुगतान करने के लिए आपके अकाउंट में पर्याप्त ETH नहीं है।" - }, "alertMessageNetworkBusy": { "message": "गैस प्राइसें अधिक हैं और अनुमान कम सटीक हैं।" }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "अपने वॉलेट में टोकन ऑटोडिटेक्ट करें, NFT प्रदर्शित करें, और बैच अकाउंट बैलेंस संबंधी अपडेट प्राप्त करें" }, - "attemptSendingAssets": { - "message": "अगर आप एसेट्स को सीधे एक नेटवर्क से दूसरे नेटवर्क पर भेजने की कोशिश करते हैं, तो ऐसा करने से आपको एसेट्स का नुकसान हो सकता है। ब्रिज का इस्तेमाल करके नेटवर्कों के बीच फंड्स को सुरक्षित तरीके से ट्रांसफ़र करें।" - }, - "attemptSendingAssetsWithPortfolio": { - "message": "अगर आप एसेट्स को सीधे एक नेटवर्क से दूसरे नेटवर्क पर भेजने की कोशिश करते हैं, तो ऐसा करने से आपको एसेट्स का नुकसान हो सकता है। ब्रिज, जैसे like $1, का इस्तेमाल करके नेटवर्कों के बीच फंड्स को सुरक्षित तरीके से ट्रांसफ़र करें।" - }, "attemptToCancelSwapForFree": { "message": "स्वैप को मुफ्त में कैंसिल करने की कोशिश करें" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "कैलकुलेट किया जा रहा है..." }, - "bridgeDontSend": { - "message": "ब्रिज, न भेजें" - }, "bridgeEnterAmount": { "message": "रकम डालें" }, @@ -954,9 +936,6 @@ "message": "अपने Ledger को WebHID के ज़रिए कनेक्ट करने के लिए यहां क्लिक करें", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "आप कभी भी मैन्युअल रूप से टोकन जोड़ सकते हैं।" - }, "close": { "message": "बंद करें" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "ट्रांसेक्शन अनुरोध" }, - "confirmationAlertModalDetails": { - "message": "आपकी एसेट्स और लॉगिन जानकारी की सुरक्षा के लिए, हम आपको अनुरोध को रिजेक्ट करने का सुझाव देते हैं।" - }, "confirmationAlertModalTitle": { "message": "यह अनुरोध संदिग्ध है" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "गैस फीस" }, - "gasIsETH": { - "message": "गैस $1 है " - }, "gasLimit": { "message": "गैस लिमिट" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "घोटाले और सुरक्षा जोखिम।" }, - "learnToBridge": { - "message": "ब्रिज करना सीखें" - }, "leaveMetaMask": { "message": "MetaMask से बाहर निकलें?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "कृपया Snap पर ट्रांजेक्शन पूरा करें।" }, - "loadingTokens": { - "message": "टोकन लोड हो रहे हैं..." - }, "localhost": { "message": "लोकलहोस्ट 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "वॉलेट नोटिफिकेशंस वर्तमान में सक्रिय नहीं हैं।" }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask स्वैप का रखरखाव किया जा रहा है। कृपया बाद में वापस देखें।" }, @@ -3047,10 +3011,6 @@ "message": "$1 निम्नलिखित के लिए आपका एप्रूवल मांग रहा है:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "इस नेटवर्क पर ओरिजिनल टोकन $1 है। यह गैस फ़ीस के लिए इस्तेमाल किया जाने वाला टोकन है।", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "नेटवर्क का ब्यौरा बदलें" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "जी नहीं, धन्यवाद" }, - "noTransactions": { - "message": "आपके पास कोई ट्रांसेक्शन नहीं है" - }, "noWebcamFound": { "message": "आपके कंप्यूटर का वेबकैम नहीं मिला। कृपया फिर से कोशिश करें।" }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "उन्नत फॉर्मेट में सिग्नेचर अनुरोध देखने के लिए इसे चालू करें।" }, - "redesignedTransactionsEnabledToggle": { - "message": "बेहतर ट्रांसेक्शन के अनुरोध" - }, - "redesignedTransactionsToggleDescription": { - "message": "उन्नत फॉर्मेट में ट्रांसेक्शन के अनुरोध देखने के लिए इसे चालू करें।" - }, "refreshList": { "message": "लिस्ट रिफ्रेश करें" }, @@ -5940,9 +5891,6 @@ "message": "$1 अब $2 पर एक्टिव है", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "आप अब इस्तेमाल कर रहे हैं" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "नेटवर्क स्विच करने से सभी लंबित कन्फर्मेशन कैंसिल हो जाएंगे" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "अपनी पसंदीदा MetaMask थीम चुन लें" }, - "thingsToKeep": { - "message": "ध्यान रखने योग्य बातें:" - }, "thirdPartySoftware": { "message": "थर्ड-पार्टी सॉफ्टवेयर नोटिस", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "प्रति: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "ऐसा करके, आप सभी साइटों के लिए कोई सिंगल नेटवर्क चुनने के बजाय हरेक साइट के लिए एक नेटवर्क चुन सकते हैं। यह फीचर आपको मैन्युअल तरीके से नेटवर्क स्विच करने से रोकता है, इस वजह से कुछ साइटों पर आपका यूज़र अनुभव ख़राब हो सकता है।" - }, - "toggleRequestQueueField": { - "message": "हरेक साइट के लिए नेटवर्क चुनें" - }, - "toggleRequestQueueOff": { - "message": "बंद करें" - }, - "toggleRequestQueueOn": { - "message": "चालू करें" - }, "token": { "message": "टोकन" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "टोकन घोटाले और सुरक्षा जोखिम" }, - "tokenShowUp": { - "message": "हो सकता है आपके वॉलेट में आपके टोकन ऑटोमेटिकली दिखाई नहीं दें। " - }, "tokenStandard": { "message": "टोकन स्टैंडर्ड" }, diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json index a4e2e37bde22..cecc6f26385b 100644 --- a/app/_locales/hn/messages.json +++ b/app/_locales/hn/messages.json @@ -152,9 +152,6 @@ "loading": { "message": "लोड हो रहा है ....." }, - "loadingTokens": { - "message": "टोकन लोड हो रहा है ....." - }, "localhost": { "message": "स्थानीयहोस्ट 8545" }, @@ -196,9 +193,6 @@ "next": { "message": "अगला" }, - "noTransactions": { - "message": "कोई लेन-देन नहीं" - }, "pastePrivateKey": { "message": "यहां अपनी निजी कुंजी स्ट्रिंग चिपकाएं:", "description": "For importing an account from a private key" diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index 7f9334f49f5c..77b864172ae2 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Učitavanje..." }, - "loadingTokens": { - "message": "Učitavanje tokena..." - }, "lock": { "message": "Odjava" }, @@ -443,9 +440,6 @@ "noConversionRateAvailable": { "message": "Nijedan konverzijski tečaj nije dostupan" }, - "noTransactions": { - "message": "Nemate transkacija" - }, "noWebcamFound": { "message": "Mrežna kamera vašeg računala nije pronađena. Pokušajte ponovno." }, diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json index 7309b04dbd05..29df50803fa9 100644 --- a/app/_locales/ht/messages.json +++ b/app/_locales/ht/messages.json @@ -260,9 +260,6 @@ "loading": { "message": "Telechaje..." }, - "loadingTokens": { - "message": "Telechaje Tokens..." - }, "lock": { "message": "Dekonekte" }, @@ -313,9 +310,6 @@ "noConversionRateAvailable": { "message": "Pa gen okenn Konvèsyon Disponib" }, - "noTransactions": { - "message": "Pa gen tranzaksyon" - }, "noWebcamFound": { "message": "Nou pakay jwenn webcam òdinatè ou. Tanpri eseye ankò." }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index 7b2b429ae5ed..9255c752b4a7 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Betöltés..." }, - "loadingTokens": { - "message": "Tokenek betöltése..." - }, "lock": { "message": "Kilépés" }, @@ -443,9 +440,6 @@ "noConversionRateAvailable": { "message": "Nincs elérhető átváltási díj" }, - "noTransactions": { - "message": "Nincsenek tranzakciói" - }, "noWebcamFound": { "message": "Nem található számítógéped webkamerája. Kérünk, próbáld újra." }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 418ca4b60489..28dfd21fec57 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Menambahkan Jaringan" }, - "addingTokens": { - "message": "Menambahkan token" - }, "additionalNetworks": { "message": "Jaringan tambahan" }, @@ -398,9 +395,6 @@ "alert": { "message": "Peringatan" }, - "alertActionBuy": { - "message": "Beli ETH" - }, "alertActionUpdateGas": { "message": "Perbarui batas gas" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Untuk melanjutkan transaksi ini, Anda perlu meningkatkan batas gas menjadi 21000 atau lebih tinggi." }, - "alertMessageInsufficientBalance2": { - "message": "Anda tidak memiliki cukup ETH di akun untuk membayar biaya jaringan." - }, "alertMessageNetworkBusy": { "message": "Harga gas tinggi dan estimasinya kurang akurat." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Autodeteksi token di dompet Anda, tampilkan NFT, dan dapatkan pembaruan saldo akun secara batch" }, - "attemptSendingAssets": { - "message": "Aset Anda berpotensi hilang jika mencoba mengirimnya dari jaringan lain. Transfer dana secara aman antar jaringan menggunakan bridge." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Aset Anda berpotensi hilang jika mencoba mengirimnya melalui jaringan lain. Transfer dana antar jaringan dengan aman menggunakan bridge, seperti $1" - }, "attemptToCancelSwapForFree": { "message": "Mencoba membatalkan pertukaran secara gratis" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Menghitung..." }, - "bridgeDontSend": { - "message": "Bridge, jangan kirim" - }, "bridgeEnterAmount": { "message": "Masukkan jumlah" }, @@ -954,9 +936,6 @@ "message": "Klik di sini untuk menghubungkan Ledger Anda melalui WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Anda dapat menambahkan token secara manual setiap saat." - }, "close": { "message": "Tutup" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Permintaan transaksi" }, - "confirmationAlertModalDetails": { - "message": "Untuk melindungi aset dan informasi login Anda, sebaiknya tolak permintaan tersebut." - }, "confirmationAlertModalTitle": { "message": "Permintaan ini mencurigakan" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Biaya gas" }, - "gasIsETH": { - "message": "Gas bernilai $1 " - }, "gasLimit": { "message": "Batas gas" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "penipuan dan risiko keamanan." }, - "learnToBridge": { - "message": "Pelajari bridge" - }, "leaveMetaMask": { "message": "Keluar dari MetaMask?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Selesaikan transaksi di Snap." }, - "loadingTokens": { - "message": "Memuat token..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Saat ini notifikasi dompet tidak aktif." }, - "metamaskPortfolio": { - "message": "Portfolio MetaMask." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swap sedang dalam pemeliharaan. Harap periksa kembali nanti." }, @@ -3047,10 +3011,6 @@ "message": "$1 meminta persetujuan Anda untuk:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Token asli di jaringan ini adalah $1. Ini merupakan token yang digunakan untuk biaya gas. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Edit detail jaringan" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "Tidak, terima kasih" }, - "noTransactions": { - "message": "Anda tidak memiliki transaksi" - }, "noWebcamFound": { "message": "Webcam komputer Anda tidak ditemukan. Harap coba lagi." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Aktifkan ini untuk melihat permintaan tanda tangan dalam format yang disempurnakan." }, - "redesignedTransactionsEnabledToggle": { - "message": "Penyempurnaan permintaan transaksi" - }, - "redesignedTransactionsToggleDescription": { - "message": "Aktifkan ini untuk melihat permintaan transaksi dalam format yang disempurnakan." - }, "refreshList": { "message": "Segarkan daftar" }, @@ -5940,9 +5891,6 @@ "message": "$1 kini telah aktif di $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Saat ini Anda menggunakan" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Mengalihkan jaringan akan membatalkan semua konfirmasi yang berstatus menunggu" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Pilih tema MetaMask yang Anda sukai." }, - "thingsToKeep": { - "message": "Ingatlah:" - }, "thirdPartySoftware": { "message": "Pemberitahuan perangkat lunak pihak ketiga", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "Ke: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Hal ini memungkinkan Anda memilih jaringan untuk setiap situs, daripada satu jaringan yang dipilih untuk semua situs. Fitur ini akan mencegah Anda berpindah jaringan secara manual, yang dapat merusak pengalaman pengguna di situs tertentu." - }, - "toggleRequestQueueField": { - "message": "Pilih jaringan untuk setiap situs" - }, - "toggleRequestQueueOff": { - "message": "Nonaktif" - }, - "toggleRequestQueueOn": { - "message": "Aktif" - }, "token": { "message": "Token" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "penipuan dan risiko keamanan token" }, - "tokenShowUp": { - "message": "Token Anda mungkin tidak muncul secara otomatis di dompet Anda. " - }, "tokenStandard": { "message": "Standar token" }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index 05cccdac0359..a88d710a6f81 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -252,9 +252,6 @@ "assetOptions": { "message": "Opzioni asset" }, - "attemptSendingAssets": { - "message": "Se si tenta di inviare risorse direttamente da una rete all'altra, ciò potrebbe comportare una perdita permanente della risorca coinvolta. Assicurati di usare un bridge." - }, "attributions": { "message": "Attribuzioni" }, @@ -369,9 +366,6 @@ "message": "Clicca qui per connettere il tuo Ledger tramite WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Clicca qui per aggiungere manualmente i token." - }, "close": { "message": "Chiudi" }, @@ -971,9 +965,6 @@ "loading": { "message": "Caricamento..." }, - "loadingTokens": { - "message": "Caricamento Tokens..." - }, "lock": { "message": "Disconnetti" }, @@ -1055,9 +1046,6 @@ "noConversionRateAvailable": { "message": "Tasso di conversione non disponibile" }, - "noTransactions": { - "message": "Nessuna Transazione" - }, "noWebcamFound": { "message": "La fotocamera del tuo computer non è stata trovata. Riprova." }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 41e34d26dd2d..b636ff2cba25 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "ネットワークを追加中" }, - "addingTokens": { - "message": "トークンを追加しています" - }, "additionalNetworks": { "message": "他のネットワーク" }, @@ -398,9 +395,6 @@ "alert": { "message": "アラート" }, - "alertActionBuy": { - "message": "ETHを購入" - }, "alertActionUpdateGas": { "message": "ガスリミットを更新" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "このトランザクションを続行するには、ガスリミットを21000以上に上げる必要があります。" }, - "alertMessageInsufficientBalance2": { - "message": "アカウントにネットワーク手数料を支払うのに十分なETHがありません。" - }, "alertMessageNetworkBusy": { "message": "ガス価格が高く、見積もりはあまり正確ではありません。" }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "ウォレットのトークンを自動検出し、NFTを表示して、アカウント残高の最新情報を一括で取得します" }, - "attemptSendingAssets": { - "message": "別のネットワークからアセットを送ろうとすると、アセットが失われる可能性があります。ネットワーク間で安全に資金を移動するには、必ずブリッジを使用してください。" - }, - "attemptSendingAssetsWithPortfolio": { - "message": "別のネットワークからアセットを送ろうとすると、アセットが失われる可能性があります。ネットワーク間で安全に資金を移動するには、必ず$1などのブリッジを使用してください。" - }, "attemptToCancelSwapForFree": { "message": "無料でスワップのキャンセルを試行" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "計算中..." }, - "bridgeDontSend": { - "message": "ブリッジを使用してください" - }, "bridgeEnterAmount": { "message": "金額を入力" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "ブリッジ先:" }, - "browserNotSupported": { "message": "ご使用のブラウザはサポートされていません..." }, @@ -955,9 +936,6 @@ "message": "ここをクリックして、WebHIDでLedgerを接続します", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "トークンはいつでも手動で追加できます。" - }, "close": { "message": "閉じる" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "トランザクションの要求" }, - "confirmationAlertModalDetails": { - "message": "資産とログイン情報を守るため、要求を拒否することをお勧めします。" - }, "confirmationAlertModalTitle": { "message": "この要求は不審です" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "ガス代" }, - "gasIsETH": { - "message": "ガス代は$1です" - }, "gasLimit": { "message": "ガスリミット" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "詐欺やセキュリティのリスク。" }, - "learnToBridge": { - "message": "ブリッジの使い方" - }, "leaveMetaMask": { "message": "MetaMaskから離れますか?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Snapでトランザクションを完了させてください。" }, - "loadingTokens": { - "message": "トークンをロードしています..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "ウォレットの通知は現在無効になっています" }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio。" - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swapsはメンテナンス中です。後でもう一度確認してください。" }, @@ -3048,10 +3011,6 @@ "message": "$1が次の承認を求めています:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "このネットワークのネイティブトークンは$1です。ガス代にもこのトークンが使用されます。", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "ネットワークの詳細を編集" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "結構です" }, - "noTransactions": { - "message": "トランザクションがありません" - }, "noWebcamFound": { "message": "お使いのコンピューターのWebカメラが見つかりませんでした。もう一度お試しください。" }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "この機能をオンにすると、強化された形式で署名要求が表示されます。" }, - "redesignedTransactionsEnabledToggle": { - "message": "改善されたトランザクション要求" - }, - "redesignedTransactionsToggleDescription": { - "message": "トランザクション要求を強化された形式で表示するには、この機能をオンにします。" - }, "refreshList": { "message": "リストを更新" }, @@ -5941,9 +5891,6 @@ "message": "$1が$2で有効になりました", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "次に切り替えました:" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "ネットワークを切り替えると、保留中の承認がすべてキャンセルされます" }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "ご希望のMetaMaskテーマを選択してください。" }, - "thingsToKeep": { - "message": "留意点:" - }, "thirdPartySoftware": { "message": "サードパーティソフトウェアに関する通知", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "移動先: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "これにより、選択した単一のネットワークをすべてのサイトで使用するのではなく、サイトごとにネットワークを選択できます。この機能により、特定のサイトでのユーザーエクスペリエンスの妨げとなる、ネットワークの手動切り替えが不要になります。" - }, - "toggleRequestQueueField": { - "message": "サイトごとにネットワークを選択する" - }, - "toggleRequestQueueOff": { - "message": "オフ" - }, - "toggleRequestQueueOn": { - "message": "オン" - }, "token": { "message": "トークン" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "トークン関連の詐欺やセキュリティのリスク" }, - "tokenShowUp": { - "message": "トークンはウォレットに自動的に表示されない可能性があります。" - }, "tokenStandard": { "message": "トークン規格" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index 120651f0b759..148a820f5bfa 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "ಲೋಡ್ ಆಗುತ್ತಿದೆ..." }, - "loadingTokens": { - "message": "ಟೋಕನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..." - }, "localhost": { "message": "ಲೋಕಲ್‌ಹೋಸ್ಟ್ 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "ಯಾವುದೇ ಪರಿವರ್ತನೆ ದರ ಲಭ್ಯವಿಲ್ಲ" }, - "noTransactions": { - "message": "ನೀವು ಯಾವುದೇ ವಹಿವಾಟುಗಳನ್ನು ಹೊಂದಿಲ್ಲ" - }, "noWebcamFound": { "message": "ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ವೆಬ್‌ಕ್ಯಾಮ್ ಕಂಡುಬಂದಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ." }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 8c0f26b8cad7..99d94087594e 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "네트워크 추가" }, - "addingTokens": { - "message": "토큰 추가" - }, "additionalNetworks": { "message": "추가 네트워크" }, @@ -398,9 +395,6 @@ "alert": { "message": "경고" }, - "alertActionBuy": { - "message": "ETH 매수" - }, "alertActionUpdateGas": { "message": "가스 한도 업데이트" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "이 트랜잭션을 계속 진행하려면, 가스 한도를 21000 이상으로 늘려야 합니다." }, - "alertMessageInsufficientBalance2": { - "message": "계정에 네트워크 수수료로 지불할 ETH가 부족합니다." - }, "alertMessageNetworkBusy": { "message": "가스비가 높고 견적의 정확도도 떨어집니다." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "지갑에서 토큰을 자동으로 감지하고, NFT를 표시하며, 계정 잔액을 일괄 업데이트하세요." }, - "attemptSendingAssets": { - "message": "다른 네트워크로 자산을 직접 전송하면 자산이 영구적으로 손실될 수 있습니다. 브릿지를 이용하여 네트워크 간에 자금을 안전하게 전송하세요." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "다른 네트워크에서 자산을 전송하려고 하면 자산이 손실될 수 있습니다. $1 같은 브릿지를 사용하여 네트워크 간에 자산을 안전하게 전송하세요." - }, "attemptToCancelSwapForFree": { "message": "무료 스왑 취소 시도" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "계산 중..." }, - "bridgeDontSend": { - "message": "전송하지 마세요, 브릿지 하세요" - }, "bridgeEnterAmount": { "message": "금액 입력" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "브릿지 대상" }, - "browserNotSupported": { "message": "지원되지 않는 브라우저입니다..." }, @@ -955,9 +936,6 @@ "message": "WebHID를 통해 Ledger를 연결하려면 여기를 클릭하세요.", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "토큰은 언제든지 직접 추가할 수 있습니다." - }, "close": { "message": "닫기" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "트랜젝션 요청" }, - "confirmationAlertModalDetails": { - "message": "자산과 로그인 정보 보호를 위해 요청을 거부하는 것이 좋습니다." - }, "confirmationAlertModalTitle": { "message": "의심스러운 요청입니다" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "가스비" }, - "gasIsETH": { - "message": "가스는 $1입니다 " - }, "gasLimit": { "message": "가스 한도" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "사기 및 보안 위험" }, - "learnToBridge": { - "message": "브릿지 알아보기" - }, "leaveMetaMask": { "message": "MetaMask를 나가시겠습니까?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Snap에서 트랜잭션을 완료하세요." }, - "loadingTokens": { - "message": "토큰 불러오는 중..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "현재 지갑 알림이 꺼져 있습니다." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps 점검 중입니다. 나중에 다시 확인하세요." }, @@ -3048,10 +3011,6 @@ "message": "$1에서 다음 승인을 요청합니다:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "이 네트워크의 네이티브 토큰은 $1입니다. 이는 가스비 지불에 사용하는 토큰입니다. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "네트워크 세부 정보 편집" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "괜찮습니다" }, - "noTransactions": { - "message": "트랜잭션이 없습니다." - }, "noWebcamFound": { "message": "컴퓨터의 웹캠을 찾을 수 없습니다. 다시 시도하세요." }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "이 기능을 켜면 개선된 형식의 서명 요청을 확인할 수 있습니다." }, - "redesignedTransactionsEnabledToggle": { - "message": "개선된 트랜잭션 요청" - }, - "redesignedTransactionsToggleDescription": { - "message": "이 기능을 켜면 개선된 형식의 트랜잭션 요청을 확인할 수 있습니다." - }, "refreshList": { "message": "새로 고침 목록" }, @@ -5941,9 +5891,6 @@ "message": "$1 계정이 현재 $2 네트워크에서 활성화되어 있습니다", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "다음을 사용 중입니다:" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "네트워크를 전환하면 대기 중인 모든 컨펌 작업이 취소됩니다." }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "원하는 MetaMask 테마를 선택하세요." }, - "thingsToKeep": { - "message": "유의 사항:" - }, "thirdPartySoftware": { "message": "타사 소프트웨어 알림", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "수신: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "이 기능을 이용하면 모든 사이트에 한 가지 네트워크를 선택하여 사용하는 대신, 사이트별로 네트워크를 다르게 선택할 수 있습니다. 이 기능을 사용하면 수동으로 네트워크를 전환하지 않아도 되므로 특정 사이트에서 사용자 경험이 저해되지 않습니다." - }, - "toggleRequestQueueField": { - "message": "각 사이트별 네트워크 선택" - }, - "toggleRequestQueueOff": { - "message": "끄기" - }, - "toggleRequestQueueOn": { - "message": "켜기" - }, "token": { "message": "토큰" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "토큰 사기 및 보안 위험" }, - "tokenShowUp": { - "message": "토큰이 지갑에 자동으로 표시되지 않을 수 있습니다. " - }, "tokenStandard": { "message": "토큰 표준" }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index fe825ae6b798..3e5586f39f50 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Įkeliama..." }, - "loadingTokens": { - "message": "Įkeliami žetonai..." - }, "localhost": { "message": "Vietinis serveris 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "Nėra keitimo kurso" }, - "noTransactions": { - "message": "Neturite jokių operacijų" - }, "noWebcamFound": { "message": "Jūsų kompiuterio vaizdo kamera nerasta. Bandykite dar kartą." }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 697af7849327..a1e166937385 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Notiek ielāde..." }, - "loadingTokens": { - "message": "Ielādē marķierus..." - }, "localhost": { "message": "Resursdators 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "Konversijas kurss nav pieejams" }, - "noTransactions": { - "message": "Jums nav neviena darījuma." - }, "noWebcamFound": { "message": "Jūsu datora tīmekļa kamera netika atrasta. Lūdzu, mēģiniet vēlreiz." }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index dc42e639ff2a..3605febbc7d7 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -374,9 +374,6 @@ "loading": { "message": "Memuatkan..." }, - "loadingTokens": { - "message": "Memuatkan Token..." - }, "lock": { "message": "Log keluar" }, @@ -433,9 +430,6 @@ "noConversionRateAvailable": { "message": "Tiada Kadar Penukaran yang Tersedia" }, - "noTransactions": { - "message": "Anda tiada transaksi" - }, "noWebcamFound": { "message": "Webcam komputer anda tidak dijumpai. Sila cuba semula." }, diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json index cbebb9a14563..acf66091845f 100644 --- a/app/_locales/nl/messages.json +++ b/app/_locales/nl/messages.json @@ -149,9 +149,6 @@ "loading": { "message": "Bezig met laden..." }, - "loadingTokens": { - "message": "Tokens laden ..." - }, "lock": { "message": "Uitloggen" }, @@ -186,9 +183,6 @@ "next": { "message": "volgende" }, - "noTransactions": { - "message": "Geen transacties" - }, "pastePrivateKey": { "message": "Plak hier uw privésleutelstring:", "description": "For importing an account from a private key" diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 45a101fc83a5..8459d3ef3a5f 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -369,9 +369,6 @@ "loading": { "message": "Laster inn ..." }, - "loadingTokens": { - "message": "Laster tokener ..." - }, "localhost": { "message": "Lokalvert 8545" }, @@ -434,9 +431,6 @@ "noConversionRateAvailable": { "message": "Ingen konverteringsrate tilgjengelig " }, - "noTransactions": { - "message": "Du har ingen transaksjoner" - }, "noWebcamFound": { "message": "Datamaskinens webkamera ble ikke funnet. Vennligst prøv igjen." }, diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json index 3d40dbfefd77..3dd9ae28d896 100644 --- a/app/_locales/ph/messages.json +++ b/app/_locales/ph/messages.json @@ -700,9 +700,6 @@ "loading": { "message": "Nilo-load..." }, - "loadingTokens": { - "message": "Nilo-load ang Mga Token..." - }, "localhost": { "message": "Localhost 8545" }, @@ -822,9 +819,6 @@ "noConversionRateAvailable": { "message": "Hindi Available ang Rate ng Conversion" }, - "noTransactions": { - "message": "Wala kang transaksyon" - }, "noWebcamFound": { "message": "Hindi nakita ang webcam ng iyong computer. Pakisubukan ulit." }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index d22673fa9f1f..f7f5111c9973 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Ładowanie..." }, - "loadingTokens": { - "message": "Ładowanie tokenów..." - }, "localhost": { "message": "Serwer lokalny 8545" }, @@ -443,9 +440,6 @@ "noConversionRateAvailable": { "message": "Brak kursu waluty" }, - "noTransactions": { - "message": "Nie ma transakcji" - }, "noWebcamFound": { "message": "Twoja kamera nie została znaleziona. Spróbuj ponownie." }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 77312d33bb07..d77c74054bf9 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Adicionar rede" }, - "addingTokens": { - "message": "Adicionando tokens" - }, "additionalNetworks": { "message": "Redes adicionais" }, @@ -398,9 +395,6 @@ "alert": { "message": "Alerta" }, - "alertActionBuy": { - "message": "Comprar ETH" - }, "alertActionUpdateGas": { "message": "Atualizar limite de gás" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Para continuar com essa transação, você precisará aumentar o limite de gás para 21000 ou mais." }, - "alertMessageInsufficientBalance2": { - "message": "Você não tem ETH suficiente em sua conta para pagar as taxas de rede." - }, "alertMessageNetworkBusy": { "message": "Os preços do gás são altos e as estimativas são menos precisas." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Detecte automaticamente os tokens em sua carteira, exiba NFTs e receba atualizações de saldo de contas em lote" }, - "attemptSendingAssets": { - "message": "Você poderá perder seus ativos se tentar enviá-los a partir de outra rede. Transfira fundos entre redes com segurança usando uma ponte." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Você poderá perder seus ativos se tentar enviá-los a partir de outra rede. Transfira os fundos com segurança entre redes usando uma ponte, como $1" - }, "attemptToCancelSwapForFree": { "message": "Tentar cancelar a troca sem custo" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Calculando..." }, - "bridgeDontSend": { - "message": "Usar uma ponte, não enviar" - }, "bridgeEnterAmount": { "message": "Insira o valor" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "Ponte para" }, - "browserNotSupported": { "message": "Seu navegador não é compatível..." }, @@ -955,9 +936,6 @@ "message": "Clique aqui para conectar seu Ledger por meio do WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Sempre é possível adicionar tokens manualmente." - }, "close": { "message": "Fechar" }, @@ -1061,8 +1039,8 @@ "confirmTitleTransaction": { "message": "Solicitação de transação" }, - "confirmationAlertModalDetails": { - "message": "Para proteger seus ativos e informações de login, é recomendável que você recuse a solicitação." + "confirmationAlertDetails": { + "message": "Para proteger seus ativos, é recomendável que você recuse a solicitação." }, "confirmationAlertModalTitle": { "message": "Esta solicitação é suspeita" @@ -2139,9 +2117,6 @@ "gasFee": { "message": "Taxa de gás" }, - "gasIsETH": { - "message": "O gás é $1 " - }, "gasLimit": { "message": "Limite de gás" }, @@ -2703,9 +2678,6 @@ "learnScamRisk": { "message": "golpes e riscos de segurança." }, - "learnToBridge": { - "message": "Aprenda a usar uma ponte" - }, "leaveMetaMask": { "message": "Sair da MetaMask?" }, @@ -2797,9 +2769,6 @@ "loadingScreenSnapMessage": { "message": "Por favor, conclua a transação no Snap." }, - "loadingTokens": { - "message": "Carregando tokens..." - }, "localhost": { "message": "Host local 8545" }, @@ -2901,9 +2870,6 @@ "metamaskNotificationsAreOff": { "message": "As notificações de carteiras estão inativas no momento." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "O recurso de Trocas da MetaMask está em manutenção. Verifique novamente mais tarde." }, @@ -3048,10 +3014,6 @@ "message": "$1 solicita sua aprovação para:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "O token nativo dessa rede é $1. Esse é o token usado para taxas de gás.", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Editar detalhes da rede" }, @@ -3336,9 +3298,6 @@ "noThanks": { "message": "Não, obrigado" }, - "noTransactions": { - "message": "Você não tem transações" - }, "noWebcamFound": { "message": "A webcam do seu computador não foi encontrada. Tente novamente." }, @@ -4351,12 +4310,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Ative para ver as solicitações de assinatura em um formato aprimorado." }, - "redesignedTransactionsEnabledToggle": { - "message": "Solicitações de transação aprimoradas" - }, - "redesignedTransactionsToggleDescription": { - "message": "Ative esta opção para ver as solicitações de transação em formato aprimorado." - }, "refreshList": { "message": "Atualizar lista" }, @@ -5941,9 +5894,6 @@ "message": "$1 agora está ativa na $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Você alternou para" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "A alternância de redes cancelará todas as confirmações pendentes" }, @@ -5980,9 +5930,6 @@ "themeDescription": { "message": "Escolha o seu tema preferido para a MetaMask." }, - "thingsToKeep": { - "message": "Informações importantes:" - }, "thirdPartySoftware": { "message": "Aviso de software de terceiros", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5960,6 @@ "message": "Para: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Isso permite que você selecione uma rede para cada site em vez de uma única rede selecionada para todos eles. O recurso evitará que você alterne manualmente entre redes, o que pode atrapalhar sua experiência de usuário em determinados sites." - }, - "toggleRequestQueueField": { - "message": "Selecionar redes para cada site" - }, - "toggleRequestQueueOff": { - "message": "Não" - }, - "toggleRequestQueueOn": { - "message": "Sim" - }, "token": { "message": "Token" }, @@ -6064,9 +5999,6 @@ "tokenScamSecurityRisk": { "message": "golpes e riscos de segurança envolvendo tokens" }, - "tokenShowUp": { - "message": "Seus tokens podem não aparecer automaticamente em sua carteira." - }, "tokenStandard": { "message": "Padrão de token" }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 0bc1005ad674..3c9c30147276 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -1086,9 +1086,6 @@ "loading": { "message": "Carregando..." }, - "loadingTokens": { - "message": "Carregando tokens..." - }, "localhost": { "message": "Host local 8545" }, @@ -1276,9 +1273,6 @@ "noConversionRateAvailable": { "message": "Não há uma taxa de conversão disponível" }, - "noTransactions": { - "message": "Você não tem transações" - }, "noWebcamFound": { "message": "A webcam do seu computador não foi encontrada. Tente novamente." }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index 912accba29be..db440fcfd264 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -375,9 +375,6 @@ "loading": { "message": "Se încarcă…" }, - "loadingTokens": { - "message": "Se încarcă token-urile..." - }, "lock": { "message": "Deconectați-vă" }, @@ -437,9 +434,6 @@ "noConversionRateAvailable": { "message": "Nici o rată de conversie disponibilă" }, - "noTransactions": { - "message": "Nu aveți tranzacții" - }, "noWebcamFound": { "message": "Webcam-ul computerului dvs. nu a fost găsit. Vă rugăm să încercați din nou." }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 89ba6f0d0bd9..7f79904c5e4c 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Добавление сети" }, - "addingTokens": { - "message": "Добавление токенов" - }, "additionalNetworks": { "message": "Дополнительные сети" }, @@ -398,9 +395,6 @@ "alert": { "message": "Оповещение" }, - "alertActionBuy": { - "message": "Купить ETH" - }, "alertActionUpdateGas": { "message": "Обновить лимит газа" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Чтобы продолжить эту транзакцию, вам необходимо увеличить лимит газа до 21 000 или выше." }, - "alertMessageInsufficientBalance2": { - "message": "У вас на счету недостаточно ETH для оплаты комиссий сети." - }, "alertMessageNetworkBusy": { "message": "Цены газа высоки, а оценки менее точны." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Автоматически обнаруживайте токены в своем кошельке, отображайте NFT и получайте пакетные обновления баланса счета" }, - "attemptSendingAssets": { - "message": "Вы можете потерять свои активы, если попытаетесь отправить их из другой сети. Безопасно переводите средства между сетями с помощью моста." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Попытка отправки активов напрямую из одной сети в другую может привести к необратимой потере активов. Следует использовать мост, такой как $1" - }, "attemptToCancelSwapForFree": { "message": "Бесплатная попытка отменить своп" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Расчет..." }, - "bridgeDontSend": { - "message": "Мост, не отправлять" - }, "bridgeEnterAmount": { "message": "Введите сумму" }, @@ -954,9 +936,6 @@ "message": "Нажмите здесь, чтобы подключить свой Ledger через WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Вы также можете добавлять токены вручную." - }, "close": { "message": "Закрыть" }, @@ -1060,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Запрос транзакции" }, - "confirmationAlertModalDetails": { - "message": "Чтобы защитить ваши активы и данные для входа, рекомендуем отклонить запрос." - }, "confirmationAlertModalTitle": { "message": "Этот запрос подозрительный" }, @@ -2138,9 +2114,6 @@ "gasFee": { "message": "Плата за газ" }, - "gasIsETH": { - "message": "Газ стоит $1 " - }, "gasLimit": { "message": "Лимит газа" }, @@ -2702,9 +2675,6 @@ "learnScamRisk": { "message": "мошенничество и угрозы безопасности." }, - "learnToBridge": { - "message": "Научитесь создавать мост для" - }, "leaveMetaMask": { "message": "Выйти из MetaMask?" }, @@ -2796,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Завершите транзакцию в Snap." }, - "loadingTokens": { - "message": "Загрузка токенов..." - }, "localhost": { "message": "Локальный хост 8545" }, @@ -2900,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Уведомления кошелька в настоящее время неактивны." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "Сервис свопов MetaMask на техобслуживании. Зайдите позже." }, @@ -3047,10 +3011,6 @@ "message": "$1 запрашивает ваше одобрение на:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Нативный токен этой сети — $1. Этот токен используется для внесения платы за газ. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Изменить сведения о сети" }, @@ -3335,9 +3295,6 @@ "noThanks": { "message": "Нет, спасибо" }, - "noTransactions": { - "message": "У вас нет транзакций" - }, "noWebcamFound": { "message": "Веб-камера вашего компьютера не найдена. Попробуйте еще раз." }, @@ -4350,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Включите эту опцию, чтобы видеть запросы на подпись в расширенном формате." }, - "redesignedTransactionsEnabledToggle": { - "message": "Улучшенные запросы транзакций" - }, - "redesignedTransactionsToggleDescription": { - "message": "Включите эту опцию, чтобы видеть запросы транзакций в расширенном формате." - }, "refreshList": { "message": "Обновить список" }, @@ -5940,9 +5891,6 @@ "message": "$1 теперь активен в $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Сейчас вы используете" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "В случае смены сетей все ожидающие подтверждения будут отменены" }, @@ -5979,9 +5927,6 @@ "themeDescription": { "message": "Выберите предпочитаемую тему MetaMask." }, - "thingsToKeep": { - "message": "Что нужно помнить:" - }, "thirdPartySoftware": { "message": "Уведомление о стороннем ПО", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6012,18 +5957,6 @@ "message": "Адресат: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Это позволяет вам выбрать сеть для каждого сайта вместо одной выбранной сети для всех сайтов. Эта функция не позволит вам переключать сети вручную, что может снизить удобство использования некоторых сайтов." - }, - "toggleRequestQueueField": { - "message": "Выберите сети для каждого сайта" - }, - "toggleRequestQueueOff": { - "message": "Выкл." - }, - "toggleRequestQueueOn": { - "message": "Вкл." - }, "token": { "message": "Токен" }, @@ -6063,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "мошенничество с токенами и угрозы безопасности" }, - "tokenShowUp": { - "message": "Ваши токены могут не отображаться автоматически в вашем кошельке. " - }, "tokenStandard": { "message": "Стандарт токена" }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 829435f28ff7..a65bc68593f6 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -368,9 +368,6 @@ "loading": { "message": "Načítám..." }, - "loadingTokens": { - "message": "Načítám tokeny..." - }, "lock": { "message": "Odhlásit" }, @@ -421,9 +418,6 @@ "noConversionRateAvailable": { "message": "Nie je k dispozícii žiadna sadzba konverzie" }, - "noTransactions": { - "message": "Žádné transakce" - }, "noWebcamFound": { "message": "Webová kamera vášho počítača sa nenašla. Skúste znova." }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index cb82e0358212..ebc303e90c5c 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -375,9 +375,6 @@ "loading": { "message": "Nalaganje ..." }, - "loadingTokens": { - "message": "Nalaganje žetonov ..." - }, "lock": { "message": "Odjava" }, @@ -434,9 +431,6 @@ "noConversionRateAvailable": { "message": "Menjalni tečaj ni na voljo" }, - "noTransactions": { - "message": "Nimate transakcij" - }, "noWebcamFound": { "message": "Spletna kamera ni najdena. Poskusite znova kasneje." }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index e15ae23086b3..1bbcd0754b92 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -378,9 +378,6 @@ "loading": { "message": "Учитава се..." }, - "loadingTokens": { - "message": "Učitavanje tokena..." - }, "lock": { "message": "Odjavi se" }, @@ -437,9 +434,6 @@ "noConversionRateAvailable": { "message": "Nije dostupan kurs za konverziju" }, - "noTransactions": { - "message": "Nemate transakcije" - }, "noWebcamFound": { "message": "Nije pronađena veb kamera na vašem kompjuteru. Molimo vas pokušajte ponovo." }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index 163cdebc426e..818f1eb498d6 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -375,9 +375,6 @@ "loading": { "message": "Läser in..." }, - "loadingTokens": { - "message": "Laddar tokens..." - }, "lock": { "message": "Logga ut" }, @@ -434,9 +431,6 @@ "noConversionRateAvailable": { "message": "Ingen omräkningskurs tillgänglig" }, - "noTransactions": { - "message": "Du har inga överföringar" - }, "noWebcamFound": { "message": "Din dators webbkamera hittades inte. Vänligen försök igen." }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index c1535d76cdd8..c33abcb51a18 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -372,9 +372,6 @@ "loading": { "message": "Inapakia..." }, - "loadingTokens": { - "message": "Inapakia Vianzio..." - }, "lock": { "message": "Toka kwenye akaunti" }, @@ -428,9 +425,6 @@ "noConversionRateAvailable": { "message": "Hakuna Kiwango cha Ubadilishaji" }, - "noTransactions": { - "message": "Huna miamala." - }, "noWebcamFound": { "message": "Kamera yako ya kumpyuta haikupatikana. Tafadhali jaribu tena." }, diff --git a/app/_locales/ta/messages.json b/app/_locales/ta/messages.json index d5d1929a2dc4..c5905e4e0bee 100644 --- a/app/_locales/ta/messages.json +++ b/app/_locales/ta/messages.json @@ -209,9 +209,6 @@ "loading": { "message": "ஏற்றுகிறது…" }, - "loadingTokens": { - "message": "டோக்கன்களை ஏற்றுகிறது ..." - }, "localhost": { "message": "லோக்கல் ஹோஸ்ட் 8545" }, @@ -256,9 +253,6 @@ "next": { "message": "அடுத்தது" }, - "noTransactions": { - "message": "பரிவர்த்தனைகள் இல்லை" - }, "off": { "message": "ஆஃப்" }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index e6c074fe1264..96166c6fb6ba 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -194,9 +194,6 @@ "loading": { "message": "กำลังโหลด..." }, - "loadingTokens": { - "message": "กำลังโหลดโทเค็น..." - }, "lock": { "message": "ออกจากระบบ" }, @@ -235,9 +232,6 @@ "next": { "message": "ถัดไป" }, - "noTransactions": { - "message": "ยังไม่มีรายการธุรกรรม" - }, "on": { "message": "เปิด" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index d235dc123943..3f1d364933f6 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Nagdaragdag ng Network" }, - "addingTokens": { - "message": "Nagdaragdag ng mga token" - }, "additionalNetworks": { "message": "Mga karagdagang network" }, @@ -398,9 +395,6 @@ "alert": { "message": "Alerto" }, - "alertActionBuy": { - "message": "Bumili ng ETH" - }, "alertActionUpdateGas": { "message": "I-update ang gas limit" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Para magpatuloy sa transaksyong ito, kakailanganin mong dagdagan ang gas limit sa 21000 o mas mataas." }, - "alertMessageInsufficientBalance2": { - "message": "Wala kang sapat na ETH sa iyong account para bayaran ang mga bayarin sa network." - }, "alertMessageNetworkBusy": { "message": "Ang mga presyo ng gas ay mataas at ang pagtantiya ay hindi gaanong tumpak." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "I-autodetect ang mga token sa wallet mo, ipakita ang mga NFT, at kumuha ng naka-batch na mga update sa balanse ng account" }, - "attemptSendingAssets": { - "message": "Maaari mong mawala ang mga asset kung susubukan mo itong ipadala mula sa isang network papunta sa isa pa. Ligtas ng maglipat ng pondo sa pagitan ng mga network sa pamamagitan ng paggamit ng bridge." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Maaaring mawala ang iyong mga asset kung susubukan mong ipadala ito mula sa ibang network. Ilipat ang mga pondo nang ligtas sa pagitan ng mga network gamit ang isang bridge, tulad ng $1" - }, "attemptToCancelSwapForFree": { "message": "Subukang kanselahin ang swap nang libre" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Nagkakalkula..." }, - "bridgeDontSend": { - "message": "Bridge, huwag ipadala" - }, "bridgeEnterAmount": { "message": "Ilagay ang halaga" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "I-bridge papunta sa" }, - "browserNotSupported": { "message": "Hindi sinusuportahan ang iyong browser..." }, @@ -955,9 +936,6 @@ "message": "Mag-click dito upang ikonekta ang iyong Ledger sa pamamagitan ng WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Maaari ka ring magdagdag ng mga token nang manu-mano." - }, "close": { "message": "Isara" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Hiling na Transaksyon" }, - "confirmationAlertModalDetails": { - "message": "Para protektahan ang iyong mga asset at impormasyon sa pag-login, iminumungkahi namin na tanggihan mo ang kahilingan." - }, "confirmationAlertModalTitle": { "message": "Kahina-hinala ang kahilingang ito" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "Bayad sa gas" }, - "gasIsETH": { - "message": "Ang gas ay $1 " - }, "gasLimit": { "message": "Limitasyon ng gas" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "mga panloloko at panganib sa seguridad." }, - "learnToBridge": { - "message": "Matutong mag-bridge" - }, "leaveMetaMask": { "message": "Umalis sa MetaMask?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Mangyaring kumpletuhin ang transaksyon sa Snap." }, - "loadingTokens": { - "message": "Nilo-load ang Mga Token..." - }, "localhost": { "message": "Localhost 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Hindi active sa kasalukuyan ang mga notipikasyon sa wallet." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "Kasalukuyang minementina ang MetaMask Swaps. Bumalik sa ibang pagkakataon." }, @@ -3048,10 +3011,6 @@ "message": "Ang $1 ay humihiling ng iyong pag-apruba para:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Ang native token sa network na ito ay $1. Ito ang token na ginagamit para sa mga gas fee. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "I-edit ang mga detalye ng network" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "Salamat na lang" }, - "noTransactions": { - "message": "Wala kang transaksyon" - }, "noWebcamFound": { "message": "Hindi nakita ang webcam ng iyong computer. Pakisubukan ulit." }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "I-on ito upang makita ang mga hiling sa pirma sa isang pinahusay na format." }, - "redesignedTransactionsEnabledToggle": { - "message": "Pinahusay na mga hiling sa transaksyon" - }, - "redesignedTransactionsToggleDescription": { - "message": "I-on ito upang makita ang mga hiling sa transaksyon sa isang pinahusay na format." - }, "refreshList": { "message": "I-refresh ang listahan" }, @@ -5941,9 +5891,6 @@ "message": "Ang $1 ay aktibo ngayon sa $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Lumipat ka sa" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Ang paglipat ng network ay magkakansela ng lahat ng nakabinbing kumpirmasyon" }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "Piliin ang mas gusto mong tema ng MetaMask." }, - "thingsToKeep": { - "message": "Mga bagay na dapat tandaan:" - }, "thirdPartySoftware": { "message": "Paunawa ng third-party na software", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "Para kay/sa: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Pinahihintulutan ka nitong pumili ng network para sa bawat site sa halip na iisang piniling network para sa lahat ng site. Pipigilan ka ng feature na ito na magpalit ng network nang mano-mano, na maaaring makasira sa iyong karanasan bilang user sa ilang partikular na site." - }, - "toggleRequestQueueField": { - "message": "Piliin ang mga network para sa bawat site" - }, - "toggleRequestQueueOff": { - "message": "Naka-off" - }, - "toggleRequestQueueOn": { - "message": "Naka-on" - }, "token": { "message": "Token" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "mga panloloko sa token at panganib sa seguridad" }, - "tokenShowUp": { - "message": "Maaaring hindi awtomatikong lumabas ang iyong mga token sa iyong wallet. " - }, "tokenStandard": { "message": "Pamantayan ng token" }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index cf65b516f6eb..914f7b9f92ce 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Ağ Ekleniyor" }, - "addingTokens": { - "message": "Token'leri ekleme" - }, "additionalNetworks": { "message": "İlave ağlar" }, @@ -398,9 +395,6 @@ "alert": { "message": "Uyarı" }, - "alertActionBuy": { - "message": "ETH Al" - }, "alertActionUpdateGas": { "message": "Gaz limitini güncelle" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Bu işlemle devam etmek için gaz limitini 21000 veya üzeri olacak şekilde artırmanız gerekecek." }, - "alertMessageInsufficientBalance2": { - "message": "Hesabınızda ağ ücretlerini ödemek için yeterli ETH yok." - }, "alertMessageNetworkBusy": { "message": "Gaz fiyatları yüksektir ve tahmin daha az kesindir." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Cüzdanınızdaki token'ler otomatik algılansın, NFT'ler gösterilsin ve toplu hesap bakiye güncellemeleri alınsın" }, - "attemptSendingAssets": { - "message": "Varlıklarınızı doğrudan bir ağdan diğerine göndermeye çalışırsanız onları kaybedebilirsiniz. Fonları köprü kullanarak ağlar arasında güvenli bir şekilde transfer edin." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Varlıkları doğrudan bir ağdan diğerine göndermeye çalışırsanız bu durum kalıcı varlık kaybına neden olabilir. $1 gibi bir köprü kullandığınızdan emin olun" - }, "attemptToCancelSwapForFree": { "message": "Swap işlemini ücretsiz iptal etme girişimi" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Hesaplanıyor..." }, - "bridgeDontSend": { - "message": "Köprü yap, gönderme" - }, "bridgeEnterAmount": { "message": "Miktar girin" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "Şuraya köprü:" }, - "browserNotSupported": { "message": "Tarayıcınız desteklenmiyor..." }, @@ -955,9 +936,6 @@ "message": "WebHID üzerinden Ledger'ınızı bağlamak için tıklayın", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Dilediğiniz zaman tokenleri manuel olarak ekleyebilirsiniz." - }, "close": { "message": "Kapat" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "İşlem talebi" }, - "confirmationAlertModalDetails": { - "message": "Varlıklarınızı ve oturum açma bilgilerinizi korumak için talebi reddetmenizi öneririz." - }, "confirmationAlertModalTitle": { "message": "Bu talep şüphelidir" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "Gaz ücreti" }, - "gasIsETH": { - "message": "Gaz $1 " - }, "gasLimit": { "message": "Gaz limiti" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "dolandırıcılıklar ve güvenlik riskleri." }, - "learnToBridge": { - "message": "Köprü yapmayı öğren" - }, "leaveMetaMask": { "message": "MetaMask'ten ayrıl?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Lütfen işlemi Snap üzerinde tamamlayın." }, - "loadingTokens": { - "message": "Tokenler yükleniyor..." - }, "localhost": { "message": "Yerel Ana Bilgisayar 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Cüzdan bildirimleri şu anda aktif değil." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swap İşlemleri bakımda. Lütfen daha sonra tekrar kontrol edin." }, @@ -3048,10 +3011,6 @@ "message": "$1 sizden şunun için onay istiyor:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Bu ağdaki yerli token $1. Bu, gaz ücretleri için kullanılan tokendir. ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Ağ bilgilerini düzenle" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "Hayır, istemiyorum" }, - "noTransactions": { - "message": "İşleminiz yok" - }, "noWebcamFound": { "message": "Bilgisayarınızın web kamerası bulunamadı. Lütfen tekrar deneyin." }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "İmza taleplerini geliştirilmiş bir biçimde görmek için bunu açın." }, - "redesignedTransactionsEnabledToggle": { - "message": "İşlem talepleri iyileştirildi" - }, - "redesignedTransactionsToggleDescription": { - "message": "İşlem taleplerini gelişmiş bir biçimde görmek için bunu açın." - }, "refreshList": { "message": "Listeyi yenile" }, @@ -5941,9 +5891,6 @@ "message": "$1, $2 üzerinde aktif", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Şu anda kullandığınız ağ" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Ağ değiştirmek bekleyen tüm onayları iptal eder" }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "Tercih ettiğin MetaMask temasını seç." }, - "thingsToKeep": { - "message": "Unutulmaması gerekenler:" - }, "thirdPartySoftware": { "message": "Üçüncü taraf yazılım uyarısı", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "Alıcı: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Bu, tüm siteler için tek bir seçili ağ yerine her bir site için bir ağ seçebilmenize olanak sağlar. Bu özellik, manuel olarak ağ değiştirmenizi önleyebilir ve bu da belirli sitelerde kullanıcı deneyiminizi bozabilir." - }, - "toggleRequestQueueField": { - "message": "Her site için ağ seçin" - }, - "toggleRequestQueueOff": { - "message": "Kapalı" - }, - "toggleRequestQueueOn": { - "message": "Açık" - }, "token": { "message": "Token" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "token dolandırıcılıkları ve güvenlik riskleri" }, - "tokenShowUp": { - "message": "Tokenleriniz cüzdanınızda otomatik olarak görünmeyebilir. " - }, "tokenStandard": { "message": "Token standardı" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index b0c011690910..58787e9a2238 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -381,9 +381,6 @@ "loading": { "message": "Завантаження..." }, - "loadingTokens": { - "message": "Завантаження токенів…" - }, "localhost": { "message": "Локальний хост 8545" }, @@ -446,9 +443,6 @@ "noConversionRateAvailable": { "message": "Немає доступного обмінного курсу" }, - "noTransactions": { - "message": "У вас немає транзакцій" - }, "noWebcamFound": { "message": "Веб-камеру комп’ютера не знайдено. Повторіть спробу." }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 024a91858cc2..89d650129b86 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "Thêm mạng" }, - "addingTokens": { - "message": "Đang thêm token" - }, "additionalNetworks": { "message": "Mạng bổ sung" }, @@ -398,9 +395,6 @@ "alert": { "message": "Cảnh báo" }, - "alertActionBuy": { - "message": "Mua ETH" - }, "alertActionUpdateGas": { "message": "Cập nhập hạn mức phí gas" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "Để tiếp tục giao dịch này, bạn cần tăng giới hạn phí gas lên 21000 hoặc cao hơn." }, - "alertMessageInsufficientBalance2": { - "message": "Bạn không có đủ ETH trong tài khoản để thanh toán phí mạng." - }, "alertMessageNetworkBusy": { "message": "Phí gas cao và ước tính kém chính xác hơn." }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "Tự động phát hiện token trong ví của bạn, hiển thị NFT và nhận hàng loạt thông tin cập nhật về số dư tài khoản" }, - "attemptSendingAssets": { - "message": "Bạn có thể bị mất tài sản nếu cố gắng gửi tài sản từ một mạng khác. Chuyển tiền an toàn giữa các mạng bằng cách sử dụng cầu nối." - }, - "attemptSendingAssetsWithPortfolio": { - "message": "Bạn có thể bị mất tài sản nếu cố gắng gửi tài sản từ một mạng khác. Chuyển tiền an toàn giữa các mạng bằng cách sử dụng cầu nối, chẳng hạn như $1" - }, "attemptToCancelSwapForFree": { "message": "Cố gắng hủy hoán đổi miễn phí" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "Đang tính toán..." }, - "bridgeDontSend": { - "message": "Cầu nối, không gửi" - }, "bridgeEnterAmount": { "message": "Nhập số tiền" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "Cầu nối đến" }, - "browserNotSupported": { "message": "Trình duyệt của bạn không được hỗ trợ..." }, @@ -955,9 +936,6 @@ "message": "Nhấp vào đây để kết nối với ví Ledger của bạn qua WebHID", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "Bạn luôn có thể thêm token theo cách thủ công." - }, "close": { "message": "Đóng" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "Yêu cầu giao dịch" }, - "confirmationAlertModalDetails": { - "message": "Để bảo vệ tài sản và thông tin đăng nhập của bạn, chúng tôi đề nghị bạn từ chối yêu cầu này." - }, "confirmationAlertModalTitle": { "message": "Yêu cầu này có dấu hiệu đáng ngờ" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "Phí gas" }, - "gasIsETH": { - "message": "Gas là $1 " - }, "gasLimit": { "message": "Hạn mức phí gas" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "lừa đảo và nguy cơ bảo mật." }, - "learnToBridge": { - "message": "Tìm hiểu cách sử dụng cầu nối" - }, "leaveMetaMask": { "message": "Rời khỏi MetaMask?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "Vui lòng hoàn tất giao dịch trên Snap." }, - "loadingTokens": { - "message": "Đang tải token..." - }, "localhost": { "message": "Máy chủ cục bộ 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "Thông báo ví hiện không hoạt động." }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio." - }, "metamaskSwapsOfflineDescription": { "message": "Tính năng Hoán đổi trên MetaMask đang được bảo trì. Vui lòng kiểm tra lại sau." }, @@ -3048,10 +3011,6 @@ "message": "$1 đang yêu cầu sự chấp thuận của bạn cho:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "Token gốc của mạng này là $1. Token này được dùng làm phí gas.", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "Chỉnh sửa thông tin mạng" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "Không, cảm ơn" }, - "noTransactions": { - "message": "Bạn không có giao dịch nào" - }, "noWebcamFound": { "message": "Không tìm thấy webcam trên máy tính của bạn. Vui lòng thử lại." }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "Bật tính năng này để xem các yêu cầu chữ ký ở định dạng nâng cao." }, - "redesignedTransactionsEnabledToggle": { - "message": "Yêu cầu giao dịch được cải thiện" - }, - "redesignedTransactionsToggleDescription": { - "message": "Bật tính năng này để xem các yêu cầu giao dịch ở định dạng nâng cao." - }, "refreshList": { "message": "Làm mới danh sách" }, @@ -5941,9 +5891,6 @@ "message": "$1 hiện đang hoạt động trên $2", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "Bạn hiện đang sử dụng" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "Khi bạn chuyển mạng, mọi xác nhận đang chờ xử lý sẽ bị hủy" }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "Chọn chủ đề MetaMask yêu thích của bạn." }, - "thingsToKeep": { - "message": "Những điều cần lưu ý:" - }, "thirdPartySoftware": { "message": "Thông báo phần mềm của bên thứ ba", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "Đến: $1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "Tính năng này cho phép bạn chọn mạng cho từng trang web thay vì một mạng duy nhất được chọn cho tất cả các trang web. Tính năng này sẽ ngăn bạn chuyển đổi mạng theo cách thủ công, điều này có thể ảnh hưởng đến trải nghiệm người dùng của bạn trên một số trang web." - }, - "toggleRequestQueueField": { - "message": "Chọn mạng cho từng trang web" - }, - "toggleRequestQueueOff": { - "message": "Tắt" - }, - "toggleRequestQueueOn": { - "message": "Bật" - }, "token": { "message": "Token" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "rủi ro về bảo mật và lừa đảo token" }, - "tokenShowUp": { - "message": "Các token có thể không tự động hiển thị trong ví của bạn. " - }, "tokenStandard": { "message": "Tiêu chuẩn token" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 719d2f102faf..af12318687b2 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -330,9 +330,6 @@ "addingCustomNetwork": { "message": "正在添加网络" }, - "addingTokens": { - "message": "正在添加代币" - }, "additionalNetworks": { "message": "其他网络" }, @@ -398,9 +395,6 @@ "alert": { "message": "提醒" }, - "alertActionBuy": { - "message": "买入 ETH" - }, "alertActionUpdateGas": { "message": "更新燃料限制" }, @@ -428,9 +422,6 @@ "alertMessageGasTooLow": { "message": "要继续此交易,您需要将燃料限制提高到 21000 或更高。" }, - "alertMessageInsufficientBalance2": { - "message": "您的账户中没有足够的 ETH 来支付网络费用。" - }, "alertMessageNetworkBusy": { "message": "燃料价格很高,估算不太准确。" }, @@ -627,12 +618,6 @@ "assetsDescription": { "message": "自动检测钱包中的代币,显示 NFT,并获取批量账户余额更新" }, - "attemptSendingAssets": { - "message": "如果您试图将资产从一个网络直接发送到另一个网络,这可能会导致永久的资产损失。请务必使用跨链桥进行操作。" - }, - "attemptSendingAssetsWithPortfolio": { - "message": "如果您尝试将资产从一个网络发送到另一个网络,这可能会导致资产损失。请务必使用跨链桥在不同网络间安全转移资金,例如 $1" - }, "attemptToCancelSwapForFree": { "message": "尝试免费取消兑换" }, @@ -840,9 +825,6 @@ "bridgeCalculatingAmount": { "message": "正在计算......" }, - "bridgeDontSend": { - "message": "跨链桥,不要发送" - }, "bridgeEnterAmount": { "message": "输入金额" }, @@ -858,7 +840,6 @@ "bridgeTo": { "message": "桥接至" }, - "browserNotSupported": { "message": "您的浏览器不受支持……" }, @@ -955,9 +936,6 @@ "message": "点击这里以通过 WebHID 连接您的 Ledger", "description": "Text that can be clicked to open a browser popup for connecting the ledger device via webhid" }, - "clickToManuallyAdd": { - "message": "请点击这里,以手动添加代币。" - }, "close": { "message": "关闭" }, @@ -1061,9 +1039,6 @@ "confirmTitleTransaction": { "message": "交易请求" }, - "confirmationAlertModalDetails": { - "message": "为了保护您的资产和登录信息,我们建议您拒绝该请求。" - }, "confirmationAlertModalTitle": { "message": "此请求可疑" }, @@ -2139,9 +2114,6 @@ "gasFee": { "message": "燃料费" }, - "gasIsETH": { - "message": "燃料是 $1 " - }, "gasLimit": { "message": "燃料限制" }, @@ -2703,9 +2675,6 @@ "learnScamRisk": { "message": "欺诈和安全风险信息。" }, - "learnToBridge": { - "message": "了解跨链桥" - }, "leaveMetaMask": { "message": "要离开 MetaMask?" }, @@ -2797,9 +2766,6 @@ "loadingScreenSnapMessage": { "message": "请在Snap上完成交易。" }, - "loadingTokens": { - "message": "加载代币中……" - }, "localhost": { "message": "Localhost 8545" }, @@ -2901,9 +2867,6 @@ "metamaskNotificationsAreOff": { "message": "钱包通知目前未开启。" }, - "metamaskPortfolio": { - "message": "MetaMask Portfolio。" - }, "metamaskSwapsOfflineDescription": { "message": "MetaMask Swaps 正在进行维护。请稍后再查看。" }, @@ -3048,10 +3011,6 @@ "message": "$1 请求您的批准,以便:", "description": "$1 represents dapp name" }, - "nativeToken": { - "message": "此网络上的原生代币为 $1。它是用于燃料费的代币。 ", - "description": "$1 represents the name of the native token on the current network" - }, "nativeTokenScamWarningConversion": { "message": "编辑网络详情" }, @@ -3336,9 +3295,6 @@ "noThanks": { "message": "不,谢谢" }, - "noTransactions": { - "message": "您没有任何交易" - }, "noWebcamFound": { "message": "未找到您电脑的网络摄像头。请重试。" }, @@ -4351,12 +4307,6 @@ "redesignedConfirmationsToggleDescription": { "message": "开启此选项以查看增强格式的签名请求。" }, - "redesignedTransactionsEnabledToggle": { - "message": "经过改进的交易请求" - }, - "redesignedTransactionsToggleDescription": { - "message": "开启此选项以查看增强格式的交易请求。" - }, "refreshList": { "message": "刷新列表" }, @@ -5941,9 +5891,6 @@ "message": "$1 现已在 $2 上激活", "description": "$1 represents the account name, $2 represents the network name" }, - "switchedTo": { - "message": "您现在使用的是" - }, "switchingNetworksCancelsPendingConfirmations": { "message": "切换网络将取消所有待处理的确认" }, @@ -5980,9 +5927,6 @@ "themeDescription": { "message": "选择您喜欢的MetaMask主题。" }, - "thingsToKeep": { - "message": "注意事项:" - }, "thirdPartySoftware": { "message": "第三方软件通告", "description": "Title of a popup modal displayed when installing a snap for the first time." @@ -6013,18 +5957,6 @@ "message": "至:$1", "description": "$1 is the address to include in the To label. It is typically shortened first using shortenAddress" }, - "toggleRequestQueueDescription": { - "message": "这使您可以为每个网站选择网络,而不是为所有网站选择同一个网络。此功能将阻止您手动切换网络,这可能会破坏您在某些网站上的用户体验。" - }, - "toggleRequestQueueField": { - "message": "为每个网站选择网络" - }, - "toggleRequestQueueOff": { - "message": "关" - }, - "toggleRequestQueueOn": { - "message": "开" - }, "token": { "message": "代币" }, @@ -6064,9 +5996,6 @@ "tokenScamSecurityRisk": { "message": "代币欺诈和安全风险。" }, - "tokenShowUp": { - "message": "您的代币可能不会自动显示在您的钱包中。" - }, "tokenStandard": { "message": "代币标准" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index ed1793427a90..7b4a425a03ad 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -699,9 +699,6 @@ "loading": { "message": "載入..." }, - "loadingTokens": { - "message": "載入代幣..." - }, "lock": { "message": "鎖定" }, @@ -815,9 +812,6 @@ "noConversionRateAvailable": { "message": "尚未有匯率比較值" }, - "noTransactions": { - "message": "尚未有交易" - }, "noWebcamFound": { "message": "無法搜尋到攝影鏡頭裝置。請再試一次" }, diff --git a/app/images/bitcoin-logo.svg b/app/images/bitcoin-logo.svg index 4306787921c7..7b0c116bbf12 100644 --- a/app/images/bitcoin-logo.svg +++ b/app/images/bitcoin-logo.svg @@ -1,14 +1,5 @@ - - - - - - - - - - - - - + + + + diff --git a/app/images/info-fox.svg b/app/images/info-fox.svg deleted file mode 100644 index 57660c1fe6bc..000000000000 --- a/app/images/info-fox.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/images/ink-sepolia.svg b/app/images/ink-sepolia.svg new file mode 100644 index 000000000000..7e6dfe3ca85d --- /dev/null +++ b/app/images/ink-sepolia.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/images/ink.svg b/app/images/ink.svg new file mode 100644 index 000000000000..a42ada4be3dc --- /dev/null +++ b/app/images/ink.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/images/kaia.svg b/app/images/kaia.svg new file mode 100644 index 000000000000..88a10cd86e68 --- /dev/null +++ b/app/images/kaia.svg @@ -0,0 +1,9 @@ + + image + + + + + + diff --git a/app/images/klaytn.svg b/app/images/klaytn.svg deleted file mode 100644 index 4eb1ff5f107b..000000000000 --- a/app/images/klaytn.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/images/lisk.svg b/app/images/lisk.svg new file mode 100644 index 000000000000..3f90844a8b5f --- /dev/null +++ b/app/images/lisk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/images/lisk_sepolia.svg b/app/images/lisk_sepolia.svg new file mode 100644 index 000000000000..e38de3c9c07a --- /dev/null +++ b/app/images/lisk_sepolia.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/images/no-nfts.svg b/app/images/no-nfts.svg index 220eb4790d75..6b3197e9a3e1 100644 --- a/app/images/no-nfts.svg +++ b/app/images/no-nfts.svg @@ -1,10 +1,51 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/images/soneium.svg b/app/images/soneium.svg new file mode 100644 index 000000000000..f045afaef99a --- /dev/null +++ b/app/images/soneium.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/scripts/background.js b/app/scripts/background.js index c6a3bccd46aa..029adf026841 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1153,10 +1153,8 @@ export function setupController( controller.appStateController.waitingForUnlock.length + controller.approvalController.getTotalApprovalCount(); - if (controller.preferencesController.getUseRequestQueue()) { - pendingApprovalCount += - controller.queuedRequestController.state.queuedRequestCount; - } + pendingApprovalCount += + controller.queuedRequestController.state.queuedRequestCount; return pendingApprovalCount; } catch (error) { console.error('Failed to get pending approval count:', error); diff --git a/app/scripts/constants/sentry-state.ts b/app/scripts/constants/sentry-state.ts index ab53ffb3f22d..91fb10f4efc7 100644 --- a/app/scripts/constants/sentry-state.ts +++ b/app/scripts/constants/sentry-state.ts @@ -42,6 +42,11 @@ export const SENTRY_BACKGROUND_STATE = { }, AuthenticationController: { isSignedIn: false, + sessionData: { + profile: true, + accessToken: false, + expiresIn: true, + }, }, NetworkOrderController: { orderedNetworkList: [], @@ -244,7 +249,6 @@ export const SENTRY_BACKGROUND_STATE = { autoLockTimeLimit: true, hideZeroBalanceTokens: true, redesignedConfirmationsEnabled: true, - redesignedTransactionsEnabled: false, isRedesignedConfirmationsDeveloperEnabled: false, showExtensionInFullSizeView: true, showFiatInTestnets: true, @@ -270,7 +274,6 @@ export const SENTRY_BACKGROUND_STATE = { useNonceField: true, usePhishDetect: true, useTokenDetection: true, - useRequestQueue: true, useTransactionSimulations: true, enableMV3TimestampSave: true, }, @@ -422,11 +425,7 @@ const flattenedBackgroundStateMask = Object.values( export const SENTRY_UI_STATE = { gas: true, history: true, - metamask: { - ...flattenedBackgroundStateMask, - // This property comes from the background but isn't in controller state - isInitialized: true, - // These properties are in the `metamask` slice but not in the background state + appState: { customNonceValue: true, isAccountMenuOpen: true, isNetworkMenuOpen: true, @@ -435,6 +434,11 @@ export const SENTRY_UI_STATE = { welcomeScreenSeen: true, slides: false, confirmationExchangeRates: true, + }, + metamask: { + ...flattenedBackgroundStateMask, + // This property comes from the background but isn't in controller state + isInitialized: true, useSafeChainsListValidation: true, watchEthereumAccountEnabled: false, bitcoinSupportEnabled: false, diff --git a/app/scripts/controllers/account-tracker-controller.test.ts b/app/scripts/controllers/account-tracker-controller.test.ts index 7456244fc5a4..d9090c2e67f8 100644 --- a/app/scripts/controllers/account-tracker-controller.test.ts +++ b/app/scripts/controllers/account-tracker-controller.test.ts @@ -1,6 +1,6 @@ import EventEmitter from 'events'; import { ControllerMessenger } from '@metamask/base-controller'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { BlockTracker, Provider } from '@metamask/network-controller'; import { flushPromises } from '../../../test/lib/timer-helpers'; diff --git a/app/scripts/controllers/account-tracker-controller.ts b/app/scripts/controllers/account-tracker-controller.ts index 5f509a1901bf..54d55d3d0bff 100644 --- a/app/scripts/controllers/account-tracker-controller.ts +++ b/app/scripts/controllers/account-tracker-controller.ts @@ -7,11 +7,9 @@ * on each new block. */ -import EthQuery from '@metamask/eth-query'; import { v4 as random } from 'uuid'; import log from 'loglevel'; -import pify from 'pify'; import { Web3Provider } from '@ethersproject/providers'; import { Contract } from '@ethersproject/contracts'; import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi'; @@ -24,7 +22,7 @@ import { NetworkControllerGetStateAction, Provider, } from '@metamask/network-controller'; -import { hasProperty, Hex } from '@metamask/utils'; +import { hasProperty, type Hex, type JsonRpcParams } from '@metamask/utils'; import { BaseController, ControllerGetStateAction, @@ -36,7 +34,7 @@ import { AccountsControllerSelectedEvmAccountChangeEvent, } from '@metamask/accounts-controller'; import { KeyringControllerAccountRemovedEvent } from '@metamask/keyring-controller'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { LOCALHOST_RPC_URL } from '../../../shared/constants/network'; import { SINGLE_CALL_BALANCES_ADDRESSES } from '../constants/contracts'; @@ -481,7 +479,7 @@ export default class AccountTrackerController extends BaseController< * AccountTrackerController. * * Once this AccountTrackerController accounts are up to date with those referenced by the passed addresses, each - * of these accounts are given an updated balance via EthQuery. + * of these accounts are given an updated balance via Provider. * * @param addresses - The array of hex addresses for accounts with which this AccountTrackerController accounts should be * in sync @@ -588,7 +586,7 @@ export default class AccountTrackerController extends BaseController< /** * Given a block, updates this AccountTrackerController currentBlockGasLimit and currentBlockGasLimitByChainId and then updates - * each local account's balance via EthQuery + * each local account's balance via Provider * * @private * @param blockNumber - the block number to update to. @@ -600,7 +598,7 @@ export default class AccountTrackerController extends BaseController< /** * Given a block, updates this AccountTrackerController currentBlockGasLimitByChainId, and then updates each local account's balance - * via EthQuery + * via Provider * * @private * @param networkClientId - optional network client ID to use instead of the globally selected network. @@ -616,10 +614,13 @@ export default class AccountTrackerController extends BaseController< this.#currentBlockNumberByChainId[chainId] = blockNumber; // block gasLimit polling shouldn't be in account-tracker shouldn't be here... - const currentBlock = await pify(new EthQuery(provider)).getBlockByNumber( - blockNumber, - false, - ); + const currentBlock = await provider.request< + JsonRpcParams, + { gasLimit: string } + >({ + method: 'eth_getBlockByNumber', + params: [blockNumber, false], + }); if (!currentBlock) { return; } @@ -729,7 +730,10 @@ export default class AccountTrackerController extends BaseController< // query balance try { - balance = await pify(new EthQuery(provider)).getBalance(address); + balance = await provider.request({ + method: 'eth_getBalance', + params: [address, 'latest'], + }); } catch (error) { if ( error && diff --git a/app/scripts/controllers/bridge-status/mocks.ts b/app/scripts/controllers/bridge-status/mocks.ts index 1507af5830ec..0292fc7ecf9a 100644 --- a/app/scripts/controllers/bridge-status/mocks.ts +++ b/app/scripts/controllers/bridge-status/mocks.ts @@ -236,7 +236,7 @@ export const getMockStartPollingForBridgeTxStatusArgs = ({ }, approval: null, estimatedProcessingTimeInSeconds: 15, - sentAmount: { amount: '1.234', fiat: null }, + sentAmount: { amount: '1.234', valueInCurrency: null }, }, startTime: 1729964825189, slippagePercentage: 0, diff --git a/app/scripts/controllers/bridge-status/utils.ts b/app/scripts/controllers/bridge-status/utils.ts index d8dbac9e1590..5447b483e34f 100644 --- a/app/scripts/controllers/bridge-status/utils.ts +++ b/app/scripts/controllers/bridge-status/utils.ts @@ -8,9 +8,7 @@ import { StatusRequestWithSrcTxHash, StatusRequestDto, } from '../../../../shared/types/bridge-status'; -// TODO fix this -// eslint-disable-next-line import/no-restricted-paths -import { Quote } from '../../../../ui/pages/bridge/types'; +import type { Quote } from '../../../../shared/types/bridge'; import { validateResponse, validators } from './validators'; const CLIENT_ID_HEADER = { 'X-Client-Id': BRIDGE_CLIENT_ID }; diff --git a/app/scripts/controllers/bridge/bridge-controller.test.ts b/app/scripts/controllers/bridge/bridge-controller.test.ts index 3b0d095fa0c3..e35d3c41e67c 100644 --- a/app/scripts/controllers/bridge/bridge-controller.test.ts +++ b/app/scripts/controllers/bridge/bridge-controller.test.ts @@ -5,20 +5,19 @@ import { BRIDGE_API_BASE_URL } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { SWAPS_API_V2_BASE_URL } from '../../../../shared/constants/swaps'; import { flushPromises } from '../../../../test/lib/timer-helpers'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import * as bridgeUtil from '../../../../ui/pages/bridge/bridge.util'; +import * as bridgeUtil from '../../../../shared/modules/bridge-utils/bridge.util'; import * as balanceUtils from '../../../../shared/modules/bridge-utils/balance'; import mockBridgeQuotesErc20Native from '../../../../test/data/bridge/mock-quotes-erc20-native.json'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; import mockBridgeQuotesNativeErc20Eth from '../../../../test/data/bridge/mock-quotes-native-erc20-eth.json'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { QuoteResponse } from '../../../../ui/pages/bridge/types'; +import { + type QuoteResponse, + RequestStatus, +} from '../../../../shared/types/bridge'; import { decimalToHex } from '../../../../shared/modules/conversion.utils'; import BridgeController from './bridge-controller'; import { BridgeControllerMessenger } from './types'; -import { DEFAULT_BRIDGE_CONTROLLER_STATE, RequestStatus } from './constants'; +import { DEFAULT_BRIDGE_CONTROLLER_STATE } from './constants'; const EMPTY_INIT_STATE = { bridgeState: DEFAULT_BRIDGE_CONTROLLER_STATE, diff --git a/app/scripts/controllers/bridge/bridge-controller.ts b/app/scripts/controllers/bridge/bridge-controller.ts index 4770c342587c..005e2d334e9f 100644 --- a/app/scripts/controllers/bridge/bridge-controller.ts +++ b/app/scripts/controllers/bridge/bridge-controller.ts @@ -12,9 +12,7 @@ import { fetchBridgeFeatureFlags, fetchBridgeQuotes, fetchBridgeTokens, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/bridge.util'; +} from '../../../../shared/modules/bridge-utils/bridge.util'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths import { fetchTopAssetsList } from '../../../../ui/pages/swaps/swaps.util'; @@ -23,30 +21,24 @@ import { sumHexes, } from '../../../../shared/modules/conversion.utils'; import { - L1GasFees, - QuoteRequest, - QuoteResponse, - TxData, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/types'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { isValidQuoteRequest } from '../../../../ui/pages/bridge/utils/quote'; + type L1GasFees, + type QuoteRequest, + type QuoteResponse, + type TxData, + type BridgeControllerState, + BridgeFeatureFlagsKey, + RequestStatus, +} from '../../../../shared/types/bridge'; +import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote'; import { hasSufficientBalance } from '../../../../shared/modules/bridge-utils/balance'; import { CHAIN_IDS } from '../../../../shared/constants/network'; +import { REFRESH_INTERVAL_MS } from '../../../../shared/constants/bridge'; import { BRIDGE_CONTROLLER_NAME, DEFAULT_BRIDGE_CONTROLLER_STATE, - REFRESH_INTERVAL_MS, - RequestStatus, METABRIDGE_CHAIN_TO_ADDRESS_MAP, } from './constants'; -import { - BridgeControllerState, - BridgeControllerMessenger, - BridgeFeatureFlagsKey, -} from './types'; +import type { BridgeControllerMessenger } from './types'; const metadata: StateMetadata<{ bridgeState: BridgeControllerState }> = { bridgeState: { diff --git a/app/scripts/controllers/bridge/constants.ts b/app/scripts/controllers/bridge/constants.ts index 4903a9ee2858..65e2840cfb73 100644 --- a/app/scripts/controllers/bridge/constants.ts +++ b/app/scripts/controllers/bridge/constants.ts @@ -2,21 +2,15 @@ import { zeroAddress } from 'ethereumjs-util'; import { Hex } from '@metamask/utils'; import { BRIDGE_DEFAULT_SLIPPAGE, + DEFAULT_MAX_REFRESH_COUNT, METABRIDGE_ETHEREUM_ADDRESS, + REFRESH_INTERVAL_MS, } from '../../../../shared/constants/bridge'; import { CHAIN_IDS } from '../../../../shared/constants/network'; -import { BridgeControllerState, BridgeFeatureFlagsKey } from './types'; +import { BridgeFeatureFlagsKey } from '../../../../shared/types/bridge'; +import type { BridgeControllerState } from '../../../../shared/types/bridge'; export const BRIDGE_CONTROLLER_NAME = 'BridgeController'; -export const REFRESH_INTERVAL_MS = 30 * 1000; -const DEFAULT_MAX_REFRESH_COUNT = 5; - -export enum RequestStatus { - LOADING, - FETCHED, - ERROR, -} - export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = { bridgeFeatureFlags: { [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { diff --git a/app/scripts/controllers/bridge/types.ts b/app/scripts/controllers/bridge/types.ts index 7cdfa43cabd0..811b8dfb119b 100644 --- a/app/scripts/controllers/bridge/types.ts +++ b/app/scripts/controllers/bridge/types.ts @@ -2,64 +2,18 @@ import { ControllerStateChangeEvent, RestrictedControllerMessenger, } from '@metamask/base-controller'; -import { Hex } from '@metamask/utils'; import { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller'; import { NetworkControllerFindNetworkClientIdByChainIdAction, NetworkControllerGetSelectedNetworkClientAction, } from '@metamask/network-controller'; -import { SwapsTokenObject } from '../../../../shared/constants/swaps'; -import { - L1GasFees, - QuoteRequest, - QuoteResponse, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../../ui/pages/bridge/types'; -import { ChainConfiguration } from '../../../../shared/types/bridge'; +import type { + BridgeBackgroundAction, + BridgeControllerState, + BridgeUserAction, +} from '../../../../shared/types/bridge'; import BridgeController from './bridge-controller'; -import { BRIDGE_CONTROLLER_NAME, RequestStatus } from './constants'; - -export enum BridgeFeatureFlagsKey { - EXTENSION_CONFIG = 'extensionConfig', -} - -export type BridgeFeatureFlags = { - [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { - refreshRate: number; - maxRefreshCount: number; - support: boolean; - chains: Record; - }; -}; - -export type BridgeControllerState = { - bridgeFeatureFlags: BridgeFeatureFlags; - srcTokens: Record; - srcTopAssets: { address: string }[]; - srcTokensLoadingStatus?: RequestStatus; - destTokensLoadingStatus?: RequestStatus; - destTokens: Record; - destTopAssets: { address: string }[]; - quoteRequest: Partial; - quotes: (QuoteResponse & L1GasFees)[]; - quotesInitialLoadTime?: number; - quotesLastFetched?: number; - quotesLoadingStatus?: RequestStatus; - quoteFetchError?: string; - quotesRefreshCount: number; -}; - -export enum BridgeUserAction { - SELECT_SRC_NETWORK = 'selectSrcNetwork', - SELECT_DEST_NETWORK = 'selectDestNetwork', - UPDATE_QUOTE_PARAMS = 'updateBridgeQuoteRequestParams', -} -export enum BridgeBackgroundAction { - SET_FEATURE_FLAGS = 'setBridgeFeatureFlags', - RESET_STATE = 'resetState', - GET_BRIDGE_ERC20_ALLOWANCE = 'getBridgeERC20Allowance', -} +import { BRIDGE_CONTROLLER_NAME } from './constants'; type BridgeControllerAction = { type: `${typeof BRIDGE_CONTROLLER_NAME}:${FunctionName}`; diff --git a/app/scripts/controllers/metametrics-controller.test.ts b/app/scripts/controllers/metametrics-controller.test.ts index bee3c3c323d2..939d8e506070 100644 --- a/app/scripts/controllers/metametrics-controller.test.ts +++ b/app/scripts/controllers/metametrics-controller.test.ts @@ -10,7 +10,7 @@ import { Token, TokensControllerState, } from '@metamask/assets-controllers'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { Browser } from 'webextension-polyfill'; import { ControllerMessenger } from '@metamask/base-controller'; import { merge } from 'lodash'; diff --git a/app/scripts/controllers/mmi-controller.ts b/app/scripts/controllers/mmi-controller.ts index f94388aa5e8f..7378585a7e8f 100644 --- a/app/scripts/controllers/mmi-controller.ts +++ b/app/scripts/controllers/mmi-controller.ts @@ -27,8 +27,8 @@ import { OriginalRequest, SignatureController, } from '@metamask/signature-controller'; -import { InternalAccount } from '@metamask/keyring-api'; import { toHex } from '@metamask/controller-utils'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths diff --git a/app/scripts/controllers/permissions/specifications.js b/app/scripts/controllers/permissions/specifications.js index b0b2051b10f5..c56b8f06e9f0 100644 --- a/app/scripts/controllers/permissions/specifications.js +++ b/app/scripts/controllers/permissions/specifications.js @@ -47,7 +47,7 @@ export const CaveatFactories = Object.freeze({ * PermissionController. * * @param {{ - * getInternalAccounts: () => Record, + * getInternalAccounts: () => Record, * }} options - Options bag. */ export const getCaveatSpecifications = ({ @@ -96,7 +96,7 @@ export const getCaveatSpecifications = ({ * * @param {{ * getAllAccounts: () => Promise, - * getInternalAccounts: () => Record, + * getInternalAccounts: () => Record, * }} options - Options bag. * @param options.getAllAccounts - A function that returns all Ethereum accounts * in the current MetaMask instance. @@ -254,7 +254,7 @@ export const getPermissionSpecifications = ({ * corresponds to a PreferencesController identity. * * @param {string[]} accounts - The accounts associated with the caveat. - * @param {() => Record} getInternalAccounts - + * @param {() => Record} getInternalAccounts - * Gets all AccountsController InternalAccounts. */ function validateCaveatAccounts(accounts, getInternalAccounts) { @@ -408,13 +408,19 @@ export const unrestrictedMethods = Object.freeze([ 'wallet_invokeSnap', 'wallet_invokeKeyring', 'snap_getClientStatus', + 'snap_getCurrencyRate', + 'snap_clearState', 'snap_getFile', + 'snap_getState', 'snap_createInterface', 'snap_updateInterface', 'snap_getInterfaceState', 'snap_getInterfaceContext', 'snap_resolveInterface', - 'snap_getCurrencyRate', + 'snap_setState', + 'snap_scheduleBackgroundEvent', + 'snap_cancelBackgroundEvent', + 'snap_getBackgroundEvents', ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) 'metamaskinstitutional_authenticate', 'metamaskinstitutional_reauthenticate', diff --git a/app/scripts/controllers/preferences-controller.test.ts b/app/scripts/controllers/preferences-controller.test.ts index 39a2d49648b2..a9049bec7758 100644 --- a/app/scripts/controllers/preferences-controller.test.ts +++ b/app/scripts/controllers/preferences-controller.test.ts @@ -640,19 +640,6 @@ describe('preferences controller', () => { }); }); - describe('useRequestQueue', () => { - it('defaults useRequestQueue to true', () => { - const { controller } = setupController({}); - expect(controller.state.useRequestQueue).toStrictEqual(true); - }); - - it('setUseRequestQueue to false', () => { - const { controller } = setupController({}); - controller.setUseRequestQueue(false); - expect(controller.state.useRequestQueue).toStrictEqual(false); - }); - }); - describe('addSnapAccountEnabled', () => { it('defaults addSnapAccountEnabled to false', () => { const { controller } = setupController({}); @@ -733,12 +720,12 @@ describe('preferences controller', () => { privacyMode: false, showFiatInTestnets: false, showTestNetworks: false, + smartTransactionsMigrationApplied: false, smartTransactionsOptInStatus: true, useNativeCurrencyAsPrimaryCurrency: true, hideZeroBalanceTokens: false, petnamesEnabled: true, redesignedConfirmationsEnabled: true, - redesignedTransactionsEnabled: true, shouldShowAggregatedBalancePopover: true, featureNotificationsEnabled: false, isRedesignedConfirmationsDeveloperEnabled: false, @@ -762,13 +749,13 @@ describe('preferences controller', () => { showExtensionInFullSizeView: false, showFiatInTestnets: false, showTestNetworks: false, + smartTransactionsMigrationApplied: false, smartTransactionsOptInStatus: true, useNativeCurrencyAsPrimaryCurrency: true, hideZeroBalanceTokens: false, petnamesEnabled: true, privacyMode: false, redesignedConfirmationsEnabled: true, - redesignedTransactionsEnabled: true, shouldShowAggregatedBalancePopover: true, featureNotificationsEnabled: false, isRedesignedConfirmationsDeveloperEnabled: false, diff --git a/app/scripts/controllers/preferences-controller.ts b/app/scripts/controllers/preferences-controller.ts index d705be4c3180..447d9ec0847f 100644 --- a/app/scripts/controllers/preferences-controller.ts +++ b/app/scripts/controllers/preferences-controller.ts @@ -104,12 +104,12 @@ export type Preferences = { showFiatInTestnets: boolean; showTestNetworks: boolean; smartTransactionsOptInStatus: boolean; + smartTransactionsMigrationApplied: boolean; showNativeTokenAsMainBalance: boolean; useNativeCurrencyAsPrimaryCurrency: boolean; hideZeroBalanceTokens: boolean; petnamesEnabled: boolean; redesignedConfirmationsEnabled: boolean; - redesignedTransactionsEnabled: boolean; featureNotificationsEnabled: boolean; showMultiRpcModal: boolean; privacyMode: boolean; @@ -129,6 +129,7 @@ export type PreferencesControllerState = Omit< PreferencesState, | 'showTestNetworks' | 'smartTransactionsOptInStatus' + | 'smartTransactionsMigrationApplied' | 'privacyMode' | 'tokenSortConfig' | 'useMultiRpcMigration' @@ -141,7 +142,6 @@ export type PreferencesControllerState = Omit< useMultiAccountBalanceChecker: boolean; use4ByteResolution: boolean; useCurrencyRateCheck: boolean; - useRequestQueue: boolean; ///: BEGIN:ONLY_INCLUDE_IF(build-flask) watchEthereumAccountEnabled: boolean; ///: END:ONLY_INCLUDE_IF @@ -188,7 +188,6 @@ export const getDefaultPreferencesControllerState = useNftDetection: true, use4ByteResolution: true, useCurrencyRateCheck: true, - useRequestQueue: true, openSeaEnabled: true, securityAlertsEnabled: true, watchEthereumAccountEnabled: false, @@ -217,12 +216,12 @@ export const getDefaultPreferencesControllerState = showFiatInTestnets: false, showTestNetworks: false, smartTransactionsOptInStatus: true, + smartTransactionsMigrationApplied: false, showNativeTokenAsMainBalance: false, useNativeCurrencyAsPrimaryCurrency: true, hideZeroBalanceTokens: false, petnamesEnabled: true, redesignedConfirmationsEnabled: true, - redesignedTransactionsEnabled: true, featureNotificationsEnabled: false, isRedesignedConfirmationsDeveloperEnabled: false, showConfirmationAdvancedDetails: false, @@ -339,10 +338,6 @@ const controllerMetadata = { persist: true, anonymous: true, }, - useRequestQueue: { - persist: true, - anonymous: true, - }, openSeaEnabled: { persist: true, anonymous: true, @@ -406,6 +401,16 @@ const controllerMetadata = { preferences: { persist: true, anonymous: true, + properties: { + smartTransactionsOptInStatus: { + persist: true, + anonymous: true, + }, + smartTransactionsMigrationApplied: { + persist: true, + anonymous: true, + }, + }, }, ipfsGateway: { persist: true, @@ -629,17 +634,6 @@ export class PreferencesController extends BaseController< }); } - /** - * Setter for the `useRequestQueue` property - * - * @param val - Whether or not the user wants to have requests queued if network change is required. - */ - setUseRequestQueue(val: boolean): void { - this.update((state) => { - state.useRequestQueue = val; - }); - } - /** * Setter for the `openSeaEnabled` property * @@ -852,15 +846,6 @@ export class PreferencesController extends BaseController< return selectedAccount.address; } - /** - * Getter for the `useRequestQueue` property - * - * @returns whether this option is on or off. - */ - getUseRequestQueue(): boolean { - return this.state.useRequestQueue; - } - /** * Sets a custom label for an account * diff --git a/app/scripts/fixtures/with-preferences.js b/app/scripts/fixtures/with-preferences.js index c3a482ef8f94..8d1845f728bb 100644 --- a/app/scripts/fixtures/with-preferences.js +++ b/app/scripts/fixtures/with-preferences.js @@ -31,7 +31,6 @@ export const FIXTURES_PREFERENCES = { useTokenDetection: true, useCurrencyRateCheck: true, useMultiAccountBalanceChecker: true, - useRequestQueue: true, theme: 'light', useExternalNameSources: true, useTransactionSimulations: true, diff --git a/app/scripts/lib/AccountIdentitiesPetnamesBridge.ts b/app/scripts/lib/AccountIdentitiesPetnamesBridge.ts index 87f4d114eabb..dac123744772 100644 --- a/app/scripts/lib/AccountIdentitiesPetnamesBridge.ts +++ b/app/scripts/lib/AccountIdentitiesPetnamesBridge.ts @@ -4,7 +4,7 @@ import { NameType, NameOrigin, } from '@metamask/name-controller'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { AccountsControllerChangeEvent, AccountsControllerListAccountsAction, diff --git a/app/scripts/lib/accounts/BalancesController.test.ts b/app/scripts/lib/accounts/BalancesController.test.ts index 982df0289fea..3dec8c565c73 100644 --- a/app/scripts/lib/accounts/BalancesController.test.ts +++ b/app/scripts/lib/accounts/BalancesController.test.ts @@ -1,10 +1,7 @@ import { ControllerMessenger } from '@metamask/base-controller'; -import { - Balance, - BtcAccountType, - CaipAssetType, - InternalAccount, -} from '@metamask/keyring-api'; +import { Balance, BtcAccountType, CaipAssetType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; +import { KeyringTypes } from '@metamask/keyring-controller'; import { createMockInternalAccount } from '../../../../test/jest/mocks'; import { MultichainNetworks } from '../../../../shared/constants/multichain/networks'; import { @@ -29,6 +26,7 @@ const mockBtcAccount = createMockInternalAccount({ options: { scope: MultichainNetworks.BITCOIN_TESTNET, }, + keyringType: KeyringTypes.snap, }); const mockBalanceResult = { diff --git a/app/scripts/lib/accounts/BalancesController.ts b/app/scripts/lib/accounts/BalancesController.ts index 588053d6ea2a..4b9616fac35f 100644 --- a/app/scripts/lib/accounts/BalancesController.ts +++ b/app/scripts/lib/accounts/BalancesController.ts @@ -8,13 +8,13 @@ import { } from '@metamask/base-controller'; import { BtcAccountType, - KeyringClient, + SolAccountType, + isEvmAccountType, type Balance, type CaipAssetType, - type InternalAccount, - isEvmAccountType, - SolAccountType, } from '@metamask/keyring-api'; +import { type InternalAccount } from '@metamask/keyring-internal-api'; +import { KeyringClient } from '@metamask/keyring-snap-client'; import type { HandleSnapRequest } from '@metamask/snaps-controllers'; import type { SnapId } from '@metamask/snaps-sdk'; import { HandlerType } from '@metamask/snaps-utils'; diff --git a/app/scripts/lib/backup.test.js b/app/scripts/lib/backup.test.js index 826aa04018d9..242b9174add4 100644 --- a/app/scripts/lib/backup.test.js +++ b/app/scripts/lib/backup.test.js @@ -175,7 +175,6 @@ const jsonData = JSON.stringify({ theme: 'light', customNetworkListEnabled: false, textDirection: 'auto', - useRequestQueue: true, }, internalAccounts: { accounts: { diff --git a/app/scripts/lib/ens-ipfs/resolver.js b/app/scripts/lib/ens-ipfs/resolver.js index ecdab8c05596..575cbd999ff6 100644 --- a/app/scripts/lib/ens-ipfs/resolver.js +++ b/app/scripts/lib/ens-ipfs/resolver.js @@ -1,35 +1,49 @@ import namehash from 'eth-ens-namehash'; -import Eth from '@metamask/ethjs-query'; -import EthContract from '@metamask/ethjs-contract'; import contentHash from '@ensdomains/content-hash'; +import { Web3Provider } from '@ethersproject/providers'; +import { Contract } from '@ethersproject/contracts'; import registryAbi from './contracts/registry'; import resolverAbi from './contracts/resolver'; export default async function resolveEnsToIpfsContentId({ provider, name }) { - const eth = new Eth(provider); const hash = namehash.hash(name); - const contract = new EthContract(eth); + // lookup registry - const chainId = Number.parseInt(await eth.net_version(), 10); + const chainId = Number.parseInt( + await provider.request({ method: 'net_version' }), + 10, + ); const registryAddress = getRegistryForChainId(chainId); if (!registryAddress) { throw new Error( `EnsIpfsResolver - no known ens-ipfs registry for chainId "${chainId}"`, ); } - const Registry = contract(registryAbi).at(registryAddress); + const web3Provider = new Web3Provider(provider); + const registryContract = new Contract( + registryAddress, + registryAbi, + web3Provider, + ); // lookup resolver - const resolverLookupResult = await Registry.resolver(hash); - const resolverAddress = resolverLookupResult[0]; + const resolverAddress = await registryContract.resolver(hash); if (hexValueIsEmpty(resolverAddress)) { throw new Error(`EnsIpfsResolver - no resolver found for name "${name}"`); } - const Resolver = contract(resolverAbi).at(resolverAddress); + const resolverContract = new Contract( + resolverAddress, + resolverAbi, + web3Provider, + ); - const isEIP1577Compliant = await Resolver.supportsInterface('0xbc1c58d1'); - const isLegacyResolver = await Resolver.supportsInterface('0xd8389dc5'); - if (isEIP1577Compliant[0]) { - const contentLookupResult = await Resolver.contenthash(hash); + const isEIP1577Compliant = await resolverContract.supportsInterface( + '0xbc1c58d1', + ); + const isLegacyResolver = await resolverContract.supportsInterface( + '0xd8389dc5', + ); + if (isEIP1577Compliant) { + const contentLookupResult = await resolverContract.contenthash(hash); const rawContentHash = contentLookupResult[0]; let decodedContentHash = contentHash.decode(rawContentHash); const type = contentHash.getCodec(rawContentHash); @@ -41,9 +55,9 @@ export default async function resolveEnsToIpfsContentId({ provider, name }) { return { type, hash: decodedContentHash }; } - if (isLegacyResolver[0]) { + if (isLegacyResolver) { // lookup content id - const contentLookupResult = await Resolver.content(hash); + const contentLookupResult = await resolverContract.content(hash); const content = contentLookupResult[0]; if (hexValueIsEmpty(content)) { throw new Error( diff --git a/app/scripts/lib/offscreen-bridge/ledger-offscreen-bridge.ts b/app/scripts/lib/offscreen-bridge/ledger-offscreen-bridge.ts index 608d1ee8156b..1ff85111f54a 100644 --- a/app/scripts/lib/offscreen-bridge/ledger-offscreen-bridge.ts +++ b/app/scripts/lib/offscreen-bridge/ledger-offscreen-bridge.ts @@ -1,4 +1,8 @@ -import { LedgerBridge } from '@metamask/eth-ledger-bridge-keyring'; +import { + LedgerBridge, + LedgerSignTypedDataParams, + LedgerSignTypedDataResponse, +} from '@metamask/eth-ledger-bridge-keyring'; import { LedgerAction, OffscreenCommunicationEvents, @@ -161,11 +165,9 @@ export class LedgerOffscreenBridge }); } - deviceSignTypedData(params: { - hdPath: string; - domainSeparatorHex: string; - hashStructMessageHex: string; - }) { + deviceSignTypedData( + params: LedgerSignTypedDataParams, + ): Promise { return new Promise<{ v: number; s: string; diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js index afcc2e167043..66d57dd8786b 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js @@ -50,7 +50,7 @@ async function addEthereumChainHandler( ) { let validParams; try { - validParams = validateAddEthereumChainParams(req.params[0], end); + validParams = validateAddEthereumChainParams(req.params[0]); } catch (error) { return end(error); } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js index ee0c9d3f732b..eb35e27a1c2b 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js @@ -84,92 +84,62 @@ describe('addEthereumChainHandler', () => { jest.clearAllMocks(); }); - describe('with `endowment:permitted-chains` permissioning inactive', () => { - it('creates a new network configuration for the given chainid and switches to it if none exists', async () => { - const mocks = makeMocks(); - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: CHAIN_IDS.OPTIMISM, - chainName: 'Optimism Mainnet', - rpcUrls: ['https://optimism.llamarpc.com'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - blockExplorerUrls: ['https://optimistic.etherscan.io'], - iconUrls: ['https://optimism.icon.com'], - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); + it('creates a new network configuration for the given chainid, requests `endowment:permitted-chains` permission and switches to it if no networkConfigurations with the same chainId exist', async () => { + const nonInfuraConfiguration = createMockNonInfuraConfiguration(); - expect(mocks.requestUserApproval).toHaveBeenCalledTimes(1); - expect(mocks.addNetwork).toHaveBeenCalledTimes(1); - expect(mocks.addNetwork).toHaveBeenCalledWith({ - blockExplorerUrls: ['https://optimistic.etherscan.io'], - defaultBlockExplorerUrlIndex: 0, - chainId: '0xa', - defaultRpcEndpointIndex: 0, - name: 'Optimism Mainnet', - nativeCurrency: 'ETH', - rpcEndpoints: [ + const mocks = makeMocks({ + permissionedChainIds: [], + overrides: { + getCurrentChainIdForDomain: jest + .fn() + .mockReturnValue(CHAIN_IDS.MAINNET), + }, + }); + await addEthereumChainHandler( + { + origin: 'example.com', + params: [ { - name: 'Optimism Mainnet', - url: 'https://optimism.llamarpc.com', - type: 'custom', + chainId: nonInfuraConfiguration.chainId, + chainName: nonInfuraConfiguration.name, + rpcUrls: nonInfuraConfiguration.rpcEndpoints.map((rpc) => rpc.url), + nativeCurrency: { + symbol: nonInfuraConfiguration.nativeCurrency, + decimals: 18, + }, + blockExplorerUrls: nonInfuraConfiguration.blockExplorerUrls, }, ], - }); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith(123); - }); + }, + {}, + jest.fn(), + jest.fn(), + mocks, + ); - it('creates a new networkConfiguration when called without "blockExplorerUrls" property', async () => { - const mocks = makeMocks(); - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: CHAIN_IDS.OPTIMISM, - chainName: 'Optimism Mainnet', - rpcUrls: ['https://optimism.llamarpc.com'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - iconUrls: ['https://optimism.icon.com'], - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - expect(mocks.addNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - }); + expect(mocks.addNetwork).toHaveBeenCalledWith(nonInfuraConfiguration); + expect( + mocks.grantPermittedChainsPermissionIncremental, + ).toHaveBeenCalledTimes(1); + expect( + mocks.grantPermittedChainsPermissionIncremental, + ).toHaveBeenCalledWith([createMockNonInfuraConfiguration().chainId]); + expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); + expect(mocks.setActiveNetwork).toHaveBeenCalledWith(123); + }); - describe('if a networkConfiguration for the given chainId already exists', () => { - it('updates the existing networkConfiguration with the new rpc url if it doesnt already exist', async () => { + describe('if a networkConfiguration for the given chainId already exists', () => { + describe('if the proposed networkConfiguration has a different rpcUrl from the one already in state', () => { + it('create a new networkConfiguration and switches to it without requesting permissions, if the requested chainId has `endowment:permitted-chains` permission granted for requesting origin', async () => { const mocks = makeMocks({ + permissionedChainIds: [CHAIN_IDS.MAINNET], overrides: { - getNetworkConfigurationByChainId: jest + getCurrentChainIdForDomain: jest .fn() - // Start with just infura endpoint - .mockReturnValue(createMockMainnetConfiguration()), + .mockReturnValue(CHAIN_IDS.SEPOLIA), }, }); - // Add a custom endpoint await addEthereumChainHandler( { origin: 'example.com', @@ -192,131 +162,38 @@ describe('addEthereumChainHandler', () => { mocks, ); - expect(mocks.updateNetwork).toHaveBeenCalledTimes(1); - expect(mocks.updateNetwork).toHaveBeenCalledWith( - '0x1', - { - chainId: '0x1', - name: 'Ethereum Mainnet', - // Expect both endpoints - rpcEndpoints: [ - { - networkClientId: 'mainnet', - url: 'https://mainnet.infura.io/v3/', - type: 'infura', - }, - { - name: 'Ethereum Mainnet', - url: 'https://eth.llamarpc.com', - type: 'custom', - }, - ], - // and the new one is the default - defaultRpcEndpointIndex: 1, - nativeCurrency: 'ETH', - blockExplorerUrls: ['https://etherscan.io'], - defaultBlockExplorerUrlIndex: 0, - }, - undefined, - ); + expect(mocks.requestUserApproval).toHaveBeenCalledTimes(1); + expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); + expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); + expect(mocks.setActiveNetwork).toHaveBeenCalledWith(123); }); - it('makes the rpc url the default if it already exists', async () => { - const existingNetwork = { - chainId: '0x1', - name: 'Ethereum Mainnet', - // Start with infura + custom endpoint - rpcEndpoints: [ - { - networkClientId: 'mainnet', - url: 'https://mainnet.infura.io/v3/', - type: 'infura', - }, - { - name: 'Ethereum Mainnet', - url: 'https://eth.llamarpc.com', - type: 'custom', - }, - ], - // Infura is the default - defaultRpcEndpointIndex: 0, - nativeCurrency: 'ETH', - blockExplorerUrls: ['https://etherscan.io'], - defaultBlockExplorerUrlIndex: 0, - }; - + it('create a new networkConfiguration, requests permissions and switches to it, if the requested chainId does not have permittedChains permission granted for requesting origin', async () => { const mocks = makeMocks({ + permissionedChainIds: [], overrides: { getNetworkConfigurationByChainId: jest .fn() - .mockReturnValue(existingNetwork), - }, - }); - - // Add the same custom endpoint - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: CHAIN_IDS.MAINNET, - chainName: 'Ethereum Mainnet', - rpcUrls: ['https://eth.llamarpc.com'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - blockExplorerUrls: ['https://etherscan.io'], - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.updateNetwork).toHaveBeenCalledTimes(1); - expect(mocks.updateNetwork).toHaveBeenCalledWith( - '0x1', - { - ...existingNetwork, - // Verify the custom endpoint becomes the default - defaultRpcEndpointIndex: 1, - }, - undefined, - ); - }); - - it('switches to the network if its not already the currently selected chain id', async () => { - const existingNetwork = createMockMainnetConfiguration(); - - const mocks = makeMocks({ - overrides: { - // Start on sepolia + .mockReturnValue(createMockNonInfuraConfiguration()), getCurrentChainIdForDomain: jest .fn() - .mockReturnValue(CHAIN_IDS.SEPOLIA), - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(existingNetwork), + .mockReturnValue(CHAIN_IDS.MAINNET), }, }); - // Add with rpc + block explorers that already exist await addEthereumChainHandler( { origin: 'example.com', params: [ { - chainId: CHAIN_IDS.MAINNET, - chainName: 'Ethereum Mainnet', - rpcUrls: [existingNetwork.rpcEndpoints[0].url], + chainId: NON_INFURA_CHAIN_ID, + chainName: 'Custom Network', + rpcUrls: ['https://new-custom.network'], nativeCurrency: { - symbol: 'ETH', + symbol: 'CUST', decimals: 18, }, - blockExplorerUrls: ['https://etherscan.io'], + blockExplorerUrls: ['https://custom.blockexplorer'], }, ], }, @@ -326,65 +203,49 @@ describe('addEthereumChainHandler', () => { mocks, ); - // No updates, network already had all the info - expect(mocks.updateNetwork).toHaveBeenCalledTimes(0); - - // User should be prompted to switch chains + expect(mocks.updateNetwork).toHaveBeenCalledTimes(1); + expect( + mocks.grantPermittedChainsPermissionIncremental, + ).toHaveBeenCalledTimes(1); + expect( + mocks.grantPermittedChainsPermissionIncremental, + ).toHaveBeenCalledWith([NON_INFURA_CHAIN_ID]); expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith('mainnet'); - }); - - it('should return error for invalid chainId', async () => { - const mocks = makeMocks(); - const mockEnd = jest.fn(); - - await addEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: 'invalid_chain_id' }], - }, - {}, - jest.fn(), - mockEnd, - mocks, - ); - - expect(mockEnd).toHaveBeenCalledWith( - rpcErrors.invalidParams({ - message: `Expected 0x-prefixed, unpadded, non-zero hexadecimal string 'chainId'. Received:\ninvalid_chain_id`, - }), - ); }); }); - }); - - describe('with `endowment:permitted-chains` permissioning active', () => { - it('creates a new network configuration for the given chainid, requests `endowment:permitted-chains` permission and switches to it if no networkConfigurations with the same chainId exist', async () => { - const nonInfuraConfiguration = createMockNonInfuraConfiguration(); + it('should switch to the existing networkConfiguration if one already exsits for the given chain id', async () => { const mocks = makeMocks({ - permissionedChainIds: [], + permissionedChainIds: [ + createMockOptimismConfiguration().chainId, + CHAIN_IDS.MAINNET, + ], overrides: { getCurrentChainIdForDomain: jest .fn() .mockReturnValue(CHAIN_IDS.MAINNET), + getNetworkConfigurationByChainId: jest + .fn() + .mockReturnValue(createMockOptimismConfiguration()), }, }); + await addEthereumChainHandler( { origin: 'example.com', params: [ { - chainId: nonInfuraConfiguration.chainId, - chainName: nonInfuraConfiguration.name, - rpcUrls: nonInfuraConfiguration.rpcEndpoints.map( + chainId: createMockOptimismConfiguration().chainId, + chainName: createMockOptimismConfiguration().name, + rpcUrls: createMockOptimismConfiguration().rpcEndpoints.map( (rpc) => rpc.url, ), nativeCurrency: { - symbol: nonInfuraConfiguration.nativeCurrency, + symbol: createMockOptimismConfiguration().nativeCurrency, decimals: 18, }, - blockExplorerUrls: nonInfuraConfiguration.blockExplorerUrls, + blockExplorerUrls: + createMockOptimismConfiguration().blockExplorerUrls, }, ], }, @@ -394,150 +255,11 @@ describe('addEthereumChainHandler', () => { mocks, ); - expect(mocks.addNetwork).toHaveBeenCalledWith(nonInfuraConfiguration); - expect( - mocks.grantPermittedChainsPermissionIncremental, - ).toHaveBeenCalledTimes(1); - expect( - mocks.grantPermittedChainsPermissionIncremental, - ).toHaveBeenCalledWith([createMockNonInfuraConfiguration().chainId]); + expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith(123); - }); - - describe('if a networkConfiguration for the given chainId already exists', () => { - describe('if the proposed networkConfiguration has a different rpcUrl from the one already in state', () => { - it('create a new networkConfiguration and switches to it without requesting permissions, if the requested chainId has `endowment:permitted-chains` permission granted for requesting origin', async () => { - const mocks = makeMocks({ - permissionedChainIds: [CHAIN_IDS.MAINNET], - overrides: { - getCurrentChainIdForDomain: jest - .fn() - .mockReturnValue(CHAIN_IDS.SEPOLIA), - }, - }); - - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: CHAIN_IDS.MAINNET, - chainName: 'Ethereum Mainnet', - rpcUrls: ['https://eth.llamarpc.com'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - blockExplorerUrls: ['https://etherscan.io'], - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.requestUserApproval).toHaveBeenCalledTimes(1); - expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith(123); - }); - - it('create a new networkConfiguration, requests permissions and switches to it, if the requested chainId does not have permittedChains permission granted for requesting origin', async () => { - const mocks = makeMocks({ - permissionedChainIds: [], - overrides: { - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(createMockNonInfuraConfiguration()), - getCurrentChainIdForDomain: jest - .fn() - .mockReturnValue(CHAIN_IDS.MAINNET), - }, - }); - - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: NON_INFURA_CHAIN_ID, - chainName: 'Custom Network', - rpcUrls: ['https://new-custom.network'], - nativeCurrency: { - symbol: 'CUST', - decimals: 18, - }, - blockExplorerUrls: ['https://custom.blockexplorer'], - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.updateNetwork).toHaveBeenCalledTimes(1); - expect( - mocks.grantPermittedChainsPermissionIncremental, - ).toHaveBeenCalledTimes(1); - expect( - mocks.grantPermittedChainsPermissionIncremental, - ).toHaveBeenCalledWith([NON_INFURA_CHAIN_ID]); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - }); - }); - - it('should switch to the existing networkConfiguration if one already exsits for the given chain id', async () => { - const mocks = makeMocks({ - permissionedChainIds: [ - createMockOptimismConfiguration().chainId, - CHAIN_IDS.MAINNET, - ], - overrides: { - getCurrentChainIdForDomain: jest - .fn() - .mockReturnValue(CHAIN_IDS.MAINNET), - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(createMockOptimismConfiguration()), - }, - }); - - await addEthereumChainHandler( - { - origin: 'example.com', - params: [ - { - chainId: createMockOptimismConfiguration().chainId, - chainName: createMockOptimismConfiguration().name, - rpcUrls: createMockOptimismConfiguration().rpcEndpoints.map( - (rpc) => rpc.url, - ), - nativeCurrency: { - symbol: createMockOptimismConfiguration().nativeCurrency, - decimals: 18, - }, - blockExplorerUrls: - createMockOptimismConfiguration().blockExplorerUrls, - }, - ], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockOptimismConfiguration().rpcEndpoints[0].networkClientId, - ); - }); + expect(mocks.setActiveNetwork).toHaveBeenCalledWith( + createMockOptimismConfiguration().rpcEndpoints[0].networkClientId, + ); }); }); diff --git a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js index 10973e052715..2f86b30885e5 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js @@ -25,7 +25,7 @@ export function validateChainId(chainId) { return _chainId; } -export function validateSwitchEthereumChainParams(req, end) { +export function validateSwitchEthereumChainParams(req) { if (!req.params?.[0] || typeof req.params[0] !== 'object') { throw rpcErrors.invalidParams({ message: `Expected single, object parameter. Received:\n${JSON.stringify( @@ -43,10 +43,10 @@ export function validateSwitchEthereumChainParams(req, end) { }); } - return validateChainId(chainId, end); + return validateChainId(chainId); } -export function validateAddEthereumChainParams(params, end) { +export function validateAddEthereumChainParams(params) { if (!params || typeof params !== 'object') { throw rpcErrors.invalidParams({ message: `Expected single, object parameter. Received:\n${JSON.stringify( @@ -75,7 +75,7 @@ export function validateAddEthereumChainParams(params, end) { }); } - const _chainId = validateChainId(chainId, end); + const _chainId = validateChainId(chainId); if (!rpcUrls || !Array.isArray(rpcUrls) || rpcUrls.length === 0) { throw rpcErrors.invalidParams({ message: `Expected an array with at least one valid string HTTPS url 'rpcUrls', Received:\n${rpcUrls}`, diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js index 5f907bef4d4b..1fbeedbef3f5 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js @@ -36,7 +36,7 @@ async function switchEthereumChainHandler( ) { let chainId; try { - chainId = validateSwitchEthereumChainParams(req, end); + chainId = validateSwitchEthereumChainParams(req); } catch (error) { return end(error); } diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js index be612fbc7d8e..abd0c0eb9ff7 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js @@ -16,16 +16,6 @@ const createMockMainnetConfiguration = () => ({ ], }); -const createMockLineaMainnetConfiguration = () => ({ - chainId: CHAIN_IDS.LINEA_MAINNET, - defaultRpcEndpointIndex: 0, - rpcEndpoints: [ - { - networkClientId: NETWORK_TYPES.LINEA_MAINNET, - }, - ], -}); - describe('switchEthereumChainHandler', () => { const makeMocks = ({ permissionedChainIds = [], @@ -55,228 +45,84 @@ describe('switchEthereumChainHandler', () => { jest.clearAllMocks(); }); - describe('with permittedChains permissioning inactive', () => { - it('should call setActiveNetwork when switching to a built-in infura network', async () => { - const mocks = makeMocks({ - overrides: { - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(createMockMainnetConfiguration()), - }, - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.MAINNET }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); - }); - - it('should call setActiveNetwork when switching to a built-in infura network, when chainId from request is lower case', async () => { - const mocks = makeMocks({ - overrides: { - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(createMockLineaMainnetConfiguration()), - }, - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.LINEA_MAINNET.toLowerCase() }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockLineaMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); - }); - - it('should call setActiveNetwork when switching to a built-in infura network, when chainId from request is upper case', async () => { - const mocks = makeMocks({ - overrides: { - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(createMockLineaMainnetConfiguration()), - }, - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.LINEA_MAINNET.toUpperCase() }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockLineaMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); - }); - - it('should call setActiveNetwork when switching to a custom network', async () => { - const mocks = makeMocks({ - overrides: { - getCurrentChainIdForDomain: jest - .fn() - .mockReturnValue(CHAIN_IDS.MAINNET), - }, - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: NON_INFURA_CHAIN_ID }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); - }); - - it('should handle missing networkConfiguration', async () => { - // Mock a network configuration that has an undefined or missing rpcEndpoints - const mockNetworkConfiguration = undefined; - - const mocks = makeMocks({ - overrides: { - getNetworkConfigurationByChainId: jest - .fn() - .mockReturnValue(mockNetworkConfiguration), - }, - }); - - const switchEthereumChainHandler = switchEthereumChain.implementation; - - const mockEnd = jest.fn(); - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.MAINNET }], - }, - {}, - jest.fn(), - mockEnd, - mocks, - ); - - // Check that the function handled the missing rpcEndpoints and did not attempt to call setActiveNetwork - expect(mockEnd).toHaveBeenCalledWith( - expect.objectContaining({ - code: 4902, - message: expect.stringContaining('Unrecognized chain ID'), - }), - ); - expect(mocks.setActiveNetwork).not.toHaveBeenCalled(); + it('should call requestPermittedChainsPermission and setActiveNetwork when chainId is not in `endowment:permitted-chains`', async () => { + const mockrequestPermittedChainsPermission = jest.fn().mockResolvedValue(); + const mocks = makeMocks({ + overrides: { + requestPermittedChainsPermission: mockrequestPermittedChainsPermission, + }, }); + const switchEthereumChainHandler = switchEthereumChain.implementation; + await switchEthereumChainHandler( + { + origin: 'example.com', + params: [{ chainId: CHAIN_IDS.MAINNET }], + }, + {}, + jest.fn(), + jest.fn(), + mocks, + ); + + expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledTimes(1); + expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledWith([ + CHAIN_IDS.MAINNET, + ]); + expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); + expect(mocks.setActiveNetwork).toHaveBeenCalledWith( + createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, + ); }); - describe('with permittedChains permissioning active', () => { - it('should call requestPermittedChainsPermission and setActiveNetwork when chainId is not in `endowment:permitted-chains`', async () => { - const mockrequestPermittedChainsPermission = jest - .fn() - .mockResolvedValue(); - const mocks = makeMocks({ - overrides: { - requestPermittedChainsPermission: - mockrequestPermittedChainsPermission, - }, - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.MAINNET }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledTimes(1); - expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledWith([ - CHAIN_IDS.MAINNET, - ]); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); + it('should call setActiveNetwork without calling requestPermittedChainsPermission when requested chainId is in `endowment:permitted-chains`', async () => { + const mocks = makeMocks({ + permissionedChainIds: [CHAIN_IDS.MAINNET], }); + const switchEthereumChainHandler = switchEthereumChain.implementation; + await switchEthereumChainHandler( + { + origin: 'example.com', + params: [{ chainId: CHAIN_IDS.MAINNET }], + }, + {}, + jest.fn(), + jest.fn(), + mocks, + ); + + expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); + expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); + expect(mocks.setActiveNetwork).toHaveBeenCalledWith( + createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, + ); + }); - it('should call setActiveNetwork without calling requestPermittedChainsPermission when requested chainId is in `endowment:permitted-chains`', async () => { - const mocks = makeMocks({ - permissionedChainIds: [CHAIN_IDS.MAINNET], - }); - const switchEthereumChainHandler = switchEthereumChain.implementation; - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.MAINNET }], - }, - {}, - jest.fn(), - jest.fn(), - mocks, - ); - - expect(mocks.requestPermittedChainsPermission).not.toHaveBeenCalled(); - expect(mocks.setActiveNetwork).toHaveBeenCalledTimes(1); - expect(mocks.setActiveNetwork).toHaveBeenCalledWith( - createMockMainnetConfiguration().rpcEndpoints[0].networkClientId, - ); - }); - - it('should handle errors during the switch network permission request', async () => { - const mockError = new Error('Permission request failed'); - const mockrequestPermittedChainsPermission = jest - .fn() - .mockRejectedValue(mockError); - const mocks = makeMocks({ - overrides: { - requestPermittedChainsPermission: - mockrequestPermittedChainsPermission, - }, - }); - const mockEnd = jest.fn(); - const switchEthereumChainHandler = switchEthereumChain.implementation; - - await switchEthereumChainHandler( - { - origin: 'example.com', - params: [{ chainId: CHAIN_IDS.MAINNET }], - }, - {}, - jest.fn(), - mockEnd, - mocks, - ); - - expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledTimes(1); - expect(mockEnd).toHaveBeenCalledWith(mockError); - expect(mocks.setActiveNetwork).not.toHaveBeenCalled(); + it('should handle errors during the switch network permission request', async () => { + const mockError = new Error('Permission request failed'); + const mockrequestPermittedChainsPermission = jest + .fn() + .mockRejectedValue(mockError); + const mocks = makeMocks({ + overrides: { + requestPermittedChainsPermission: mockrequestPermittedChainsPermission, + }, }); + const mockEnd = jest.fn(); + const switchEthereumChainHandler = switchEthereumChain.implementation; + + await switchEthereumChainHandler( + { + origin: 'example.com', + params: [{ chainId: CHAIN_IDS.MAINNET }], + }, + {}, + jest.fn(), + mockEnd, + mocks, + ); + + expect(mocks.requestPermittedChainsPermission).toHaveBeenCalledTimes(1); + expect(mockEnd).toHaveBeenCalledWith(mockError); + expect(mocks.setActiveNetwork).not.toHaveBeenCalled(); }); }); diff --git a/app/scripts/lib/snap-keyring/snap-keyring.test.ts b/app/scripts/lib/snap-keyring/snap-keyring.test.ts index 4136fd1fd1fc..0e778b2268d7 100644 --- a/app/scripts/lib/snap-keyring/snap-keyring.test.ts +++ b/app/scripts/lib/snap-keyring/snap-keyring.test.ts @@ -1,5 +1,6 @@ import { ControllerMessenger } from '@metamask/base-controller'; -import { EthAccountType, InternalAccount } from '@metamask/keyring-api'; +import { EthAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES } from '../../../../shared/constants/app'; import { MetaMetricsEventCategory, diff --git a/app/scripts/lib/transaction/decode/proxy.test.ts b/app/scripts/lib/transaction/decode/proxy.test.ts index d137fe567c73..b98839d16743 100644 --- a/app/scripts/lib/transaction/decode/proxy.test.ts +++ b/app/scripts/lib/transaction/decode/proxy.test.ts @@ -1,44 +1,46 @@ -import EthQuery from '@metamask/eth-query'; +import type { Provider } from '@metamask/network-controller'; import { getContractProxyAddress } from './proxy'; const CONTRACT_ADDRESS_MOCK = '0x456'; -function createEthQueryMock(storageValues: string[]): EthQuery { - const ethQuery = { - eth_getStorageAt: jest.fn(), - }; +function createProviderMock(storageValues: string[]): Provider { + const ethGetStorageAt = jest.fn(); for (const storageValue of storageValues) { - ethQuery.eth_getStorageAt.mockImplementationOnce( - (_contractAddress, _storageSlot, _blockNumber, cb) => - cb(null, storageValue), - ); + ethGetStorageAt.mockImplementationOnce(() => storageValue); } - return ethQuery as unknown as EthQuery; + return { + request: async (request) => { + if (request.method === 'eth_getStorageAt') { + return ethGetStorageAt(request); + } + throw new Error(`Unexpected method: ${request.method}`); + }, + } as Provider; } describe('Proxy', () => { describe('getContractProxyAddress', () => { it('returns undefined if all responses empty', async () => { - const ethQuery = createEthQueryMock([ + const provider = createProviderMock([ '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000000', ]); expect( - await getContractProxyAddress(CONTRACT_ADDRESS_MOCK, ethQuery), + await getContractProxyAddress(CONTRACT_ADDRESS_MOCK, provider), ).toBeUndefined(); }); it('returns first non-empty response', async () => { - const ethQuery = createEthQueryMock([ + const provider = createProviderMock([ '0x0000000000000000000000000000000000000000000000000000000000000000', '00000000000000000000000000123', ]); expect( - await getContractProxyAddress(CONTRACT_ADDRESS_MOCK, ethQuery), + await getContractProxyAddress(CONTRACT_ADDRESS_MOCK, provider), ).toBe('0x123'); }); }); diff --git a/app/scripts/lib/transaction/decode/proxy.ts b/app/scripts/lib/transaction/decode/proxy.ts index 19d5887acd13..3f0367abc648 100644 --- a/app/scripts/lib/transaction/decode/proxy.ts +++ b/app/scripts/lib/transaction/decode/proxy.ts @@ -1,6 +1,5 @@ -import { query } from '@metamask/controller-utils'; -import EthQuery from '@metamask/eth-query'; -import { Hex } from '@metamask/utils'; +import type { Provider } from '@metamask/network-controller'; +import type { Hex, JsonRpcParams } from '@metamask/utils'; import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util'; const IMPLEMENTATION_STORAGE_SLOTS = [ @@ -15,16 +14,14 @@ const EMPTY_RESULT = '0'.padEnd(64, '0'); export async function getContractProxyAddress( contractAddress: Hex, - ethQuery: EthQuery, + provider: Provider, ): Promise { const responses = await Promise.all( - IMPLEMENTATION_STORAGE_SLOTS.map( - (storageSlot) => - query(ethQuery, 'eth_getStorageAt', [ - contractAddress, - storageSlot, - 'latest', - ]) as Promise, + IMPLEMENTATION_STORAGE_SLOTS.map((storageSlot) => + provider.request({ + method: 'eth_getStorageAt', + params: [contractAddress, storageSlot, 'latest'], + }), ), ); diff --git a/app/scripts/lib/transaction/decode/util.test.ts b/app/scripts/lib/transaction/decode/util.test.ts index 66984b29cfe4..d114b5cc4fb7 100644 --- a/app/scripts/lib/transaction/decode/util.test.ts +++ b/app/scripts/lib/transaction/decode/util.test.ts @@ -1,4 +1,4 @@ -import EthQuery from '@metamask/eth-query'; +import type { Provider } from '@metamask/network-controller'; import { TRANSACTION_DATA_FOUR_BYTE, TRANSACTION_DATA_SOURCIFY, @@ -20,7 +20,7 @@ jest.mock('./proxy'); const CONTRACT_ADDRESS_MOCK = '0x456'; const CHAIN_ID_MOCK = '0x123'; -const ETH_QUERY_MOCK = {} as EthQuery; +const PROVIDER_MOCK = {} as Provider; describe('Transaction Decode Utils', () => { const decodeUniswapRouterTransactionDataMock = jest.mocked( @@ -56,7 +56,7 @@ describe('Transaction Decode Utils', () => { transactionData: TRANSACTION_DATA_UNISWAP, contractAddress: CONTRACT_ADDRESS_MOCK, chainId: CHAIN_ID_MOCK, - ethQuery: ETH_QUERY_MOCK, + provider: PROVIDER_MOCK, }); expect(result).toStrictEqual(TRANSACTION_DECODE_UNISWAP); @@ -71,7 +71,7 @@ describe('Transaction Decode Utils', () => { transactionData: TRANSACTION_DATA_SOURCIFY, contractAddress: CONTRACT_ADDRESS_MOCK, chainId: CHAIN_ID_MOCK, - ethQuery: ETH_QUERY_MOCK, + provider: PROVIDER_MOCK, }); expect(result).toStrictEqual(TRANSACTION_DECODE_SOURCIFY); @@ -86,7 +86,7 @@ describe('Transaction Decode Utils', () => { transactionData: TRANSACTION_DATA_FOUR_BYTE, contractAddress: CONTRACT_ADDRESS_MOCK, chainId: CHAIN_ID_MOCK, - ethQuery: ETH_QUERY_MOCK, + provider: PROVIDER_MOCK, }); expect(result).toStrictEqual(TRANSACTION_DECODE_FOUR_BYTE); @@ -97,7 +97,7 @@ describe('Transaction Decode Utils', () => { transactionData: TRANSACTION_DATA_FOUR_BYTE, contractAddress: CONTRACT_ADDRESS_MOCK, chainId: CHAIN_ID_MOCK, - ethQuery: ETH_QUERY_MOCK, + provider: PROVIDER_MOCK, }); expect(result).toBeUndefined(); diff --git a/app/scripts/lib/transaction/decode/util.ts b/app/scripts/lib/transaction/decode/util.ts index d8bca103ff73..cb5aca019516 100644 --- a/app/scripts/lib/transaction/decode/util.ts +++ b/app/scripts/lib/transaction/decode/util.ts @@ -1,5 +1,5 @@ import { Hex, createProjectLogger } from '@metamask/utils'; -import EthQuery from '@metamask/eth-query'; +import type { Provider } from '@metamask/network-controller'; import { DecodedTransactionDataMethod, DecodedTransactionDataParam, @@ -17,12 +17,12 @@ export async function decodeTransactionData({ transactionData, contractAddress, chainId, - ethQuery, + provider, }: { transactionData: Hex; contractAddress: Hex; chainId: Hex; - ethQuery: EthQuery; + provider: Provider; }): Promise { log('Decoding transaction data', { transactionData, @@ -45,7 +45,7 @@ export async function decodeTransactionData({ }; } - const proxyAddress = await getContractProxyAddress(contractAddress, ethQuery); + const proxyAddress = await getContractProxyAddress(contractAddress, provider); if (proxyAddress) { log('Retrieved proxy implementation address', proxyAddress); diff --git a/app/scripts/lib/transaction/metrics.test.ts b/app/scripts/lib/transaction/metrics.test.ts index 8e2924a0e30f..ad28d22967f3 100644 --- a/app/scripts/lib/transaction/metrics.test.ts +++ b/app/scripts/lib/transaction/metrics.test.ts @@ -25,6 +25,7 @@ import { BlockaidReason, BlockaidResultType, } from '../../../../shared/constants/security-provider'; +import { decimalToHex } from '../../../../shared/modules/conversion.utils'; import { handleTransactionAdded, handleTransactionApproved, @@ -74,7 +75,6 @@ const mockTransactionMetricsRequest = { trackEvent: jest.fn(), getIsSmartTransaction: jest.fn(), getSmartTransactionByMinedTxHash: jest.fn(), - getRedesignedTransactionsEnabled: jest.fn(), getMethodData: jest.fn(), getIsRedesignedConfirmationsDeveloperEnabled: jest.fn(), getIsConfirmationAdvancedDetailsOpen: jest.fn(), @@ -828,6 +828,67 @@ describe('Transaction metrics', () => { mockTransactionMetricsRequest.finalizeEventFragment, ).toHaveBeenCalledWith(expectedUniqueId); }); + + it('should create, update, finalize event fragment with completion_time_onchain', async () => { + mockTransactionMeta.txReceipt = { + gasUsed: '0x123', + status: '0x0', + }; + mockTransactionMeta.blockTimestamp = decimalToHex(124); + mockTransactionMeta.submittedTime = 123123; + + await handleTransactionConfirmed(mockTransactionMetricsRequest, { + ...mockTransactionMeta, + actionId: mockActionId, + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + const expectedUniqueId = 'transaction-submitted-1'; + + expect(mockTransactionMetricsRequest.createEventFragment).toBeCalledTimes( + 1, + ); + expect(mockTransactionMetricsRequest.createEventFragment).toBeCalledWith({ + actionId: mockActionId, + category: MetaMetricsEventCategory.Transactions, + successEvent: TransactionMetaMetricsEvent.finalized, + uniqueIdentifier: expectedUniqueId, + persist: true, + properties: expectedProperties, + sensitiveProperties: { + ...expectedSensitiveProperties, + completion_time: expect.any(String), + completion_time_onchain: '0.88', + gas_used: '0.000000291', + status: METRICS_STATUS_FAILED, + }, + }); + + expect(mockTransactionMetricsRequest.updateEventFragment).toBeCalledTimes( + 1, + ); + expect(mockTransactionMetricsRequest.updateEventFragment).toBeCalledWith( + expectedUniqueId, + { + properties: expectedProperties, + sensitiveProperties: { + ...expectedSensitiveProperties, + completion_time: expect.any(String), + completion_time_onchain: '0.88', + gas_used: '0.000000291', + status: METRICS_STATUS_FAILED, + }, + }, + ); + + expect( + mockTransactionMetricsRequest.finalizeEventFragment, + ).toBeCalledTimes(1); + expect( + mockTransactionMetricsRequest.finalizeEventFragment, + ).toBeCalledWith(expectedUniqueId); + }); }); describe('handleTransactionDropped', () => { diff --git a/app/scripts/lib/transaction/metrics.ts b/app/scripts/lib/transaction/metrics.ts index ee09d60259cd..ddea334562ba 100644 --- a/app/scripts/lib/transaction/metrics.ts +++ b/app/scripts/lib/transaction/metrics.ts @@ -1,4 +1,4 @@ -import EthQuery, { Provider } from '@metamask/eth-query'; +import type { Provider } from '@metamask/network-controller'; import { FetchGasFeeEstimateOptions } from '@metamask/gas-fee-controller'; import { BigNumber } from 'bignumber.js'; import { isHexString } from 'ethereumjs-util'; @@ -33,6 +33,7 @@ import { TRANSACTION_ENVELOPE_TYPE_NAMES, } from '../../../../shared/lib/transactions-controller-utils'; import { + hexToDecimal, hexWEIToDecETH, hexWEIToDecGWEI, } from '../../../../shared/modules/conversion.utils'; @@ -101,7 +102,6 @@ export type TransactionMetricsRequest = { getSmartTransactionByMinedTxHash: ( txhash: string | undefined, ) => SmartTransaction; - getRedesignedTransactionsEnabled: () => boolean; getMethodData: (data: string) => Promise<{ name: string }>; getIsRedesignedConfirmationsDeveloperEnabled: () => boolean; getIsConfirmationAdvancedDetailsOpen: () => boolean; @@ -228,13 +228,22 @@ export const handleTransactionConfirmed = async ( const { txReceipt } = transactionMeta; extraParams.gas_used = txReceipt?.gasUsed; + extraParams.block_number = + txReceipt?.blockNumber && hexToDecimal(txReceipt.blockNumber); - const { submittedTime } = transactionMeta; + const { submittedTime, blockTimestamp } = transactionMeta; if (submittedTime) { extraParams.completion_time = getTransactionCompletionTime(submittedTime); } + if (submittedTime && blockTimestamp) { + extraParams.completion_time_onchain = getTransactionOnchainCompletionTime( + submittedTime, + blockTimestamp, + ); + } + if (txReceipt?.status === '0x0') { extraParams.status = METRICS_STATUS_FAILED; } @@ -799,7 +808,6 @@ async function buildEventFragmentProperties({ id, userFeeLevel, } = transactionMeta; - const query = new EthQuery(transactionMetricsRequest.provider); const source = referrer === ORIGIN_METAMASK ? 'user' : 'dapp'; const gasFeeSelected = @@ -807,7 +815,7 @@ async function buildEventFragmentProperties({ const { assetType, tokenStandard } = await determineTransactionAssetType( transactionMeta, - query, + transactionMetricsRequest.provider, transactionMetricsRequest.getTokenStandardAndDetails, ); @@ -1015,8 +1023,6 @@ async function buildEventFragmentProperties({ const isRedesignedForTransaction = shouldUseRedesignForTransactions({ transactionMetadataType: transactionMeta.type as TransactionType, - isRedesignedTransactionsUserSettingEnabled: - transactionMetricsRequest.getRedesignedTransactionsEnabled(), isRedesignedConfirmationsDeveloperEnabled: transactionMetricsRequest.getIsRedesignedConfirmationsDeveloperEnabled(), }); @@ -1133,6 +1139,30 @@ function getTransactionCompletionTime(submittedTime: number) { return Math.round((Date.now() - submittedTime) / 1000).toString(); } +/** + * Returns number of seconds (rounded to the hundredths) between submitted time + * and the block timestamp. + * + * @param submittedTimeMs - The UNIX timestamp in milliseconds in which the + * transaction has been submitted + * @param blockTimestampHex - The UNIX timestamp in seconds in hexadecimal in which + * the transaction has been confirmed in a block + */ +function getTransactionOnchainCompletionTime( + submittedTimeMs: number, + blockTimestampHex: string, +): string { + const DECIMAL_DIGITS = 2; + + const blockTimestampSeconds = Number(hexToDecimal(blockTimestampHex)); + const completionTimeSeconds = blockTimestampSeconds - submittedTimeMs / 1000; + const completionTimeSecondsRounded = + Math.round(completionTimeSeconds * 10 ** DECIMAL_DIGITS) / + 10 ** DECIMAL_DIGITS; + + return completionTimeSecondsRounded.toString(); +} + /** * The allowance amount in relation to the dapp proposed amount for specific token * diff --git a/app/scripts/lib/transaction/util.test.ts b/app/scripts/lib/transaction/util.test.ts index 4d78ea51cfa5..0a941968d802 100644 --- a/app/scripts/lib/transaction/util.test.ts +++ b/app/scripts/lib/transaction/util.test.ts @@ -1,4 +1,4 @@ -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { TransactionParams } from '@metamask/eth-json-rpc-middleware'; import { TransactionController, diff --git a/app/scripts/lib/transaction/util.ts b/app/scripts/lib/transaction/util.ts index 34f27d321e0b..a3d0b929aff8 100644 --- a/app/scripts/lib/transaction/util.ts +++ b/app/scripts/lib/transaction/util.ts @@ -1,4 +1,5 @@ -import { EthAccountType, InternalAccount } from '@metamask/keyring-api'; +import { EthAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { TransactionController, TransactionMeta, diff --git a/app/scripts/lib/util.ts b/app/scripts/lib/util.ts index e41b2a00b670..676be0e8f813 100644 --- a/app/scripts/lib/util.ts +++ b/app/scripts/lib/util.ts @@ -6,6 +6,7 @@ import { TransactionEnvelopeType, TransactionMeta, } from '@metamask/transaction-controller'; +import type { Provider } from '@metamask/network-controller'; import { ENVIRONMENT_TYPE_BACKGROUND, ENVIRONMENT_TYPE_FULLSCREEN, @@ -394,7 +395,7 @@ export const getMethodDataName = async ( use4ByteResolution: boolean, prefixedData: string, addKnownMethodData: (fourBytePrefix: string, methodData: MethodData) => void, - provider: object, + provider: Provider, ) => { if (!prefixedData || !use4ByteResolution) { return null; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0c1a853a08f1..7f36a38ab941 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -45,8 +45,6 @@ import { import LatticeKeyring from 'eth-lattice-keyring'; import { rawChainData } from 'eth-chainlist'; import { MetaMaskKeyring as QRHardwareKeyring } from '@keystonehq/metamask-airgapped-keyring'; -import EthQuery from '@metamask/eth-query'; -import EthJSQuery from '@metamask/ethjs-query'; import { nanoid } from 'nanoid'; import { captureException } from '@sentry/browser'; import { AddressBookController } from '@metamask/address-book-controller'; @@ -146,12 +144,13 @@ import { TransactionType, } from '@metamask/transaction-controller'; -///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) import { + ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) getLocalizedSnapManifest, stripSnapPrefix, + ///: END:ONLY_INCLUDE_IF + isSnapId, } from '@metamask/snaps-utils'; -///: END:ONLY_INCLUDE_IF import { Interface } from '@ethersproject/abi'; import { abiERC1155, abiERC721 } from '@metamask/metamask-eth-abis'; @@ -245,11 +244,13 @@ import { } from '../../shared/lib/transactions-controller-utils'; import { getProviderConfig } from '../../shared/modules/selectors/networks'; import { endTrace, trace } from '../../shared/lib/trace'; -// eslint-disable-next-line import/no-restricted-paths -import { isSnapId } from '../../ui/helpers/utils/snaps'; import { BridgeStatusAction } from '../../shared/types/bridge-status'; import { ENVIRONMENT } from '../../development/build/constants'; import fetchWithCache from '../../shared/lib/fetch-with-cache'; +import { + BridgeUserAction, + BridgeBackgroundAction, +} from '../../shared/types/bridge'; import { BalancesController as MultichainBalancesController } from './lib/accounts/BalancesController'; import { ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) @@ -366,10 +367,6 @@ import { updateSecurityAlertResponse } from './lib/ppom/ppom-util'; import createEvmMethodsToNonEvmAccountReqFilterMiddleware from './lib/createEvmMethodsToNonEvmAccountReqFilterMiddleware'; import { isEthAddress } from './lib/multichain/address'; import { decodeTransactionData } from './lib/transaction/decode/util'; -import { - BridgeUserAction, - BridgeBackgroundAction, -} from './controllers/bridge/types'; import BridgeController from './controllers/bridge/bridge-controller'; import { BRIDGE_CONTROLLER_NAME } from './controllers/bridge/constants'; import { @@ -762,8 +759,6 @@ export default class MetamaskController extends EventEmitter { }), }); - this.nftController.setApiKey(process.env.OPENSEA_KEY); - const nftDetectionControllerMessenger = this.controllerMessenger.getRestricted({ name: 'NftDetectionController', @@ -1335,13 +1330,13 @@ export default class MetamaskController extends EventEmitter { ], }), state: initState.SelectedNetworkController, - useRequestQueuePreference: - this.preferencesController.state.useRequestQueue, - onPreferencesStateChange: (listener) => { - preferencesMessenger.subscribe( - 'PreferencesController:stateChange', - listener, - ); + useRequestQueuePreference: true, + onPreferencesStateChange: () => { + // noop + // we have removed the ability to toggle the useRequestQueue preference + // both useRequestQueue and onPreferencesStateChange will be removed + // once mobile supports per dapp network selection + // see https://github.com/MetaMask/core/pull/5065#issue-2736965186 }, domainProxyMap: new WeakRefObjectMap(), }); @@ -1393,6 +1388,7 @@ export default class MetamaskController extends EventEmitter { 'ExecutionService:unhandledError', 'ExecutionService:outboundRequest', 'ExecutionService:outboundResponse', + 'KeyringController:lock', ], allowedActions: [ `${this.permissionController.name}:getEndowments`, @@ -1634,7 +1630,15 @@ export default class MetamaskController extends EventEmitter { }, }); }, - onAccountSyncErroneousSituation: (profileId, situationMessage) => { + onAccountSyncErroneousSituation: ( + profileId, + situationMessage, + sentryContext, + ) => { + captureException( + new Error(`Account sync - ${situationMessage}`), + sentryContext, + ); this.metaMetricsController.trackEvent({ category: MetaMetricsEventCategory.ProfileSyncing, event: MetaMetricsEventName.AccountsSyncErroneousSituation, @@ -2113,7 +2117,7 @@ export default class MetamaskController extends EventEmitter { this.signatureController.hub.on( 'cancelWithReason', - ({ message, reason }) => { + ({ metadata: message, reason }) => { this.metaMetricsController.trackEvent({ event: reason, category: MetaMetricsEventCategory.Transactions, @@ -2271,7 +2275,10 @@ export default class MetamaskController extends EventEmitter { const smartTransactionsControllerMessenger = this.controllerMessenger.getRestricted({ name: 'SmartTransactionsController', - allowedActions: ['NetworkController:getNetworkClientById'], + allowedActions: [ + 'NetworkController:getNetworkClientById', + 'NetworkController:getState', + ], allowedEvents: ['NetworkController:stateChange'], }); this.smartTransactionsController = new SmartTransactionsController({ @@ -2433,6 +2440,7 @@ export default class MetamaskController extends EventEmitter { allowedEvents: [], }), disabled: !this.preferencesController.state.useExternalServices, + getMetaMetricsId: () => this.metaMetricsController.getMetaMetricsId(), clientConfigApiService: new ClientConfigApiService({ fetch: globalThis.fetch.bind(globalThis), config: { @@ -2929,6 +2937,17 @@ export default class MetamaskController extends EventEmitter { return currentLocale; } + /** + * Gets whether the privacy mode is enabled from the PreferencesController. + * + * @returns {boolean} Whether the privacy mode is enabled. + */ + getPrivacyMode() { + const { privacyMode } = this.preferencesController.state; + + return privacyMode; + } + /** * Constructor helper for getting Snap permission specifications. */ @@ -2941,7 +2960,8 @@ export default class MetamaskController extends EventEmitter { getPreferences: () => { const locale = this.getLocale(); const currency = this.currencyRateController.state.currentCurrency; - return { locale, currency }; + const hideBalances = this.getPrivacyMode(); + return { locale, currency, hideBalances }; }, clearSnapState: this.controllerMessenger.call.bind( this.controllerMessenger, @@ -3359,9 +3379,7 @@ export default class MetamaskController extends EventEmitter { * @returns {Promise<{ isUnlocked: boolean, networkVersion: string, chainId: string, accounts: string[] }>} An object with relevant state properties. */ async getProviderState(origin) { - const providerNetworkState = await this.getProviderNetworkState( - this.preferencesController.getUseRequestQueue() ? origin : undefined, - ); + const providerNetworkState = await this.getProviderNetworkState(origin); return { isUnlocked: this.isUnlocked(), @@ -3393,17 +3411,16 @@ export default class MetamaskController extends EventEmitter { let networkVersion = this.deprecatedNetworkVersions[networkClientId]; if (networkVersion === undefined && completedOnboarding) { - const ethQuery = new EthQuery(networkClient.provider); - networkVersion = await new Promise((resolve) => { - ethQuery.sendAsync({ method: 'net_version' }, (error, result) => { - if (error) { - console.error(error); - resolve(null); - } else { - resolve(convertNetworkId(result)); - } + try { + const result = await networkClient.provider.request({ + method: 'net_version', }); - }); + networkVersion = convertNetworkId(result); + } catch (error) { + console.error(error); + networkVersion = null; + } + this.deprecatedNetworkVersions[networkClientId] = networkVersion; } @@ -3520,9 +3537,6 @@ export default class MetamaskController extends EventEmitter { setOpenSeaEnabled: preferencesController.setOpenSeaEnabled.bind( preferencesController, ), - getUseRequestQueue: this.preferencesController.getUseRequestQueue.bind( - this.preferencesController, - ), getProviderConfig: () => getProviderConfig({ metamask: this.networkController.state, @@ -3572,7 +3586,6 @@ export default class MetamaskController extends EventEmitter { preferencesController.setUseTransactionSimulations.bind( preferencesController, ), - setUseRequestQueue: this.setUseRequestQueue.bind(this), setIpfsGateway: preferencesController.setIpfsGateway.bind( preferencesController, ), @@ -4443,7 +4456,7 @@ export default class MetamaskController extends EventEmitter { decodeTransactionData: (request) => decodeTransactionData({ ...request, - ethQuery: new EthQuery(this.provider), + provider: this.provider, }), // metrics data deleteion createMetaMetricsDataDeletionTask: @@ -4524,39 +4537,46 @@ export default class MetamaskController extends EventEmitter { // or if it is true but the `fetchTokenBalance`` call failed. In either case, we should // attempt to retrieve details from `assetsContractController.getTokenStandardAndDetails` if (details === undefined) { - details = await this.assetsContractController.getTokenStandardAndDetails( - address, - userAddress, - tokenId, - ); + try { + details = + await this.assetsContractController.getTokenStandardAndDetails( + address, + userAddress, + tokenId, + ); + } catch (e) { + log.warn(`Failed to get token standard and details. Error: ${e}`); + } } - const tokenDetailsStandardIsERC1155 = isEqualCaseInsensitive( - details.standard, - TokenStandard.ERC1155, - ); + if (details) { + const tokenDetailsStandardIsERC1155 = isEqualCaseInsensitive( + details.standard, + TokenStandard.ERC1155, + ); - if (tokenDetailsStandardIsERC1155) { - try { - const balance = await fetchERC1155Balance( - address, - userAddress, - tokenId, - this.provider, - ); + if (tokenDetailsStandardIsERC1155) { + try { + const balance = await fetchERC1155Balance( + address, + userAddress, + tokenId, + this.provider, + ); - const balanceToUse = balance?._hex - ? parseInt(balance._hex, 16).toString() - : null; + const balanceToUse = balance?._hex + ? parseInt(balance._hex, 16).toString() + : null; - details = { - ...details, - balance: balanceToUse, - }; - } catch (e) { - // If the `fetchTokenBalance` call failed, `details` remains undefined, and we - // fall back to the below `assetsContractController.getTokenStandardAndDetails` call - log.warn('Failed to get token balance. Error:', e); + details = { + ...details, + balance: balanceToUse, + }; + } catch (e) { + // If the `fetchTokenBalance` call failed, `details` remains undefined, and we + // fall back to the below `assetsContractController.getTokenStandardAndDetails` call + log.warn('Failed to get token balance. Error:', e); + } } } @@ -4656,12 +4676,11 @@ export default class MetamaskController extends EventEmitter { try { // Scan accounts until we find an empty one const chainId = this.#getGlobalChainId(); - const ethQuery = new EthQuery(this.provider); const accounts = await this.keyringController.getAccounts(); let address = accounts[accounts.length - 1]; for (let count = accounts.length; ; count++) { - const balance = await this.getBalance(address, ethQuery); + const balance = await this.getBalance(address, this.provider); if (balance === '0x0') { // This account has no balance, so check for tokens @@ -4731,25 +4750,25 @@ export default class MetamaskController extends EventEmitter { * Get an account balance from the AccountTrackerController or request it directly from the network. * * @param {string} address - The account address - * @param {EthQuery} ethQuery - The EthQuery instance to use when asking the network + * @param {Provider} provider - The provider instance to use when asking the network */ - getBalance(address, ethQuery) { - return new Promise((resolve, reject) => { - const cached = this.accountTrackerController.state.accounts[address]; + async getBalance(address, provider) { + const cached = this.accountTrackerController.state.accounts[address]; - if (cached && cached.balance) { - resolve(cached.balance); - } else { - ethQuery.getBalance(address, (error, balance) => { - if (error) { - reject(error); - log.error(error); - } else { - resolve(balance || '0x0'); - } - }); - } - }); + if (cached && cached.balance) { + return cached.balance; + } + + try { + const balance = await provider.request({ + method: 'eth_getBalance', + params: [address, 'latest'], + }); + return balance || '0x0'; + } catch (error) { + log.error(error); + throw error; + } } /** @@ -5405,16 +5424,13 @@ export default class MetamaskController extends EventEmitter { async estimateGas(estimateGasParams) { return new Promise((resolve, reject) => { - return new EthJSQuery(this.provider).estimateGas( - estimateGasParams, - (err, res) => { - if (err) { - return reject(err); - } - - return resolve(res.toString(16)); - }, - ); + this.provider + .request({ + method: 'eth_estimateGas', + params: [estimateGasParams], + }) + .then((result) => resolve(result.toString(16))) + .catch((err) => reject(err)); }); } @@ -5469,14 +5485,6 @@ export default class MetamaskController extends EventEmitter { this.sendUpdate(); } - //============================================================================= - // REQUEST QUEUE - //============================================================================= - - setUseRequestQueue(value) { - this.preferencesController.setUseRequestQueue(value); - } - //============================================================================= // SETUP //============================================================================= @@ -5969,12 +5977,12 @@ export default class MetamaskController extends EventEmitter { enqueueRequest: this.queuedRequestController.enqueueRequest.bind( this.queuedRequestController, ), - useRequestQueue: this.preferencesController.getUseRequestQueue.bind( - this.preferencesController, - ), shouldEnqueueRequest: (request) => { return methodsThatShouldBeEnqueued.includes(request.method); }, + // This will be removed once we can actually remove useRequestQueue state + // i.e. unrevert https://github.com/MetaMask/core/pull/5065 + useRequestQueue: () => true, }); engine.push(requestQueueMiddleware); @@ -6272,6 +6280,11 @@ export default class MetamaskController extends EventEmitter { engine.push( createSnapsMethodMiddleware(subjectType === SubjectType.Snap, { + clearSnapState: this.controllerMessenger.call.bind( + this.controllerMessenger, + 'SnapController:clearSnapState', + origin, + ), getUnlockPromise: this.appStateController.getUnlockPromise.bind( this.appStateController, ), @@ -6294,6 +6307,16 @@ export default class MetamaskController extends EventEmitter { 'SnapController:getFile', origin, ), + getSnapState: this.controllerMessenger.call.bind( + this.controllerMessenger, + 'SnapController:getSnapState', + origin, + ), + updateSnapState: this.controllerMessenger.call.bind( + this.controllerMessenger, + 'SnapController:updateSnapState', + origin, + ), installSnaps: this.controllerMessenger.call.bind( this.controllerMessenger, 'SnapController:install', @@ -6355,11 +6378,26 @@ export default class MetamaskController extends EventEmitter { currency: fiatCurrency, }; }, - ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) hasPermission: this.permissionController.hasPermission.bind( this.permissionController, origin, ), + scheduleBackgroundEvent: (event) => + this.controllerMessenger.call( + 'CronjobController:scheduleBackgroundEvent', + { ...event, snapId: origin }, + ), + cancelBackgroundEvent: this.controllerMessenger.call.bind( + this.controllerMessenger, + 'CronjobController:cancelBackgroundEvent', + origin, + ), + getBackgroundEvents: this.controllerMessenger.call.bind( + this.controllerMessenger, + 'CronjobController:getBackgroundEvents', + origin, + ), + ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) handleSnapRpcRequest: (args) => this.handleSnapRequest({ ...args, origin }), getAllowedKeyringMethods: keyringSnapPermissionsBuilder( @@ -6675,11 +6713,6 @@ export default class MetamaskController extends EventEmitter { .redesignedConfirmationsEnabled; } - isTransactionsRedesignEnabled() { - return this.preferencesController.state.preferences - .redesignedTransactionsEnabled; - } - isConfirmationRedesignDeveloperEnabled() { return this.preferencesController.state.preferences .isRedesignedConfirmationsDeveloperEnabled; @@ -6871,8 +6904,6 @@ export default class MetamaskController extends EventEmitter { }, getRedesignedConfirmationsEnabled: this.isConfirmationRedesignEnabled.bind(this), - getRedesignedTransactionsEnabled: - this.isTransactionsRedesignEnabled.bind(this), getMethodData: (data) => { if (!data) { return null; @@ -7206,31 +7237,17 @@ export default class MetamaskController extends EventEmitter { } async _notifyChainChange() { - if (this.preferencesController.getUseRequestQueue()) { - this.notifyAllConnections(async (origin) => ({ - method: NOTIFICATION_NAMES.chainChanged, - params: await this.getProviderNetworkState(origin), - })); - } else { - this.notifyAllConnections({ - method: NOTIFICATION_NAMES.chainChanged, - params: await this.getProviderNetworkState(), - }); - } + this.notifyAllConnections(async (origin) => ({ + method: NOTIFICATION_NAMES.chainChanged, + params: await this.getProviderNetworkState(origin), + })); } async _notifyChainChangeForConnection(connection, origin) { - if (this.preferencesController.getUseRequestQueue()) { - this.notifyConnection(connection, { - method: NOTIFICATION_NAMES.chainChanged, - params: await this.getProviderNetworkState(origin), - }); - } else { - this.notifyConnection(connection, { - method: NOTIFICATION_NAMES.chainChanged, - params: await this.getProviderNetworkState(), - }); - } + this.notifyConnection(connection, { + method: NOTIFICATION_NAMES.chainChanged, + params: await this.getProviderNetworkState(origin), + }); } async _onFinishedTransaction(transactionMeta) { diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 47a9050232fd..8429dd3d175d 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -4,7 +4,6 @@ import { cloneDeep } from 'lodash'; import nock from 'nock'; import { obj as createThroughStream } from 'through2'; -import EthQuery from '@metamask/eth-query'; import { wordlist as englishWordlist } from '@metamask/scure-bip39/dist/wordlists/english'; import { ListNames, @@ -780,9 +779,10 @@ describe('MetaMaskController', () => { it('should ask the network for a balance when not known by accountTrackerController', async () => { const accounts = {}; const balance = '0x14ced5122ce0a000'; - const ethQuery = new EthQuery(); - jest.spyOn(ethQuery, 'getBalance').mockImplementation((_, callback) => { - callback(undefined, balance); + const { provider } = createTestProviderTools({ + scaffold: { + eth_getBalance: balance, + }, }); jest @@ -793,7 +793,7 @@ describe('MetaMaskController', () => { const gotten = await metamaskController.getBalance( TEST_ADDRESS, - ethQuery, + provider, ); expect(balance).toStrictEqual(gotten); diff --git a/app/scripts/migrations/105.test.ts b/app/scripts/migrations/105.test.ts index 168fe8dd0916..b7d5ac0303e6 100644 --- a/app/scripts/migrations/105.test.ts +++ b/app/scripts/migrations/105.test.ts @@ -1,6 +1,6 @@ import { v4 as uuid } from 'uuid'; import { sha256FromString } from 'ethereumjs-util'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { ETH_EOA_METHODS } from '../../../shared/constants/eth-methods'; import { migrate } from './105'; diff --git a/app/scripts/migrations/105.ts b/app/scripts/migrations/105.ts index a54b3e6457a7..5febcb0479f2 100644 --- a/app/scripts/migrations/105.ts +++ b/app/scripts/migrations/105.ts @@ -1,4 +1,5 @@ -import { EthAccountType, InternalAccount } from '@metamask/keyring-api'; +import { EthAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { sha256FromString } from 'ethereumjs-util'; import { v4 as uuid } from 'uuid'; import { cloneDeep } from 'lodash'; diff --git a/app/scripts/migrations/119.ts b/app/scripts/migrations/119.ts index 8cb0d2c04b97..606a9e38a31d 100644 --- a/app/scripts/migrations/119.ts +++ b/app/scripts/migrations/119.ts @@ -1,7 +1,7 @@ import { cloneDeep, isObject } from 'lodash'; import { hasProperty } from '@metamask/utils'; import { AccountsControllerState } from '@metamask/accounts-controller'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; type VersionedData = { meta: { version: number }; diff --git a/app/scripts/migrations/134.1.test.ts b/app/scripts/migrations/134.1.test.ts index 9f251a1f2a54..c0f09a622e37 100644 --- a/app/scripts/migrations/134.1.test.ts +++ b/app/scripts/migrations/134.1.test.ts @@ -1,3 +1,4 @@ +import { NetworkConfiguration } from '@metamask/network-controller'; import { migrate, version } from './134.1'; describe(`Migration ${version}`, () => { @@ -40,7 +41,6 @@ describe(`Migration ${version}`, () => { }; const result = await migrate(originalState); - expect(sentryCaptureExceptionMock).toHaveBeenCalled(); expect(result.data).toEqual(originalState.data); expect(result.meta.version).toBe(134.1); }); @@ -241,7 +241,6 @@ describe(`Migration ${version}`, () => { }; const result = await migrate(originalState); - expect(sentryCaptureExceptionMock).toHaveBeenCalled(); expect(result.data).toEqual(originalState.data); }); @@ -274,4 +273,131 @@ describe(`Migration ${version}`, () => { expect(sentryCaptureExceptionMock).toHaveBeenCalled(); expect(result.data).toEqual(originalState.data); }); + + it('updates TokensController.tokens when all data is valid', async () => { + const originalTokens = [{ address: '0xtokenA' }, { address: '0xtokenB' }]; + const originalState = { + meta: { version: 0 }, + data: { + AccountsController: { + internalAccounts: { + selectedAccount: 'id1', + accounts: { id1: { address: '0x123' } }, + }, + }, + NetworkController: { + selectedNetworkClientId: 'mainnet', + networkConfigurationsByChainId: { + '0x1': { + rpcEndpoints: [{ networkClientId: 'mainnet' }], + }, + }, + }, + TokensController: { + allTokens: { + '0x1': { + '0x123': originalTokens, + }, + }, + tokens: [{ address: '0xOLD' }], + }, + }, + }; + + const result = await migrate(originalState); + + expect(sentryCaptureExceptionMock).not.toHaveBeenCalled(); + + const tokensControllerState = result.data.TokensController as Record< + string, + NetworkConfiguration + >; + expect(tokensControllerState.tokens).toEqual(originalTokens); + + expect(result.meta.version).toBe(134.1); + }); + + it('returns original state and logs error if tokens is not empty but allTokensForChain is not an object', async () => { + const originalState = { + meta: { version: 0 }, + data: { + AccountsController: { + internalAccounts: { + selectedAccount: 'id1', + accounts: { id1: { address: '0x123' } }, + }, + }, + NetworkController: { + selectedNetworkClientId: 'mainnet', + networkConfigurationsByChainId: { + '0x1': { + rpcEndpoints: [{ networkClientId: 'mainnet' }], + }, + }, + }, + TokensController: { + tokens: [{ address: '0xtokenA' }], // Non-empty tokens array + allTokens: { + '0x1': null, // allTokensForChain is not an object + }, + }, + }, + }; + + const result = await migrate(originalState); + + expect(sentryCaptureExceptionMock).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + `Migration ${version}: tokens is not an empty array, but allTokensForChain is not an object.`, + ), + }), + ); + + expect(result.data).toEqual(originalState.data); + }); + + it('returns original state and logs error if tokens is not empty but allTokensForChain is not an object', async () => { + const originalState = { + meta: { version: 0 }, + data: { + AccountsController: { + internalAccounts: { + selectedAccount: 'id1', + accounts: { + id1: { + address: '0x123', + }, + }, + }, + }, + NetworkController: { + selectedNetworkClientId: 'mainnet', + networkConfigurationsByChainId: { + '0x1': { + rpcEndpoints: [{ networkClientId: 'mainnet' }], + }, + }, + }, + TokensController: { + tokens: [{ address: '0xtokenA' }], // Non-empty tokens array + allTokens: { + '0x1': null, // allTokensForChain is not an object + }, + }, + }, + }; + + const result = await migrate(originalState); + + expect(sentryCaptureExceptionMock).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + `Migration ${version}: tokens is not an empty array, but allTokensForChain is not an object.`, + ), + }), + ); + + expect(result.data).toEqual(originalState.data); + }); }); diff --git a/app/scripts/migrations/134.1.ts b/app/scripts/migrations/134.1.ts index 95c405971bfb..fe2e619da9c9 100644 --- a/app/scripts/migrations/134.1.ts +++ b/app/scripts/migrations/134.1.ts @@ -208,17 +208,27 @@ function transformState( return state; } + const { tokens } = tokensControllerState; const { allTokens } = tokensControllerState; const allTokensForChain = allTokens[currentChainId]; - if (!isObject(allTokensForChain)) { + + if ( + Array.isArray(tokens) && + tokens.length > 0 && + !isObject(allTokensForChain) + ) { global.sentry?.captureException?.( new Error( - `Migration ${version}: allTokens["${currentChainId}"] is missing or not an object.`, + `Migration ${version}: tokens is not an empty array, but allTokensForChain is not an object.`, ), ); return state; } + if (!isObject(allTokensForChain)) { + return state; + } + const accountTokens = allTokensForChain[selectedAccountAddress]; if (!Array.isArray(accountTokens)) { global.sentry?.captureException?.( diff --git a/app/scripts/migrations/135.test.ts b/app/scripts/migrations/135.test.ts new file mode 100644 index 000000000000..06e78a7d6238 --- /dev/null +++ b/app/scripts/migrations/135.test.ts @@ -0,0 +1,210 @@ +import { SmartTransaction } from '@metamask/smart-transactions-controller/dist/types'; +import { migrate, VersionedData } from './135'; + +const prevVersion = 134; + +describe('migration #135', () => { + const mockSmartTransaction: SmartTransaction = { + uuid: 'test-uuid', + }; + + it('should update the version metadata', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: {}, + }; + + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ version: 135 }); + }); + + it('should preserve existing state when opt-in status is null (default-enabled from previous versions)', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: null, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(null); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(false); + }); + + it('should preserve existing state when opt-in status is null (default-enabled from previous versions)', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: null, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(null); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(false); + }); + + it('should set stx opt-in to true and mark as migration-enabled when opt-in status is undefined', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: {}, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(true); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(true); + }); + + it('should set stx opt-in to true and mark as migration-enabled when opt-in is false and no existing mainnet transactions', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: false, + }, + }, + SmartTransactionsController: { + smartTransactionsState: { + smartTransactions: { + '0x1': [], // Empty mainnet transactions + '0xAA36A7': [mockSmartTransaction], // Sepolia has transactions + }, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(true); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(true); + }); + + it('should preserve disabled stx state when user has transaction history', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: false, + }, + }, + SmartTransactionsController: { + smartTransactionsState: { + smartTransactions: { + '0x1': [mockSmartTransaction], + }, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(false); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(false); + }); + + it('should preserve existing stx enabled state', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: true, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsOptInStatus, + ).toBe(true); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(false); + }); + + it('should initialize preferences object if it does not exist', async () => { + const oldStorage: VersionedData = { + meta: { version: prevVersion }, + data: { + PreferencesController: { + preferences: { + smartTransactionsOptInStatus: true, + }, + }, + }, + }; + + const newStorage = await migrate(oldStorage); + expect(newStorage.data.PreferencesController?.preferences).toBeDefined(); + expect( + newStorage.data.PreferencesController?.preferences + ?.smartTransactionsMigrationApplied, + ).toBe(false); + }); + + it('should capture exception if PreferencesController state is invalid', async () => { + const sentryCaptureExceptionMock = jest.fn(); + global.sentry = { + captureException: sentryCaptureExceptionMock, + }; + + const oldStorage = { + meta: { version: prevVersion }, + data: { + PreferencesController: 'invalid', + }, + } as unknown as VersionedData; + + await migrate(oldStorage); + + expect(sentryCaptureExceptionMock).toHaveBeenCalledTimes(1); + expect(sentryCaptureExceptionMock).toHaveBeenCalledWith( + new Error('Invalid PreferencesController state: string'), + ); + }); +}); diff --git a/app/scripts/migrations/135.ts b/app/scripts/migrations/135.ts new file mode 100644 index 000000000000..1f6d00b5e869 --- /dev/null +++ b/app/scripts/migrations/135.ts @@ -0,0 +1,82 @@ +import { hasProperty, isObject } from '@metamask/utils'; +import { cloneDeep } from 'lodash'; +import type { SmartTransaction } from '@metamask/smart-transactions-controller/dist/types'; +import { CHAIN_IDS } from '@metamask/transaction-controller'; + +export type VersionedData = { + meta: { + version: number; + }; + data: { + PreferencesController?: { + preferences?: { + smartTransactionsOptInStatus?: boolean | null; + smartTransactionsMigrationApplied?: boolean; + }; + }; + SmartTransactionsController?: { + smartTransactionsState: { + smartTransactions: Record; + }; + }; + }; +}; + +export const version = 135; + +function transformState(state: VersionedData['data']) { + if ( + !hasProperty(state, 'PreferencesController') || + !isObject(state.PreferencesController) + ) { + global.sentry?.captureException?.( + new Error( + `Invalid PreferencesController state: ${typeof state.PreferencesController}`, + ), + ); + return state; + } + + const { PreferencesController } = state; + const currentOptInStatus = + PreferencesController.preferences?.smartTransactionsOptInStatus; + + if ( + currentOptInStatus === undefined || + (currentOptInStatus === false && !hasExistingSmartTransactions(state)) + ) { + state.PreferencesController.preferences = { + ...state.PreferencesController.preferences, + smartTransactionsOptInStatus: true, + smartTransactionsMigrationApplied: true, + }; + } else { + state.PreferencesController.preferences = { + ...state.PreferencesController.preferences, + smartTransactionsMigrationApplied: false, // Always set it, but false for existing users + }; + } + + return state; +} + +function hasExistingSmartTransactions(state: VersionedData['data']): boolean { + const smartTransactions = + state?.SmartTransactionsController?.smartTransactionsState + ?.smartTransactions; + + if (!isObject(smartTransactions)) { + return false; + } + + return (smartTransactions[CHAIN_IDS.MAINNET] || []).length > 0; +} + +export async function migrate( + originalVersionedData: VersionedData, +): Promise { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + transformState(versionedData.data); + return versionedData; +} diff --git a/app/scripts/migrations/136.test.ts b/app/scripts/migrations/136.test.ts new file mode 100644 index 000000000000..01fc9d49d69f --- /dev/null +++ b/app/scripts/migrations/136.test.ts @@ -0,0 +1,56 @@ +import { migrate, version } from './136'; + +const oldVersion = 135; + +describe(`migration #${version}`, () => { + it('updates the version metadata', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: {}, + }; + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ version }); + }); + describe(`migration #${version}`, () => { + it('removes the useRequestQueue preference', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: { + PreferencesController: { + useRequestQueue: true, + otherPreference: true, + }, + }, + }; + const expectedData = { + PreferencesController: { + otherPreference: true, + }, + }; + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + + it('does nothing to other PreferencesController state if there is a useRequestQueue preference', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: { + PreferencesController: { + existingPreference: true, + }, + }, + }; + + const expectedData = { + PreferencesController: { + existingPreference: true, + }, + }; + + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + }); +}); diff --git a/app/scripts/migrations/136.ts b/app/scripts/migrations/136.ts new file mode 100644 index 000000000000..3f6bfc661292 --- /dev/null +++ b/app/scripts/migrations/136.ts @@ -0,0 +1,37 @@ +import { hasProperty, isObject } from '@metamask/utils'; +import { cloneDeep } from 'lodash'; + +type VersionedData = { + meta: { version: number }; + data: Record; +}; +export const version = 136; +/** + * This migration removes the useRequestQueue preference from the user's preferences + * + * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. + * @param originalVersionedData.meta - State metadata. + * @param originalVersionedData.meta.version - The current state version. + * @param originalVersionedData.data - The persisted MetaMask state, keyed by controller. + * @returns Updated versioned MetaMask extension state. + */ +export async function migrate( + originalVersionedData: VersionedData, +): Promise { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + transformState(versionedData.data); + return versionedData; +} +function transformState( + state: Record, +): Record { + if ( + hasProperty(state, 'PreferencesController') && + isObject(state.PreferencesController) && + hasProperty(state.PreferencesController, 'useRequestQueue') + ) { + delete state.PreferencesController.useRequestQueue; + } + return state; +} diff --git a/app/scripts/migrations/137.test.ts b/app/scripts/migrations/137.test.ts new file mode 100644 index 000000000000..20e7fec205cb --- /dev/null +++ b/app/scripts/migrations/137.test.ts @@ -0,0 +1,66 @@ +import { migrate, version, VersionedData } from './137'; + +const oldVersion = 136; + +describe(`migration #${version}`, () => { + it('updates the version metadata', async () => { + const oldStorage: VersionedData = { + meta: { version: oldVersion }, + data: {}, + }; + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ version }); + }); + + describe(`migration #${version}`, () => { + it('sets isAccountSyncingReadyToBeDispatched to true if completedOnboarding is true', async () => { + const oldStorage: VersionedData = { + meta: { version: oldVersion }, + data: { + OnboardingController: { + completedOnboarding: true, + }, + UserStorageController: { + isAccountSyncingReadyToBeDispatched: false, + }, + }, + }; + const expectedData = { + OnboardingController: { + completedOnboarding: true, + }, + UserStorageController: { + isAccountSyncingReadyToBeDispatched: true, + }, + }; + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + + it('sets isAccountSyncingReadyToBeDispatched to false if completedOnboarding is false', async () => { + const oldStorage: VersionedData = { + meta: { version: oldVersion }, + data: { + OnboardingController: { + completedOnboarding: false, + }, + UserStorageController: { + isAccountSyncingReadyToBeDispatched: true, + }, + }, + }; + const expectedData = { + OnboardingController: { + completedOnboarding: false, + }, + UserStorageController: { + isAccountSyncingReadyToBeDispatched: false, + }, + }; + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + }); +}); diff --git a/app/scripts/migrations/137.ts b/app/scripts/migrations/137.ts new file mode 100644 index 000000000000..2e45bd6db502 --- /dev/null +++ b/app/scripts/migrations/137.ts @@ -0,0 +1,75 @@ +import { hasProperty, isObject } from '@metamask/utils'; +import { cloneDeep } from 'lodash'; + +export type VersionedData = { + meta: { + version: number; + }; + data: { + OnboardingController?: { + completedOnboarding?: boolean; + }; + UserStorageController?: { + isAccountSyncingReadyToBeDispatched?: boolean; + }; + }; +}; + +export const version = 137; + +function transformState(state: VersionedData['data']) { + if ( + !hasProperty(state, 'OnboardingController') || + !isObject(state.OnboardingController) + ) { + global.sentry?.captureException?.( + new Error( + `Invalid OnboardingController state: ${typeof state.OnboardingController}`, + ), + ); + return state; + } + + if ( + !hasProperty(state, 'UserStorageController') || + !isObject(state.UserStorageController) + ) { + global.sentry?.captureException?.( + new Error( + `Invalid UserStorageController state: ${typeof state.UserStorageController}`, + ), + ); + return state; + } + + const { OnboardingController } = state; + + const currentCompletedOnboardingStatus = + OnboardingController.completedOnboarding; + + if (currentCompletedOnboardingStatus) { + state.UserStorageController.isAccountSyncingReadyToBeDispatched = true; + } else { + state.UserStorageController.isAccountSyncingReadyToBeDispatched = false; + } + + return state; +} + +/** + * This migration sets isAccountSyncingReadyToBeDispatched to true if completedOnboarding is true + * + * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. + * @param originalVersionedData.meta - State metadata. + * @param originalVersionedData.meta.version - The current state version. + * @param originalVersionedData.data - The persisted MetaMask state, keyed by controller. + * @returns Updated versioned MetaMask extension state. + */ +export async function migrate( + originalVersionedData: VersionedData, +): Promise { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + transformState(versionedData.data); + return versionedData; +} diff --git a/app/scripts/migrations/138.test.ts b/app/scripts/migrations/138.test.ts new file mode 100644 index 000000000000..1084d6b08136 --- /dev/null +++ b/app/scripts/migrations/138.test.ts @@ -0,0 +1,79 @@ +import { migrate, version } from './138'; + +const oldVersion = 137; + +describe(`migration #${version}`, () => { + it('updates the version metadata', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: {}, + }; + const newStorage = await migrate(oldStorage); + expect(newStorage.meta).toStrictEqual({ version }); + }); + + describe(`migration #${version}`, () => { + it('removes the redesignedTransactionsEnabled preference if it is set to true', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: { + PreferencesController: { + preferences: { + redesignedTransactionsEnabled: true, + }, + }, + }, + }; + const expectedData = { + PreferencesController: { + preferences: {}, + }, + }; + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + + it('removes the redesignedTransactionsEnabled preference if it is set to false', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: { + PreferencesController: { + preferences: { + redesignedTransactionsEnabled: false, + }, + }, + }, + }; + const expectedData = { + PreferencesController: { + preferences: {}, + }, + }; + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + + it('does nothing to other PreferencesController state if there is not a redesignedTransactionsEnabled preference', async () => { + const oldStorage = { + meta: { version: oldVersion }, + data: { + PreferencesController: { + existingPreference: true, + }, + }, + }; + + const expectedData = { + PreferencesController: { + existingPreference: true, + }, + }; + + const newStorage = await migrate(oldStorage); + + expect(newStorage.data).toStrictEqual(expectedData); + }); + }); +}); diff --git a/app/scripts/migrations/138.ts b/app/scripts/migrations/138.ts new file mode 100644 index 000000000000..a4a51348bffc --- /dev/null +++ b/app/scripts/migrations/138.ts @@ -0,0 +1,47 @@ +import { hasProperty } from '@metamask/utils'; +import { cloneDeep } from 'lodash'; + +type VersionedData = { + meta: { version: number }; + data: Record; +}; + +export const version = 138; + +/** + * This migration deletes the preference `redesignedTransactionsEnabled` if the + * user has existing data. + * + * @param originalVersionedData - Versioned MetaMask extension state, exactly + * what we persist to dist. + * @param originalVersionedData.meta - State metadata. + * @param originalVersionedData.meta.version - The current state version. + * @param originalVersionedData.data - The persisted MetaMask state, keyed by + * controller. + * @returns Updated versioned MetaMask extension state. + */ +export async function migrate( + originalVersionedData: VersionedData, +): Promise { + const versionedData = cloneDeep(originalVersionedData); + versionedData.meta.version = version; + transformState(versionedData.data); + return versionedData; +} + +function transformState(state: Record) { + const preferencesControllerState = state?.PreferencesController as + | Record + | undefined; + + const preferences = preferencesControllerState?.preferences as + | Record + | undefined; + + if ( + preferences && + hasProperty(preferences, 'redesignedTransactionsEnabled') + ) { + delete preferences.redesignedTransactionsEnabled; + } +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index a5c587249994..219c7ff55c36 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -159,6 +159,10 @@ const migrations = [ require('./133.2'), require('./134'), require('./134.1'), + require('./135'), + require('./136'), + require('./137'), + require('./138'), ]; export default migrations; diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 794037e12761..ea3b6b3f1254 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -11,8 +11,6 @@ import 'react-devtools'; import PortStream from 'extension-port-stream'; import browser from 'webextension-polyfill'; -import Eth from '@metamask/ethjs'; -import EthQuery from '@metamask/eth-query'; import StreamProvider from 'web3-stream-provider'; import log from 'loglevel'; // TODO: Remove restricted import @@ -362,8 +360,6 @@ function setupWeb3Connection(connectionStream) { connectionStream.on('error', console.error.bind(console)); providerStream.on('error', console.error.bind(console)); global.ethereumProvider = providerStream; - global.ethQuery = new EthQuery(providerStream); - global.eth = new Eth(providerStream); } /** diff --git a/attribution.txt b/attribution.txt index be40c797bf2c..f1eede4f12f9 100644 --- a/attribution.txt +++ b/attribution.txt @@ -420,21 +420,6 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -ansi-styles -3.2.1 -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ****************************** ansi-styles @@ -719,7 +704,7 @@ PERFORMANCE OF THIS SOFTWARE. ****************************** @babel/code-frame -7.25.9 +7.26.2 MIT License Copyright (c) 2014-present Sebastian McKenzie and other contributors @@ -1248,38 +1233,10 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -@babel/highlight -7.25.9 -MIT License - -Copyright (c) 2014-present Sebastian McKenzie and other contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ****************************** @babel/parser -7.25.9 +7.26.2 Copyright (C) 2012-2014 by various contributors (see AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy @@ -1528,7 +1485,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************** @babel/types -7.26.0 +7.26.3 MIT License Copyright (c) 2014-present Sebastian McKenzie and other contributors @@ -3930,21 +3887,6 @@ You may obtain a copy of the License at -****************************** - -chalk -2.4.2 -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ****************************** chalk @@ -4710,8 +4652,196 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************** crc-32 -1.2.0 -Copyright (C) 2014-present SheetJS +1.2.2 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (C) 2014-present SheetJS LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -4726,7 +4856,6 @@ Copyright (C) 2014-present SheetJS limitations under the License. - ****************************** create-hash @@ -5783,7 +5912,7 @@ SOFTWARE. ****************************** @endo/env-options -1.1.0 +1.1.8 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -6084,33 +6213,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -escape-string-regexp -1.0.5 -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ****************************** es-define-property @@ -9802,33 +9904,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -ethers -5.7.2 -MIT License - -Copyright (c) 2019 Richard Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ****************************** ethers @@ -10165,61 +10240,7 @@ SOFTWARE. ****************************** -@ethersproject/hdnode -5.7.0 -MIT License - -Copyright (c) 2019 Richard Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -****************************** - -@ethersproject/json-wallets -5.7.0 -MIT License - -Copyright (c) 2019 Richard Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -****************************** - -@ethersproject/keccak256 +@ethersproject/hdnode 5.7.0 MIT License @@ -10246,15 +10267,8 @@ SOFTWARE. ****************************** -@ethersproject/logger +@ethersproject/json-wallets 5.7.0 -license: MIT -authors: Richard Moore - -****************************** - -@ethersproject/networks -5.7.1 MIT License Copyright (c) 2019 Richard Moore @@ -10280,7 +10294,7 @@ SOFTWARE. ****************************** -@ethersproject/pbkdf2 +@ethersproject/keccak256 5.7.0 MIT License @@ -10307,8 +10321,15 @@ SOFTWARE. ****************************** -@ethersproject/properties +@ethersproject/logger 5.7.0 +license: MIT +authors: Richard Moore + +****************************** + +@ethersproject/networks +5.7.1 MIT License Copyright (c) 2019 Richard Moore @@ -10334,8 +10355,8 @@ SOFTWARE. ****************************** -@ethersproject/providers -5.7.2 +@ethersproject/pbkdf2 +5.7.0 MIT License Copyright (c) 2019 Richard Moore @@ -10361,7 +10382,7 @@ SOFTWARE. ****************************** -@ethersproject/random +@ethersproject/properties 5.7.0 MIT License @@ -10388,8 +10409,8 @@ SOFTWARE. ****************************** -@ethersproject/rlp -5.7.0 +@ethersproject/providers +5.7.2 MIT License Copyright (c) 2019 Richard Moore @@ -10415,7 +10436,7 @@ SOFTWARE. ****************************** -@ethersproject/sha2 +@ethersproject/random 5.7.0 MIT License @@ -10442,7 +10463,7 @@ SOFTWARE. ****************************** -@ethersproject/signing-key +@ethersproject/rlp 5.7.0 MIT License @@ -10469,7 +10490,7 @@ SOFTWARE. ****************************** -@ethersproject/solidity +@ethersproject/sha2 5.7.0 MIT License @@ -10496,7 +10517,7 @@ SOFTWARE. ****************************** -@ethersproject/strings +@ethersproject/signing-key 5.7.0 MIT License @@ -10523,7 +10544,7 @@ SOFTWARE. ****************************** -@ethersproject/transactions +@ethersproject/strings 5.7.0 MIT License @@ -10550,7 +10571,7 @@ SOFTWARE. ****************************** -@ethersproject/units +@ethersproject/transactions 5.7.0 MIT License @@ -10868,25 +10889,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -exit-on-epipe -1.0.1 -Copyright (C) 2015-present SheetJS - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ****************************** extend @@ -12661,21 +12663,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -has-flag -3.0.0 -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ****************************** has-flag @@ -15913,7 +15900,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ****************************** @ledgerhq/cryptoassets-evm-signatures -13.5.0 +13.5.2 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -15967,7 +15954,7 @@ THE SOFTWARE. ****************************** @ledgerhq/domain-service -1.2.6 +1.2.15 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -16021,7 +16008,7 @@ THE SOFTWARE. ****************************** @ledgerhq/evm-tools -1.2.3 +1.3.0 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -16048,7 +16035,7 @@ THE SOFTWARE. ****************************** @ledgerhq/hw-app-eth -6.39.0 +6.42.2 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -16129,7 +16116,7 @@ THE SOFTWARE. ****************************** @ledgerhq/live-env -2.3.0 +2.4.1 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -16163,7 +16150,7 @@ authors: undefined ****************************** @ledgerhq/types-live -6.52.0 +6.56.0 The MIT License Copyright (c) 2017-present Ledger https://www.ledger.com/ @@ -17093,7 +17080,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** luxon -3.2.1 +3.5.0 Copyright 2019 JS Foundation and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -17500,8 +17487,15 @@ authors: Maarten Zuidhoorn ****************************** +@metamask/abi-utils +3.0.0 +license: (Apache-2.0 AND MIT) +authors: Maarten Zuidhoorn + +****************************** + @metamask/accounts-controller -20.0.0 +20.0.2 MIT License Copyright (c) 2018 MetaMask @@ -17786,7 +17780,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/approval-controller -7.1.1 +7.1.2 MIT License Copyright (c) 2018 MetaMask @@ -17864,7 +17858,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/base-controller -7.0.2 +7.1.1 MIT License Copyright (c) 2018 MetaMask @@ -17939,7 +17933,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/controller-utils -11.4.4 +11.4.5 MIT License Copyright (c) 2018 MetaMask @@ -18250,7 +18244,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/eth-block-tracker -11.0.3 +11.0.4 MIT License Copyright (c) 2018 MetaMask @@ -18315,33 +18309,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -****************************** - -@metamask/ethjs -0.6.0 -The MIT License - -Copyright (c) 2016 Nick Dodson. nickdodson.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ****************************** @metamask/ethjs-contract @@ -18468,7 +18435,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/eth-json-rpc-middleware -15.0.1 +15.1.2 ISC License Copyright (c) 2020 MetaMask @@ -18489,7 +18456,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/eth-json-rpc-provider -4.1.6 +4.1.7 ISC License Copyright (c) 2022 MetaMask @@ -18507,33 +18474,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -****************************** - -@metamask/ethjs-provider-http -0.3.0 -The MIT License - -Copyright (c) 2016 Nick Dodson. nickdodson.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ****************************** @metamask/ethjs-query @@ -18645,7 +18585,7 @@ THE SOFTWARE. ****************************** @metamask/eth-ledger-bridge-keyring -5.0.1 +8.0.3 ISC License Copyright (c) 2020 MetaMask @@ -18694,7 +18634,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/eth-sig-util -8.0.0 +8.1.2 ISC License Copyright (c) 2020 MetaMask @@ -18736,7 +18676,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/eth-snap-keyring -5.0.1 +7.0.0 Copyright ConsenSys Software Inc. 2022. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -18781,7 +18721,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/eth-trezor-keyring -3.1.3 +6.0.0 ISC License Copyright (c) 2020 MetaMask @@ -19236,7 +19176,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/keyring-api -10.1.0 +12.0.0 Copyright ConsenSys Software Inc. 2022. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -19260,7 +19200,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/keyring-api -12.0.0 +13.0.0 Copyright ConsenSys Software Inc. 2022. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -19284,7 +19224,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/keyring-controller -19.0.2 +19.0.3 MIT License Copyright (c) 2018 MetaMask @@ -19316,6 +19256,27 @@ authors: undefined ****************************** +@metamask/keyring-internal-api +2.0.0 +license: Custom: https://github.com/MetaMask/accounts +authors: undefined + +****************************** + +@metamask/keyring-internal-snap-client +1.0.0 +license: Custom: https://github.com/MetaMask/accounts +authors: undefined + +****************************** + +@metamask/keyring-snap-client +1.0.0 +license: Custom: https://github.com/MetaMask/accounts +authors: undefined + +****************************** + @metamask/keyring-utils 1.0.0 license: Custom: https://github.com/MetaMask/accounts @@ -19324,7 +19285,7 @@ authors: undefined ****************************** @metamask/key-tree -10.0.1 +10.0.2 MIT License Copyright (c) 2021 MetaMask @@ -19476,7 +19437,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/network-controller -22.1.0 +22.1.1 MIT License Copyright (c) 2018 MetaMask @@ -19582,7 +19543,7 @@ THE SOFTWARE. ****************************** @metamask/object-multiplex -2.0.0 +2.1.0 ISC License Copyright (c) 2020 MetaMask @@ -19624,7 +19585,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/permission-controller -11.0.3 +11.0.5 MIT License Copyright (c) 2018 MetaMask @@ -19674,7 +19635,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/phishing-controller -12.3.0 +12.3.1 MIT License Copyright (c) 2018 MetaMask @@ -19700,7 +19661,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/polling-controller -12.0.1 +12.0.2 MIT License Copyright (c) 2018 MetaMask @@ -19726,7 +19687,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/post-message-stream -8.1.1 +9.0.0 ISC License Copyright (c) 2020 MetaMask @@ -19754,7 +19715,7 @@ authors: undefined ****************************** @metamask/preinstalled-example-snap -0.2.0 +0.3.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -19961,7 +19922,7 @@ authors: undefined ****************************** @metamask/profile-sync-controller -3.1.1 +4.1.0 MIT License Copyright (c) 2024 MetaMask @@ -19984,33 +19945,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -****************************** - -@metamask/providers -18.3.1 -MIT License - -Copyright (c) 2020 MetaMask - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ****************************** @metamask/providers @@ -20093,7 +20027,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/remote-feature-flag-controller -1.1.0 +1.3.0 This project is licensed under either of * MIT license ([LICENSE.MIT](LICENSE.MIT)) @@ -20265,7 +20199,7 @@ authors: Dan Finlay ****************************** @metamask/smart-transactions-controller -15.0.0 +16.0.1 Copyright ConsenSys Software Inc. 2020. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -20289,7 +20223,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/snaps-controllers -9.15.0 +9.17.0 Copyright ConsenSys Software Inc. 2021. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -20313,7 +20247,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/snaps-execution-environments -6.10.0 +6.12.0 Copyright ConsenSys Software Inc. 2022. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -20339,7 +20273,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/snaps-registry -3.2.2 +3.2.3 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -20546,7 +20480,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/snaps-rpc-methods -11.7.0 +11.9.1 Copyright ConsenSys Software Inc. 2021. All rights reserved. You acknowledge and agree that ConsenSys Software Inc. (“ConsenSys”) (or ConsenSys’s licensors) own all legal right, title and interest in and to the work, software, application, source code, documentation and any other documents in this repository (collectively, the “Program”), including any intellectual property rights which subsist in the Program (whether those rights happen to be registered or not, and wherever in the world those rights may exist), whether in source code or any other form. @@ -20570,7 +20504,7 @@ If you have any questions, comments or interest in pursuing any other use cases, ****************************** @metamask/snaps-sdk -6.13.0 +6.15.0 ISC License Copyright (c) 2023 MetaMask @@ -20591,7 +20525,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/snaps-utils -8.6.1 +8.8.0 ISC License Copyright (c) 2022 MetaMask @@ -20641,7 +20575,7 @@ authors: undefined ****************************** @metamask/transaction-controller -42.0.0 +42.1.0 MIT License Copyright (c) 2018 MetaMask @@ -20667,7 +20601,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ****************************** @metamask/user-operation-controller -19.0.0 +21.0.0 MIT License Copyright (c) 2023 MetaMask @@ -20714,7 +20648,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************** @metamask/utils -11.1.0 +11.0.1 ISC License Copyright (c) 2022 MetaMask @@ -21541,6 +21475,32 @@ THE SOFTWARE. ****************************** +@noble/hashes +1.5.0 +The MIT License (MIT) + +Copyright (c) 2022 Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +****************************** + @noble/secp256k1 1.6.3 The MIT License (MIT) @@ -21691,7 +21651,7 @@ SOFTWARE. ****************************** node-gyp-build -4.8.0 +4.8.4 The MIT License (MIT) Copyright (c) 2017 Mathias Buus @@ -22205,26 +22165,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -printj -1.1.2 -Copyright (C) 2016-present SheetJS - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - ****************************** process @@ -23755,7 +23695,7 @@ IN THE SOFTWARE. ****************************** readable-stream -4.4.2 +4.5.2 Node.js is licensed for use as follows: """ @@ -25707,7 +25647,7 @@ THE SOFTWARE. ****************************** @scure/base -1.1.7 +1.1.9 The MIT License (MIT) Copyright (c) 2022 Paul Miller (https://paulmillr.com) @@ -26157,7 +26097,7 @@ SOFTWARE. ****************************** ses -1.1.0 +1.9.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -27393,21 +27333,6 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -supports-color -5.5.0 -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ****************************** supports-color @@ -28643,7 +28568,7 @@ PERFORMANCE OF THIS SOFTWARE. ****************************** tslib -2.6.2 +2.6.3 Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any @@ -31118,31 +31043,6 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************** - -xhr2 -0.2.1 -Copyright (c) 2013 Victor Costan - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ****************************** xml diff --git a/builds.yml b/builds.yml index e8c7f5a28d93..2f5a287bba4d 100644 --- a/builds.yml +++ b/builds.yml @@ -27,7 +27,7 @@ buildTypes: - ALLOW_LOCAL_SNAPS: false - REQUIRE_SNAPS_ALLOWLIST: true - REJECT_INVALID_SNAPS_PLATFORM_VERSION: true - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.10.0/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.12.0/index.html - ACCOUNT_SNAPS_DIRECTORY_URL: https://snaps.metamask.io/account-management # Main build uses the default browser manifest manifestOverrides: false @@ -48,7 +48,7 @@ buildTypes: - ALLOW_LOCAL_SNAPS: false - REQUIRE_SNAPS_ALLOWLIST: true - REJECT_INVALID_SNAPS_PLATFORM_VERSION: true - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.10.0/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.12.0/index.html - ACCOUNT_SNAPS_DIRECTORY_URL: https://snaps.metamask.io/account-management # Modifies how the version is displayed. # eg. instead of 10.25.0 -> 10.25.0-beta.2 @@ -71,7 +71,7 @@ buildTypes: - ALLOW_LOCAL_SNAPS: true - REQUIRE_SNAPS_ALLOWLIST: false - REJECT_INVALID_SNAPS_PLATFORM_VERSION: false - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.10.0/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.12.0/index.html - SUPPORT_LINK: https://support.metamask.io/ - SUPPORT_REQUEST_LINK: https://support.metamask.io/ - INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID @@ -95,7 +95,7 @@ buildTypes: - ALLOW_LOCAL_SNAPS: false - REQUIRE_SNAPS_ALLOWLIST: true - REJECT_INVALID_SNAPS_PLATFORM_VERSION: true - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.10.0/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/iframe/6.12.0/index.html - MMI_CONFIGURATION_SERVICE_URL: https://configuration.metamask-institutional.io/v2/configuration/default - SUPPORT_LINK: https://support.metamask-institutional.io - SUPPORT_REQUEST_LINK: https://support.metamask-institutional.io @@ -214,13 +214,9 @@ env: # API keys to 3rd party services ### - - PUBNUB_PUB_KEY: null - - PUBNUB_SUB_KEY: null - SEGMENT_HOST: null - SENTRY_DSN: null - SENTRY_DSN_DEV: null - - OPENSEA_KEY: null - - ETHERSCAN_KEY: null # also INFURA_PROJECT_ID below ### @@ -318,3 +314,10 @@ env: # This should NEVER be enabled in production since it slows down react ### - ENABLE_WHY_DID_YOU_RENDER: false + + ### + # Unused environment variables referenced in dependencies + # Unset environment variables cause a build error. These are set to `null` to tell our build + # system that they are intentionally unset. + ### + - ETHERSCAN_KEY: null # Used by `gridplus-sdk/dist/util.js` diff --git a/development/charts/flamegraph/chart/index.html b/development/charts/flamegraph/chart/index.html deleted file mode 100644 index ce53076ad9e4..000000000000 --- a/development/charts/flamegraph/chart/index.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - Performance Measurements - - - - - -
-
- -

d3-flame-graph

-
-
-
-
-
- - - - - - - - - - - diff --git a/development/charts/flamegraph/lib/d3-flamegraph-tooltip.js b/development/charts/flamegraph/lib/d3-flamegraph-tooltip.js deleted file mode 100644 index cc042a0f281b..000000000000 --- a/development/charts/flamegraph/lib/d3-flamegraph-tooltip.js +++ /dev/null @@ -1,3117 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["flamegraph"] = factory(); - else - root["flamegraph"] = root["flamegraph"] || {}, root["flamegraph"]["tooltip"] = factory(); -})(self, function() { -return /******/ (() => { // webpackBootstrap -/******/ "use strict"; -/******/ // The require scope -/******/ var __webpack_require__ = {}; -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// ESM COMPAT FLAG -__webpack_require__.r(__webpack_exports__); - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "defaultFlamegraphTooltip": () => (/* binding */ defaultFlamegraphTooltip) -}); - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selector.js -function none() {} - -/* harmony default export */ function selector(selector) { - return selector == null ? none : function() { - return this.querySelector(selector); - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/select.js - - - -/* harmony default export */ function selection_select(select) { - if (typeof select !== "function") select = selector(select); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - } - } - } - - return new Selection(subgroups, this._parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/array.js -// Given something array like (or null), returns something that is strictly an -// array. This is used to ensure that array-like objects passed to d3.selectAll -// or selection.selectAll are converted into proper arrays when creating a -// selection; we don’t ever want to create a selection backed by a live -// HTMLCollection or NodeList. However, note that selection.selectAll will use a -// static NodeList as a group, since it safely derived from querySelectorAll. -function array(x) { - return x == null ? [] : Array.isArray(x) ? x : Array.from(x); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selectorAll.js -function empty() { - return []; -} - -/* harmony default export */ function selectorAll(selector) { - return selector == null ? empty : function() { - return this.querySelectorAll(selector); - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectAll.js - - - - -function arrayAll(select) { - return function() { - return array(select.apply(this, arguments)); - }; -} - -/* harmony default export */ function selectAll(select) { - if (typeof select === "function") select = arrayAll(select); - else select = selectorAll(select); - - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - subgroups.push(select.call(node, node.__data__, i, group)); - parents.push(node); - } - } - } - - return new Selection(subgroups, parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/matcher.js -/* harmony default export */ function matcher(selector) { - return function() { - return this.matches(selector); - }; -} - -function childMatcher(selector) { - return function(node) { - return node.matches(selector); - }; -} - - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectChild.js - - -var find = Array.prototype.find; - -function childFind(match) { - return function() { - return find.call(this.children, match); - }; -} - -function childFirst() { - return this.firstElementChild; -} - -/* harmony default export */ function selectChild(match) { - return this.select(match == null ? childFirst - : childFind(typeof match === "function" ? match : childMatcher(match))); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectChildren.js - - -var filter = Array.prototype.filter; - -function children() { - return Array.from(this.children); -} - -function childrenFilter(match) { - return function() { - return filter.call(this.children, match); - }; -} - -/* harmony default export */ function selectChildren(match) { - return this.selectAll(match == null ? children - : childrenFilter(typeof match === "function" ? match : childMatcher(match))); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/filter.js - - - -/* harmony default export */ function selection_filter(match) { - if (typeof match !== "function") match = matcher(match); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Selection(subgroups, this._parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/sparse.js -/* harmony default export */ function sparse(update) { - return new Array(update.length); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/enter.js - - - -/* harmony default export */ function enter() { - return new Selection(this._enter || this._groups.map(sparse), this._parents); -} - -function EnterNode(parent, datum) { - this.ownerDocument = parent.ownerDocument; - this.namespaceURI = parent.namespaceURI; - this._next = null; - this._parent = parent; - this.__data__ = datum; -} - -EnterNode.prototype = { - constructor: EnterNode, - appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, - insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, - querySelector: function(selector) { return this._parent.querySelector(selector); }, - querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } -}; - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/constant.js -/* harmony default export */ function src_constant(x) { - return function() { - return x; - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/data.js - - - - -function bindIndex(parent, group, enter, update, exit, data) { - var i = 0, - node, - groupLength = group.length, - dataLength = data.length; - - // Put any non-null nodes that fit into update. - // Put any null nodes into enter. - // Put any remaining data into enter. - for (; i < dataLength; ++i) { - if (node = group[i]) { - node.__data__ = data[i]; - update[i] = node; - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Put any non-null nodes that don’t fit into exit. - for (; i < groupLength; ++i) { - if (node = group[i]) { - exit[i] = node; - } - } -} - -function bindKey(parent, group, enter, update, exit, data, key) { - var i, - node, - nodeByKeyValue = new Map, - groupLength = group.length, - dataLength = data.length, - keyValues = new Array(groupLength), - keyValue; - - // Compute the key for each node. - // If multiple nodes have the same key, the duplicates are added to exit. - for (i = 0; i < groupLength; ++i) { - if (node = group[i]) { - keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + ""; - if (nodeByKeyValue.has(keyValue)) { - exit[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - } - } - - // Compute the key for each datum. - // If there a node associated with this key, join and add it to update. - // If there is not (or the key is a duplicate), add it to enter. - for (i = 0; i < dataLength; ++i) { - keyValue = key.call(parent, data[i], i, data) + ""; - if (node = nodeByKeyValue.get(keyValue)) { - update[i] = node; - node.__data__ = data[i]; - nodeByKeyValue.delete(keyValue); - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Add any remaining nodes that were not bound to data to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) { - exit[i] = node; - } - } -} - -function datum(node) { - return node.__data__; -} - -/* harmony default export */ function data(value, key) { - if (!arguments.length) return Array.from(this, datum); - - var bind = key ? bindKey : bindIndex, - parents = this._parents, - groups = this._groups; - - if (typeof value !== "function") value = src_constant(value); - - for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { - var parent = parents[j], - group = groups[j], - groupLength = group.length, - data = arraylike(value.call(parent, parent && parent.__data__, j, parents)), - dataLength = data.length, - enterGroup = enter[j] = new Array(dataLength), - updateGroup = update[j] = new Array(dataLength), - exitGroup = exit[j] = new Array(groupLength); - - bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); - - // Now connect the enter nodes to their following update node, such that - // appendChild can insert the materialized enter node before this node, - // rather than at the end of the parent node. - for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { - if (previous = enterGroup[i0]) { - if (i0 >= i1) i1 = i0 + 1; - while (!(next = updateGroup[i1]) && ++i1 < dataLength); - previous._next = next || null; - } - } - } - - update = new Selection(update, parents); - update._enter = enter; - update._exit = exit; - return update; -} - -// Given some data, this returns an array-like view of it: an object that -// exposes a length property and allows numeric indexing. Note that unlike -// selectAll, this isn’t worried about “live” collections because the resulting -// array will only be used briefly while data is being bound. (It is possible to -// cause the data to change while iterating by using a key function, but please -// don’t; we’d rather avoid a gratuitous copy.) -function arraylike(data) { - return typeof data === "object" && "length" in data - ? data // Array, TypedArray, NodeList, array-like - : Array.from(data); // Map, Set, iterable, string, or anything else -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/exit.js - - - -/* harmony default export */ function exit() { - return new Selection(this._exit || this._groups.map(sparse), this._parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/join.js -/* harmony default export */ function join(onenter, onupdate, onexit) { - var enter = this.enter(), update = this, exit = this.exit(); - if (typeof onenter === "function") { - enter = onenter(enter); - if (enter) enter = enter.selection(); - } else { - enter = enter.append(onenter + ""); - } - if (onupdate != null) { - update = onupdate(update); - if (update) update = update.selection(); - } - if (onexit == null) exit.remove(); else onexit(exit); - return enter && update ? enter.merge(update).order() : update; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/merge.js - - -/* harmony default export */ function merge(context) { - var selection = context.selection ? context.selection() : context; - - for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Selection(merges, this._parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/order.js -/* harmony default export */ function order() { - - for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { - for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { - if (node = group[i]) { - if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - - return this; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/sort.js - - -/* harmony default export */ function sort(compare) { - if (!compare) compare = ascending; - - function compareNode(a, b) { - return a && b ? compare(a.__data__, b.__data__) : !a - !b; - } - - for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group[i]) { - sortgroup[i] = node; - } - } - sortgroup.sort(compareNode); - } - - return new Selection(sortgroups, this._parents).order(); -} - -function ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/call.js -/* harmony default export */ function call() { - var callback = arguments[0]; - arguments[0] = this; - callback.apply(null, arguments); - return this; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/nodes.js -/* harmony default export */ function nodes() { - return Array.from(this); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/node.js -/* harmony default export */ function node() { - - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { - var node = group[i]; - if (node) return node; - } - } - - return null; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/size.js -/* harmony default export */ function size() { - let size = 0; - for (const node of this) ++size; // eslint-disable-line no-unused-vars - return size; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/empty.js -/* harmony default export */ function selection_empty() { - return !this.node(); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/each.js -/* harmony default export */ function each(callback) { - - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) callback.call(node, node.__data__, i, group); - } - } - - return this; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/namespaces.js -var xhtml = "http://www.w3.org/1999/xhtml"; - -/* harmony default export */ const namespaces = ({ - svg: "http://www.w3.org/2000/svg", - xhtml: xhtml, - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}); - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/namespace.js - - -/* harmony default export */ function namespace(name) { - var prefix = name += "", i = prefix.indexOf(":"); - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/attr.js - - -function attrRemove(name) { - return function() { - this.removeAttribute(name); - }; -} - -function attrRemoveNS(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} - -function attrConstant(name, value) { - return function() { - this.setAttribute(name, value); - }; -} - -function attrConstantNS(fullname, value) { - return function() { - this.setAttributeNS(fullname.space, fullname.local, value); - }; -} - -function attrFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttribute(name); - else this.setAttribute(name, v); - }; -} - -function attrFunctionNS(fullname, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttributeNS(fullname.space, fullname.local); - else this.setAttributeNS(fullname.space, fullname.local, v); - }; -} - -/* harmony default export */ function attr(name, value) { - var fullname = namespace(name); - - if (arguments.length < 2) { - var node = this.node(); - return fullname.local - ? node.getAttributeNS(fullname.space, fullname.local) - : node.getAttribute(fullname); - } - - return this.each((value == null - ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" - ? (fullname.local ? attrFunctionNS : attrFunction) - : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/window.js -/* harmony default export */ function src_window(node) { - return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node - || (node.document && node) // node is a Window - || node.defaultView; // node is a Document -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/style.js - - -function styleRemove(name) { - return function() { - this.style.removeProperty(name); - }; -} - -function styleConstant(name, value, priority) { - return function() { - this.style.setProperty(name, value, priority); - }; -} - -function styleFunction(name, value, priority) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.style.removeProperty(name); - else this.style.setProperty(name, v, priority); - }; -} - -/* harmony default export */ function style(name, value, priority) { - return arguments.length > 1 - ? this.each((value == null - ? styleRemove : typeof value === "function" - ? styleFunction - : styleConstant)(name, value, priority == null ? "" : priority)) - : styleValue(this.node(), name); -} - -function styleValue(node, name) { - return node.style.getPropertyValue(name) - || src_window(node).getComputedStyle(node, null).getPropertyValue(name); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/property.js -function propertyRemove(name) { - return function() { - delete this[name]; - }; -} - -function propertyConstant(name, value) { - return function() { - this[name] = value; - }; -} - -function propertyFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) delete this[name]; - else this[name] = v; - }; -} - -/* harmony default export */ function property(name, value) { - return arguments.length > 1 - ? this.each((value == null - ? propertyRemove : typeof value === "function" - ? propertyFunction - : propertyConstant)(name, value)) - : this.node()[name]; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/classed.js -function classArray(string) { - return string.trim().split(/^|\s+/); -} - -function classList(node) { - return node.classList || new ClassList(node); -} - -function ClassList(node) { - this._node = node; - this._names = classArray(node.getAttribute("class") || ""); -} - -ClassList.prototype = { - add: function(name) { - var i = this._names.indexOf(name); - if (i < 0) { - this._names.push(name); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - remove: function(name) { - var i = this._names.indexOf(name); - if (i >= 0) { - this._names.splice(i, 1); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - contains: function(name) { - return this._names.indexOf(name) >= 0; - } -}; - -function classedAdd(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.add(names[i]); -} - -function classedRemove(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.remove(names[i]); -} - -function classedTrue(names) { - return function() { - classedAdd(this, names); - }; -} - -function classedFalse(names) { - return function() { - classedRemove(this, names); - }; -} - -function classedFunction(names, value) { - return function() { - (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); - }; -} - -/* harmony default export */ function classed(name, value) { - var names = classArray(name + ""); - - if (arguments.length < 2) { - var list = classList(this.node()), i = -1, n = names.length; - while (++i < n) if (!list.contains(names[i])) return false; - return true; - } - - return this.each((typeof value === "function" - ? classedFunction : value - ? classedTrue - : classedFalse)(names, value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/text.js -function textRemove() { - this.textContent = ""; -} - -function textConstant(value) { - return function() { - this.textContent = value; - }; -} - -function textFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - }; -} - -/* harmony default export */ function selection_text(value) { - return arguments.length - ? this.each(value == null - ? textRemove : (typeof value === "function" - ? textFunction - : textConstant)(value)) - : this.node().textContent; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/html.js -function htmlRemove() { - this.innerHTML = ""; -} - -function htmlConstant(value) { - return function() { - this.innerHTML = value; - }; -} - -function htmlFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - }; -} - -/* harmony default export */ function html(value) { - return arguments.length - ? this.each(value == null - ? htmlRemove : (typeof value === "function" - ? htmlFunction - : htmlConstant)(value)) - : this.node().innerHTML; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/raise.js -function raise() { - if (this.nextSibling) this.parentNode.appendChild(this); -} - -/* harmony default export */ function selection_raise() { - return this.each(raise); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/lower.js -function lower() { - if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); -} - -/* harmony default export */ function selection_lower() { - return this.each(lower); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/creator.js - - - -function creatorInherit(name) { - return function() { - var document = this.ownerDocument, - uri = this.namespaceURI; - return uri === xhtml && document.documentElement.namespaceURI === xhtml - ? document.createElement(name) - : document.createElementNS(uri, name); - }; -} - -function creatorFixed(fullname) { - return function() { - return this.ownerDocument.createElementNS(fullname.space, fullname.local); - }; -} - -/* harmony default export */ function creator(name) { - var fullname = namespace(name); - return (fullname.local - ? creatorFixed - : creatorInherit)(fullname); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/append.js - - -/* harmony default export */ function append(name) { - var create = typeof name === "function" ? name : creator(name); - return this.select(function() { - return this.appendChild(create.apply(this, arguments)); - }); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/insert.js - - - -function constantNull() { - return null; -} - -/* harmony default export */ function insert(name, before) { - var create = typeof name === "function" ? name : creator(name), - select = before == null ? constantNull : typeof before === "function" ? before : selector(before); - return this.select(function() { - return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); - }); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/remove.js -function remove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); -} - -/* harmony default export */ function selection_remove() { - return this.each(remove); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/clone.js -function selection_cloneShallow() { - var clone = this.cloneNode(false), parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; -} - -function selection_cloneDeep() { - var clone = this.cloneNode(true), parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; -} - -/* harmony default export */ function clone(deep) { - return this.select(deep ? selection_cloneDeep : selection_cloneShallow); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/datum.js -/* harmony default export */ function selection_datum(value) { - return arguments.length - ? this.property("__data__", value) - : this.node().__data__; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/on.js -function contextListener(listener) { - return function(event) { - listener.call(this, event, this.__data__); - }; -} - -function parseTypenames(typenames) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - return {type: t, name: name}; - }); -} - -function onRemove(typename) { - return function() { - var on = this.__on; - if (!on) return; - for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { - if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.options); - } else { - on[++i] = o; - } - } - if (++i) on.length = i; - else delete this.__on; - }; -} - -function onAdd(typename, value, options) { - return function() { - var on = this.__on, o, listener = contextListener(value); - if (on) for (var j = 0, m = on.length; j < m; ++j) { - if ((o = on[j]).type === typename.type && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.options); - this.addEventListener(o.type, o.listener = listener, o.options = options); - o.value = value; - return; - } - } - this.addEventListener(typename.type, listener, options); - o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options}; - if (!on) this.__on = [o]; - else on.push(o); - }; -} - -/* harmony default export */ function on(typename, value, options) { - var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; - - if (arguments.length < 2) { - var on = this.node().__on; - if (on) for (var j = 0, m = on.length, o; j < m; ++j) { - for (i = 0, o = on[j]; i < n; ++i) { - if ((t = typenames[i]).type === o.type && t.name === o.name) { - return o.value; - } - } - } - return; - } - - on = value ? onAdd : onRemove; - for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options)); - return this; -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/dispatch.js - - -function dispatchEvent(node, type, params) { - var window = src_window(node), - event = window.CustomEvent; - - if (typeof event === "function") { - event = new event(type, params); - } else { - event = window.document.createEvent("Event"); - if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; - else event.initEvent(type, false, false); - } - - node.dispatchEvent(event); -} - -function dispatchConstant(type, params) { - return function() { - return dispatchEvent(this, type, params); - }; -} - -function dispatchFunction(type, params) { - return function() { - return dispatchEvent(this, type, params.apply(this, arguments)); - }; -} - -/* harmony default export */ function dispatch(type, params) { - return this.each((typeof params === "function" - ? dispatchFunction - : dispatchConstant)(type, params)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/iterator.js -/* harmony default export */ function* iterator() { - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) yield node; - } - } -} - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/index.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -var root = [null]; - -function Selection(groups, parents) { - this._groups = groups; - this._parents = parents; -} - -function selection() { - return new Selection([[document.documentElement]], root); -} - -function selection_selection() { - return this; -} - -Selection.prototype = selection.prototype = { - constructor: Selection, - select: selection_select, - selectAll: selectAll, - selectChild: selectChild, - selectChildren: selectChildren, - filter: selection_filter, - data: data, - enter: enter, - exit: exit, - join: join, - merge: merge, - selection: selection_selection, - order: order, - sort: sort, - call: call, - nodes: nodes, - node: node, - size: size, - empty: selection_empty, - each: each, - attr: attr, - style: style, - property: property, - classed: classed, - text: selection_text, - html: html, - raise: selection_raise, - lower: selection_lower, - append: append, - insert: insert, - remove: selection_remove, - clone: clone, - datum: selection_datum, - on: on, - dispatch: dispatch, - [Symbol.iterator]: iterator -}; - -/* harmony default export */ const src_selection = (selection); - -;// CONCATENATED MODULE: ../node_modules/d3-selection/src/select.js - - -/* harmony default export */ function src_select(selector) { - return typeof selector === "string" - ? new Selection([[document.querySelector(selector)]], [document.documentElement]) - : new Selection([[selector]], root); -} - -;// CONCATENATED MODULE: ../node_modules/d3-dispatch/src/dispatch.js -var noop = {value: () => {}}; - -function dispatch_dispatch() { - for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { - if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t); - _[t] = []; - } - return new Dispatch(_); -} - -function Dispatch(_) { - this._ = _; -} - -function dispatch_parseTypenames(typenames, types) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); - return {type: t, name: name}; - }); -} - -Dispatch.prototype = dispatch_dispatch.prototype = { - constructor: Dispatch, - on: function(typename, callback) { - var _ = this._, - T = dispatch_parseTypenames(typename + "", _), - t, - i = -1, - n = T.length; - - // If no callback was specified, return the callback of the given type and name. - if (arguments.length < 2) { - while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; - return; - } - - // If a type was specified, set the callback for the given type and name. - // Otherwise, if a null callback was specified, remove callbacks of the given name. - if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); - while (++i < n) { - if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); - else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); - } - - return this; - }, - copy: function() { - var copy = {}, _ = this._; - for (var t in _) copy[t] = _[t].slice(); - return new Dispatch(copy); - }, - call: function(type, that) { - if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - }, - apply: function(type, that, args) { - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - } -}; - -function get(type, name) { - for (var i = 0, n = type.length, c; i < n; ++i) { - if ((c = type[i]).name === name) { - return c.value; - } - } -} - -function set(type, name, callback) { - for (var i = 0, n = type.length; i < n; ++i) { - if (type[i].name === name) { - type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); - break; - } - } - if (callback != null) type.push({name: name, value: callback}); - return type; -} - -/* harmony default export */ const src_dispatch = (dispatch_dispatch); - -;// CONCATENATED MODULE: ../node_modules/d3-timer/src/timer.js -var timer_frame = 0, // is an animation frame pending? - timeout = 0, // is a timeout pending? - interval = 0, // are any timers active? - pokeDelay = 1000, // how frequently we check for clock skew - taskHead, - taskTail, - clockLast = 0, - clockNow = 0, - clockSkew = 0, - clock = typeof performance === "object" && performance.now ? performance : Date, - setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; - -function now() { - return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); -} - -function clearNow() { - clockNow = 0; -} - -function Timer() { - this._call = - this._time = - this._next = null; -} - -Timer.prototype = timer.prototype = { - constructor: Timer, - restart: function(callback, delay, time) { - if (typeof callback !== "function") throw new TypeError("callback is not a function"); - time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); - if (!this._next && taskTail !== this) { - if (taskTail) taskTail._next = this; - else taskHead = this; - taskTail = this; - } - this._call = callback; - this._time = time; - sleep(); - }, - stop: function() { - if (this._call) { - this._call = null; - this._time = Infinity; - sleep(); - } - } -}; - -function timer(callback, delay, time) { - var t = new Timer; - t.restart(callback, delay, time); - return t; -} - -function timerFlush() { - now(); // Get the current time, if not already set. - ++timer_frame; // Pretend we’ve set an alarm, if we haven’t already. - var t = taskHead, e; - while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e); - t = t._next; - } - --timer_frame; -} - -function wake() { - clockNow = (clockLast = clock.now()) + clockSkew; - timer_frame = timeout = 0; - try { - timerFlush(); - } finally { - timer_frame = 0; - nap(); - clockNow = 0; - } -} - -function poke() { - var now = clock.now(), delay = now - clockLast; - if (delay > pokeDelay) clockSkew -= delay, clockLast = now; -} - -function nap() { - var t0, t1 = taskHead, t2, time = Infinity; - while (t1) { - if (t1._call) { - if (time > t1._time) time = t1._time; - t0 = t1, t1 = t1._next; - } else { - t2 = t1._next, t1._next = null; - t1 = t0 ? t0._next = t2 : taskHead = t2; - } - } - taskTail = t0; - sleep(time); -} - -function sleep(time) { - if (timer_frame) return; // Soonest alarm already set, or will be. - if (timeout) timeout = clearTimeout(timeout); - var delay = time - clockNow; // Strictly less than if we recomputed clockNow. - if (delay > 24) { - if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); - if (interval) interval = clearInterval(interval); - } else { - if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); - timer_frame = 1, setFrame(wake); - } -} - -;// CONCATENATED MODULE: ../node_modules/d3-timer/src/timeout.js - - -/* harmony default export */ function src_timeout(callback, delay, time) { - var t = new Timer; - delay = delay == null ? 0 : +delay; - t.restart(elapsed => { - t.stop(); - callback(elapsed + delay); - }, delay, time); - return t; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/schedule.js - - - -var emptyOn = src_dispatch("start", "end", "cancel", "interrupt"); -var emptyTween = []; - -var CREATED = 0; -var SCHEDULED = 1; -var STARTING = 2; -var STARTED = 3; -var RUNNING = 4; -var ENDING = 5; -var ENDED = 6; - -/* harmony default export */ function schedule(node, name, id, index, group, timing) { - var schedules = node.__transition; - if (!schedules) node.__transition = {}; - else if (id in schedules) return; - create(node, id, { - name: name, - index: index, // For context during callback. - group: group, // For context during callback. - on: emptyOn, - tween: emptyTween, - time: timing.time, - delay: timing.delay, - duration: timing.duration, - ease: timing.ease, - timer: null, - state: CREATED - }); -} - -function init(node, id) { - var schedule = schedule_get(node, id); - if (schedule.state > CREATED) throw new Error("too late; already scheduled"); - return schedule; -} - -function schedule_set(node, id) { - var schedule = schedule_get(node, id); - if (schedule.state > STARTED) throw new Error("too late; already running"); - return schedule; -} - -function schedule_get(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found"); - return schedule; -} - -function create(node, id, self) { - var schedules = node.__transition, - tween; - - // Initialize the self timer when the transition is created. - // Note the actual delay is not known until the first callback! - schedules[id] = self; - self.timer = timer(schedule, 0, self.time); - - function schedule(elapsed) { - self.state = SCHEDULED; - self.timer.restart(start, self.delay, self.time); - - // If the elapsed delay is less than our first sleep, start immediately. - if (self.delay <= elapsed) start(elapsed - self.delay); - } - - function start(elapsed) { - var i, j, n, o; - - // If the state is not SCHEDULED, then we previously errored on start. - if (self.state !== SCHEDULED) return stop(); - - for (i in schedules) { - o = schedules[i]; - if (o.name !== self.name) continue; - - // While this element already has a starting transition during this frame, - // defer starting an interrupting transition until that transition has a - // chance to tick (and possibly end); see d3/d3-transition#54! - if (o.state === STARTED) return src_timeout(start); - - // Interrupt the active transition, if any. - if (o.state === RUNNING) { - o.state = ENDED; - o.timer.stop(); - o.on.call("interrupt", node, node.__data__, o.index, o.group); - delete schedules[i]; - } - - // Cancel any pre-empted transitions. - else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - o.on.call("cancel", node, node.__data__, o.index, o.group); - delete schedules[i]; - } - } - - // Defer the first tick to end of the current frame; see d3/d3#1576. - // Note the transition may be canceled after start and before the first tick! - // Note this must be scheduled before the start event; see d3/d3-transition#16! - // Assuming this is successful, subsequent callbacks go straight to tick. - src_timeout(function() { - if (self.state === STARTED) { - self.state = RUNNING; - self.timer.restart(tick, self.delay, self.time); - tick(elapsed); - } - }); - - // Dispatch the start event. - // Note this must be done before the tween are initialized. - self.state = STARTING; - self.on.call("start", node, node.__data__, self.index, self.group); - if (self.state !== STARTING) return; // interrupted - self.state = STARTED; - - // Initialize the tween, deleting null tween. - tween = new Array(n = self.tween.length); - for (i = 0, j = -1; i < n; ++i) { - if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { - tween[++j] = o; - } - } - tween.length = j + 1; - } - - function tick(elapsed) { - var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), - i = -1, - n = tween.length; - - while (++i < n) { - tween[i].call(node, t); - } - - // Dispatch the end event. - if (self.state === ENDING) { - self.on.call("end", node, node.__data__, self.index, self.group); - stop(); - } - } - - function stop() { - self.state = ENDED; - self.timer.stop(); - delete schedules[id]; - for (var i in schedules) return; // eslint-disable-line no-unused-vars - delete node.__transition; - } -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/interrupt.js - - -/* harmony default export */ function interrupt(node, name) { - var schedules = node.__transition, - schedule, - active, - empty = true, - i; - - if (!schedules) return; - - name = name == null ? null : name + ""; - - for (i in schedules) { - if ((schedule = schedules[i]).name !== name) { empty = false; continue; } - active = schedule.state > STARTING && schedule.state < ENDING; - schedule.state = ENDED; - schedule.timer.stop(); - schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group); - delete schedules[i]; - } - - if (empty) delete node.__transition; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/interrupt.js - - -/* harmony default export */ function selection_interrupt(name) { - return this.each(function() { - interrupt(this, name); - }); -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/number.js -/* harmony default export */ function number(a, b) { - return a = +a, b = +b, function(t) { - return a * (1 - t) + b * t; - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/decompose.js -var degrees = 180 / Math.PI; - -var identity = { - translateX: 0, - translateY: 0, - rotate: 0, - skewX: 0, - scaleX: 1, - scaleY: 1 -}; - -/* harmony default export */ function decompose(a, b, c, d, e, f) { - var scaleX, scaleY, skewX; - if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; - if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; - if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; - if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; - return { - translateX: e, - translateY: f, - rotate: Math.atan2(b, a) * degrees, - skewX: Math.atan(skewX) * degrees, - scaleX: scaleX, - scaleY: scaleY - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/parse.js - - -var svgNode; - -/* eslint-disable no-undef */ -function parseCss(value) { - const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + ""); - return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f); -} - -function parseSvg(value) { - if (value == null) return identity; - if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); - svgNode.setAttribute("transform", value); - if (!(value = svgNode.transform.baseVal.consolidate())) return identity; - value = value.matrix; - return decompose(value.a, value.b, value.c, value.d, value.e, value.f); -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/index.js - - - -function interpolateTransform(parse, pxComma, pxParen, degParen) { - - function pop(s) { - return s.length ? s.pop() + " " : ""; - } - - function translate(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push("translate(", null, pxComma, null, pxParen); - q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); - } else if (xb || yb) { - s.push("translate(" + xb + pxComma + yb + pxParen); - } - } - - function rotate(a, b, s, q) { - if (a !== b) { - if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path - q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)}); - } else if (b) { - s.push(pop(s) + "rotate(" + b + degParen); - } - } - - function skewX(a, b, s, q) { - if (a !== b) { - q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)}); - } else if (b) { - s.push(pop(s) + "skewX(" + b + degParen); - } - } - - function scale(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push(pop(s) + "scale(", null, ",", null, ")"); - q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); - } else if (xb !== 1 || yb !== 1) { - s.push(pop(s) + "scale(" + xb + "," + yb + ")"); - } - } - - return function(a, b) { - var s = [], // string constants and placeholders - q = []; // number interpolators - a = parse(a), b = parse(b); - translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); - rotate(a.rotate, b.rotate, s, q); - skewX(a.skewX, b.skewX, s, q); - scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); - a = b = null; // gc - return function(t) { - var i = -1, n = q.length, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; -} - -var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); -var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/tween.js - - -function tweenRemove(id, name) { - var tween0, tween1; - return function() { - var schedule = schedule_set(this, id), - tween = schedule.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = tween0 = tween; - for (var i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1 = tween1.slice(); - tween1.splice(i, 1); - break; - } - } - } - - schedule.tween = tween1; - }; -} - -function tweenFunction(id, name, value) { - var tween0, tween1; - if (typeof value !== "function") throw new Error; - return function() { - var schedule = schedule_set(this, id), - tween = schedule.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = (tween0 = tween).slice(); - for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1[i] = t; - break; - } - } - if (i === n) tween1.push(t); - } - - schedule.tween = tween1; - }; -} - -/* harmony default export */ function tween(name, value) { - var id = this._id; - - name += ""; - - if (arguments.length < 2) { - var tween = schedule_get(this.node(), id).tween; - for (var i = 0, n = tween.length, t; i < n; ++i) { - if ((t = tween[i]).name === name) { - return t.value; - } - } - return null; - } - - return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); -} - -function tweenValue(transition, name, value) { - var id = transition._id; - - transition.each(function() { - var schedule = schedule_set(this, id); - (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); - }); - - return function(node) { - return schedule_get(node, id).value[name]; - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-color/src/define.js -/* harmony default export */ function src_define(constructor, factory, prototype) { - constructor.prototype = factory.prototype = prototype; - prototype.constructor = constructor; -} - -function extend(parent, definition) { - var prototype = Object.create(parent.prototype); - for (var key in definition) prototype[key] = definition[key]; - return prototype; -} - -;// CONCATENATED MODULE: ../node_modules/d3-color/src/color.js - - -function Color() {} - -var darker = 0.7; -var brighter = 1 / darker; - -var reI = "\\s*([+-]?\\d+)\\s*", - reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", - reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", - reHex = /^#([0-9a-f]{3,8})$/, - reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), - reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), - reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), - reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), - reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), - reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); - -var named = { - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - rebeccapurple: 0x663399, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32 -}; - -src_define(Color, color, { - copy: function(channels) { - return Object.assign(new this.constructor, this, channels); - }, - displayable: function() { - return this.rgb().displayable(); - }, - hex: color_formatHex, // Deprecated! Use color.formatHex. - formatHex: color_formatHex, - formatHsl: color_formatHsl, - formatRgb: color_formatRgb, - toString: color_formatRgb -}); - -function color_formatHex() { - return this.rgb().formatHex(); -} - -function color_formatHsl() { - return hslConvert(this).formatHsl(); -} - -function color_formatRgb() { - return this.rgb().formatRgb(); -} - -function color(format) { - var m, l; - format = (format + "").trim().toLowerCase(); - return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 - : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 - : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 - : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 - : null) // invalid hex - : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) - : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) - : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) - : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) - : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) - : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) - : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins - : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) - : null; -} - -function rgbn(n) { - return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); -} - -function rgba(r, g, b, a) { - if (a <= 0) r = g = b = NaN; - return new Rgb(r, g, b, a); -} - -function rgbConvert(o) { - if (!(o instanceof Color)) o = color(o); - if (!o) return new Rgb; - o = o.rgb(); - return new Rgb(o.r, o.g, o.b, o.opacity); -} - -function color_rgb(r, g, b, opacity) { - return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); -} - -function Rgb(r, g, b, opacity) { - this.r = +r; - this.g = +g; - this.b = +b; - this.opacity = +opacity; -} - -src_define(Rgb, color_rgb, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - rgb: function() { - return this; - }, - displayable: function() { - return (-0.5 <= this.r && this.r < 255.5) - && (-0.5 <= this.g && this.g < 255.5) - && (-0.5 <= this.b && this.b < 255.5) - && (0 <= this.opacity && this.opacity <= 1); - }, - hex: rgb_formatHex, // Deprecated! Use color.formatHex. - formatHex: rgb_formatHex, - formatRgb: rgb_formatRgb, - toString: rgb_formatRgb -})); - -function rgb_formatHex() { - return "#" + hex(this.r) + hex(this.g) + hex(this.b); -} - -function rgb_formatRgb() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "rgb(" : "rgba(") - + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.b) || 0)) - + (a === 1 ? ")" : ", " + a + ")"); -} - -function hex(value) { - value = Math.max(0, Math.min(255, Math.round(value) || 0)); - return (value < 16 ? "0" : "") + value.toString(16); -} - -function hsla(h, s, l, a) { - if (a <= 0) h = s = l = NaN; - else if (l <= 0 || l >= 1) h = s = NaN; - else if (s <= 0) h = NaN; - return new Hsl(h, s, l, a); -} - -function hslConvert(o) { - if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Color)) o = color(o); - if (!o) return new Hsl; - if (o instanceof Hsl) return o; - o = o.rgb(); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - h = NaN, - s = max - min, - l = (max + min) / 2; - if (s) { - if (r === max) h = (g - b) / s + (g < b) * 6; - else if (g === max) h = (b - r) / s + 2; - else h = (r - g) / s + 4; - s /= l < 0.5 ? max + min : 2 - max - min; - h *= 60; - } else { - s = l > 0 && l < 1 ? 0 : h; - } - return new Hsl(h, s, l, o.opacity); -} - -function hsl(h, s, l, opacity) { - return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); -} - -function Hsl(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; -} - -src_define(Hsl, hsl, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = this.h % 360 + (this.h < 0) * 360, - s = isNaN(h) || isNaN(this.s) ? 0 : this.s, - l = this.l, - m2 = l + (l < 0.5 ? l : 1 - l) * s, - m1 = 2 * l - m2; - return new Rgb( - hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), - hsl2rgb(h, m1, m2), - hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), - this.opacity - ); - }, - displayable: function() { - return (0 <= this.s && this.s <= 1 || isNaN(this.s)) - && (0 <= this.l && this.l <= 1) - && (0 <= this.opacity && this.opacity <= 1); - }, - formatHsl: function() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "hsl(" : "hsla(") - + (this.h || 0) + ", " - + (this.s || 0) * 100 + "%, " - + (this.l || 0) * 100 + "%" - + (a === 1 ? ")" : ", " + a + ")"); - } -})); - -/* From FvD 13.37, CSS Color Module Level 3 */ -function hsl2rgb(h, m1, m2) { - return (h < 60 ? m1 + (m2 - m1) * h / 60 - : h < 180 ? m2 - : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 - : m1) * 255; -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/basis.js -function basis(t1, v0, v1, v2, v3) { - var t2 = t1 * t1, t3 = t2 * t1; - return ((1 - 3 * t1 + 3 * t2 - t3) * v0 - + (4 - 6 * t2 + 3 * t3) * v1 - + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 - + t3 * v3) / 6; -} - -/* harmony default export */ function src_basis(values) { - var n = values.length - 1; - return function(t) { - var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), - v1 = values[i], - v2 = values[i + 1], - v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, - v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; - return basis((t - i / n) * n, v0, v1, v2, v3); - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/basisClosed.js - - -/* harmony default export */ function basisClosed(values) { - var n = values.length; - return function(t) { - var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), - v0 = values[(i + n - 1) % n], - v1 = values[i % n], - v2 = values[(i + 1) % n], - v3 = values[(i + 2) % n]; - return basis((t - i / n) * n, v0, v1, v2, v3); - }; -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/constant.js -/* harmony default export */ const d3_interpolate_src_constant = (x => () => x); - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/color.js - - -function linear(a, d) { - return function(t) { - return a + t * d; - }; -} - -function exponential(a, b, y) { - return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { - return Math.pow(a + t * b, y); - }; -} - -function hue(a, b) { - var d = b - a; - return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a); -} - -function gamma(y) { - return (y = +y) === 1 ? nogamma : function(a, b) { - return b - a ? exponential(a, b, y) : d3_interpolate_src_constant(isNaN(a) ? b : a); - }; -} - -function nogamma(a, b) { - var d = b - a; - return d ? linear(a, d) : d3_interpolate_src_constant(isNaN(a) ? b : a); -} - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/rgb.js - - - - - -/* harmony default export */ const rgb = ((function rgbGamma(y) { - var color = gamma(y); - - function rgb(start, end) { - var r = color((start = color_rgb(start)).r, (end = color_rgb(end)).r), - g = color(start.g, end.g), - b = color(start.b, end.b), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.r = r(t); - start.g = g(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ""; - }; - } - - rgb.gamma = rgbGamma; - - return rgb; -})(1)); - -function rgbSpline(spline) { - return function(colors) { - var n = colors.length, - r = new Array(n), - g = new Array(n), - b = new Array(n), - i, color; - for (i = 0; i < n; ++i) { - color = color_rgb(colors[i]); - r[i] = color.r || 0; - g[i] = color.g || 0; - b[i] = color.b || 0; - } - r = spline(r); - g = spline(g); - b = spline(b); - color.opacity = 1; - return function(t) { - color.r = r(t); - color.g = g(t); - color.b = b(t); - return color + ""; - }; - }; -} - -var rgbBasis = rgbSpline(src_basis); -var rgbBasisClosed = rgbSpline(basisClosed); - -;// CONCATENATED MODULE: ../node_modules/d3-interpolate/src/string.js - - -var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, - reB = new RegExp(reA.source, "g"); - -function zero(b) { - return function() { - return b; - }; -} - -function one(b) { - return function(t) { - return b(t) + ""; - }; -} - -/* harmony default export */ function string(a, b) { - var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b - am, // current match in a - bm, // current match in b - bs, // string preceding current number in b, if any - i = -1, // index in s - s = [], // string constants and placeholders - q = []; // number interpolators - - // Coerce inputs to strings. - a = a + "", b = b + ""; - - // Interpolate pairs of numbers in a & b. - while ((am = reA.exec(a)) - && (bm = reB.exec(b))) { - if ((bs = bm.index) > bi) { // a string precedes the next number in b - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match - if (s[i]) s[i] += bm; // coalesce with previous string - else s[++i] = bm; - } else { // interpolate non-matching numbers - s[++i] = null; - q.push({i: i, x: number(am, bm)}); - } - bi = reB.lastIndex; - } - - // Add remains of b. - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - - // Special optimization for only a single match. - // Otherwise, interpolate each of the numbers and rejoin the string. - return s.length < 2 ? (q[0] - ? one(q[0].x) - : zero(b)) - : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/interpolate.js - - - -/* harmony default export */ function interpolate(a, b) { - var c; - return (typeof b === "number" ? number - : b instanceof color ? rgb - : (c = color(b)) ? (b = c, rgb) - : string)(a, b); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/attr.js - - - - - -function attr_attrRemove(name) { - return function() { - this.removeAttribute(name); - }; -} - -function attr_attrRemoveNS(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} - -function attr_attrConstant(name, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = this.getAttribute(name); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; -} - -function attr_attrConstantNS(fullname, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = this.getAttributeNS(fullname.space, fullname.local); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; -} - -function attr_attrFunction(name, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0, value1 = value(this), string1; - if (value1 == null) return void this.removeAttribute(name); - string0 = this.getAttribute(name); - string1 = value1 + ""; - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; -} - -function attr_attrFunctionNS(fullname, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0, value1 = value(this), string1; - if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); - string0 = this.getAttributeNS(fullname.space, fullname.local); - string1 = value1 + ""; - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; -} - -/* harmony default export */ function transition_attr(name, value) { - var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; - return this.attrTween(name, typeof value === "function" - ? (fullname.local ? attr_attrFunctionNS : attr_attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) - : value == null ? (fullname.local ? attr_attrRemoveNS : attr_attrRemove)(fullname) - : (fullname.local ? attr_attrConstantNS : attr_attrConstant)(fullname, i, value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/attrTween.js - - -function attrInterpolate(name, i) { - return function(t) { - this.setAttribute(name, i.call(this, t)); - }; -} - -function attrInterpolateNS(fullname, i) { - return function(t) { - this.setAttributeNS(fullname.space, fullname.local, i.call(this, t)); - }; -} - -function attrTweenNS(fullname, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i); - return t0; - } - tween._value = value; - return tween; -} - -function attrTween(name, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i); - return t0; - } - tween._value = value; - return tween; -} - -/* harmony default export */ function transition_attrTween(name, value) { - var key = "attr." + name; - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - var fullname = namespace(name); - return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/delay.js - - -function delayFunction(id, value) { - return function() { - init(this, id).delay = +value.apply(this, arguments); - }; -} - -function delayConstant(id, value) { - return value = +value, function() { - init(this, id).delay = value; - }; -} - -/* harmony default export */ function delay(value) { - var id = this._id; - - return arguments.length - ? this.each((typeof value === "function" - ? delayFunction - : delayConstant)(id, value)) - : schedule_get(this.node(), id).delay; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/duration.js - - -function durationFunction(id, value) { - return function() { - schedule_set(this, id).duration = +value.apply(this, arguments); - }; -} - -function durationConstant(id, value) { - return value = +value, function() { - schedule_set(this, id).duration = value; - }; -} - -/* harmony default export */ function duration(value) { - var id = this._id; - - return arguments.length - ? this.each((typeof value === "function" - ? durationFunction - : durationConstant)(id, value)) - : schedule_get(this.node(), id).duration; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/ease.js - - -function easeConstant(id, value) { - if (typeof value !== "function") throw new Error; - return function() { - schedule_set(this, id).ease = value; - }; -} - -/* harmony default export */ function ease(value) { - var id = this._id; - - return arguments.length - ? this.each(easeConstant(id, value)) - : schedule_get(this.node(), id).ease; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/easeVarying.js - - -function easeVarying(id, value) { - return function() { - var v = value.apply(this, arguments); - if (typeof v !== "function") throw new Error; - schedule_set(this, id).ease = v; - }; -} - -/* harmony default export */ function transition_easeVarying(value) { - if (typeof value !== "function") throw new Error; - return this.each(easeVarying(this._id, value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/filter.js - - - -/* harmony default export */ function transition_filter(match) { - if (typeof match !== "function") match = matcher(match); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Transition(subgroups, this._parents, this._name, this._id); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/merge.js - - -/* harmony default export */ function transition_merge(transition) { - if (transition._id !== this._id) throw new Error; - - for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Transition(merges, this._parents, this._name, this._id); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/on.js - - -function start(name) { - return (name + "").trim().split(/^|\s+/).every(function(t) { - var i = t.indexOf("."); - if (i >= 0) t = t.slice(0, i); - return !t || t === "start"; - }); -} - -function onFunction(id, name, listener) { - var on0, on1, sit = start(name) ? init : schedule_set; - return function() { - var schedule = sit(this, id), - on = schedule.on; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); - - schedule.on = on1; - }; -} - -/* harmony default export */ function transition_on(name, listener) { - var id = this._id; - - return arguments.length < 2 - ? schedule_get(this.node(), id).on.on(name) - : this.each(onFunction(id, name, listener)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/remove.js -function removeFunction(id) { - return function() { - var parent = this.parentNode; - for (var i in this.__transition) if (+i !== id) return; - if (parent) parent.removeChild(this); - }; -} - -/* harmony default export */ function transition_remove() { - return this.on("end.remove", removeFunction(this._id)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/select.js - - - - -/* harmony default export */ function transition_select(select) { - var name = this._name, - id = this._id; - - if (typeof select !== "function") select = selector(select); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - schedule(subgroup[i], name, id, i, subgroup, schedule_get(node, id)); - } - } - } - - return new Transition(subgroups, this._parents, name, id); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/selectAll.js - - - - -/* harmony default export */ function transition_selectAll(select) { - var name = this._name, - id = this._id; - - if (typeof select !== "function") select = selectorAll(select); - - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - for (var children = select.call(node, node.__data__, i, group), child, inherit = schedule_get(node, id), k = 0, l = children.length; k < l; ++k) { - if (child = children[k]) { - schedule(child, name, id, k, children, inherit); - } - } - subgroups.push(children); - parents.push(node); - } - } - } - - return new Transition(subgroups, parents, name, id); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/selection.js - - -var selection_Selection = src_selection.prototype.constructor; - -/* harmony default export */ function transition_selection() { - return new selection_Selection(this._groups, this._parents); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/style.js - - - - - - -function styleNull(name, interpolate) { - var string00, - string10, - interpolate0; - return function() { - var string0 = styleValue(this, name), - string1 = (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, string10 = string1); - }; -} - -function style_styleRemove(name) { - return function() { - this.style.removeProperty(name); - }; -} - -function style_styleConstant(name, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = styleValue(this, name); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; -} - -function style_styleFunction(name, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0 = styleValue(this, name), - value1 = value(this), - string1 = value1 + ""; - if (value1 == null) string1 = value1 = (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; -} - -function styleMaybeRemove(id, name) { - var on0, on1, listener0, key = "style." + name, event = "end." + key, remove; - return function() { - var schedule = schedule_set(this, id), - on = schedule.on, - listener = schedule.value[key] == null ? remove || (remove = style_styleRemove(name)) : undefined; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener); - - schedule.on = on1; - }; -} - -/* harmony default export */ function transition_style(name, value, priority) { - var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; - return value == null ? this - .styleTween(name, styleNull(name, i)) - .on("end.style." + name, style_styleRemove(name)) - : typeof value === "function" ? this - .styleTween(name, style_styleFunction(name, i, tweenValue(this, "style." + name, value))) - .each(styleMaybeRemove(this._id, name)) - : this - .styleTween(name, style_styleConstant(name, i, value), priority) - .on("end.style." + name, null); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/styleTween.js -function styleInterpolate(name, i, priority) { - return function(t) { - this.style.setProperty(name, i.call(this, t), priority); - }; -} - -function styleTween(name, value, priority) { - var t, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority); - return t; - } - tween._value = value; - return tween; -} - -/* harmony default export */ function transition_styleTween(name, value, priority) { - var key = "style." + (name += ""); - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/text.js - - -function text_textConstant(value) { - return function() { - this.textContent = value; - }; -} - -function text_textFunction(value) { - return function() { - var value1 = value(this); - this.textContent = value1 == null ? "" : value1; - }; -} - -/* harmony default export */ function transition_text(value) { - return this.tween("text", typeof value === "function" - ? text_textFunction(tweenValue(this, "text", value)) - : text_textConstant(value == null ? "" : value + "")); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/textTween.js -function textInterpolate(i) { - return function(t) { - this.textContent = i.call(this, t); - }; -} - -function textTween(value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && textInterpolate(i); - return t0; - } - tween._value = value; - return tween; -} - -/* harmony default export */ function transition_textTween(value) { - var key = "text"; - if (arguments.length < 1) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, textTween(value)); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/transition.js - - - -/* harmony default export */ function transition() { - var name = this._name, - id0 = this._id, - id1 = newId(); - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - var inherit = schedule_get(node, id0); - schedule(node, name, id1, i, group, { - time: inherit.time + inherit.delay + inherit.duration, - delay: 0, - duration: inherit.duration, - ease: inherit.ease - }); - } - } - } - - return new Transition(groups, this._parents, name, id1); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/end.js - - -/* harmony default export */ function end() { - var on0, on1, that = this, id = that._id, size = that.size(); - return new Promise(function(resolve, reject) { - var cancel = {value: reject}, - end = {value: function() { if (--size === 0) resolve(); }}; - - that.each(function() { - var schedule = schedule_set(this, id), - on = schedule.on; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) { - on1 = (on0 = on).copy(); - on1._.cancel.push(cancel); - on1._.interrupt.push(cancel); - on1._.end.push(end); - } - - schedule.on = on1; - }); - - // The selection was empty, resolve end immediately - if (size === 0) resolve(); - }); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/index.js - - - - - - - - - - - - - - - - - - - - - - -var id = 0; - -function Transition(groups, parents, name, id) { - this._groups = groups; - this._parents = parents; - this._name = name; - this._id = id; -} - -function transition_transition(name) { - return src_selection().transition(name); -} - -function newId() { - return ++id; -} - -var selection_prototype = src_selection.prototype; - -Transition.prototype = transition_transition.prototype = { - constructor: Transition, - select: transition_select, - selectAll: transition_selectAll, - selectChild: selection_prototype.selectChild, - selectChildren: selection_prototype.selectChildren, - filter: transition_filter, - merge: transition_merge, - selection: transition_selection, - transition: transition, - call: selection_prototype.call, - nodes: selection_prototype.nodes, - node: selection_prototype.node, - size: selection_prototype.size, - empty: selection_prototype.empty, - each: selection_prototype.each, - on: transition_on, - attr: transition_attr, - attrTween: transition_attrTween, - style: transition_style, - styleTween: transition_styleTween, - text: transition_text, - textTween: transition_textTween, - remove: transition_remove, - tween: tween, - delay: delay, - duration: duration, - ease: ease, - easeVarying: transition_easeVarying, - end: end, - [Symbol.iterator]: selection_prototype[Symbol.iterator] -}; - -;// CONCATENATED MODULE: ../node_modules/d3-ease/src/cubic.js -function cubicIn(t) { - return t * t * t; -} - -function cubicOut(t) { - return --t * t * t + 1; -} - -function cubicInOut(t) { - return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/transition.js - - - - - -var defaultTiming = { - time: null, // Set on use. - delay: 0, - duration: 250, - ease: cubicInOut -}; - -function inherit(node, id) { - var timing; - while (!(timing = node.__transition) || !(timing = timing[id])) { - if (!(node = node.parentNode)) { - throw new Error(`transition ${id} not found`); - } - } - return timing; -} - -/* harmony default export */ function selection_transition(name) { - var id, - timing; - - if (name instanceof Transition) { - id = name._id, name = name._name; - } else { - id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; - } - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - schedule(node, name, id, i, group, timing || inherit(node, id)); - } - } - } - - return new Transition(groups, this._parents, name, id); -} - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/index.js - - - - -src_selection.prototype.interrupt = selection_interrupt; -src_selection.prototype.transition = selection_transition; - -;// CONCATENATED MODULE: ../node_modules/d3-transition/src/index.js - - - - - -;// CONCATENATED MODULE: ./tooltip.js -/* global event */ - - - - - - -function defaultLabel (d) { - return d.data.name -} - -function defaultFlamegraphTooltip () { - var rootElement = src_select('body') - var tooltip = null - // Function to get HTML content from data. - var html = defaultLabel - // Function to get text content from data. - var text = defaultLabel - // Whether to use d3's .html() to set content, otherwise use .text(). - var contentIsHTML = false - - function tip () { - tooltip = rootElement - .append('div') - .style('display', 'none') - .style('position', 'absolute') - .style('opacity', 0) - .style('pointer-events', 'none') - .attr('class', 'd3-flame-graph-tip') - } - - tip.show = function (d) { - tooltip - .style('display', 'block') - .style('left', event.pageX + 5 + 'px') - .style('top', event.pageY + 5 + 'px') - .transition() - .duration(200) - .style('opacity', 1) - .style('pointer-events', 'all') - - if (contentIsHTML) { - tooltip.html(html(d)) - } else { - tooltip.text(text(d)) - } - - return tip - } - - tip.hide = function () { - tooltip - .style('display', 'none') - .transition() - .duration(200) - .style('opacity', 0) - .style('pointer-events', 'none') - - return tip - } - - /** - * Gets/sets a function converting the d3 data into the tooltip's textContent. - * - * Cannot be combined with tip.html(). - */ - tip.text = function (_) { - if (!arguments.length) return text - text = _ - contentIsHTML = false - return tip - } - - /** - * Gets/sets a function converting the d3 data into the tooltip's innerHTML. - * - * Cannot be combined with tip.text(). - * - * @deprecated prefer tip.text(). - */ - tip.html = function (_) { - if (!arguments.length) return html - html = _ - contentIsHTML = true - return tip - } - - tip.destroy = function () { - tooltip.remove() - } - - return tip -} - -/******/ return __webpack_exports__; -/******/ })() -; -}); \ No newline at end of file diff --git a/development/charts/flamegraph/lib/d3-flamegraph.css b/development/charts/flamegraph/lib/d3-flamegraph.css deleted file mode 100644 index fa6f345ff7a9..000000000000 --- a/development/charts/flamegraph/lib/d3-flamegraph.css +++ /dev/null @@ -1,46 +0,0 @@ -.d3-flame-graph rect { - stroke: #EEEEEE; - fill-opacity: .8; -} - -.d3-flame-graph rect:hover { - stroke: #474747; - stroke-width: 0.5; - cursor: pointer; -} - -.d3-flame-graph-label { - pointer-events: none; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - font-size: 12px; - font-family: Verdana; - margin-left: 4px; - margin-right: 4px; - line-height: 1.5; - padding: 0 0 0; - font-weight: 400; - color: black; - text-align: left; -} - -.d3-flame-graph .fade { - opacity: 0.6 !important; -} - -.d3-flame-graph .title { - font-size: 20px; - font-family: Verdana; -} - -.d3-flame-graph-tip { - background-color: black; - border: none; - border-radius: 3px; - padding: 5px 10px 5px 10px; - min-width: 250px; - text-align: left; - color: white; - z-index: 10; -} \ No newline at end of file diff --git a/development/charts/flamegraph/lib/d3-flamegraph.js b/development/charts/flamegraph/lib/d3-flamegraph.js deleted file mode 100644 index eabb2c44972c..000000000000 --- a/development/charts/flamegraph/lib/d3-flamegraph.js +++ /dev/null @@ -1,5719 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if (typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if (typeof define === 'function' && define.amd) define([], factory); - else if (typeof exports === 'object') exports['flamegraph'] = factory(); - else root['flamegraph'] = factory(); -})(self, function () { - return /******/ (() => { - // webpackBootstrap - /******/ 'use strict'; // The require scope - /******/ /******/ var __webpack_require__ = {}; /* webpack/runtime/define property getters */ - /******/ - /************************************************************************/ - /******/ /******/ (() => { - /******/ // define getter functions for harmony exports - /******/ __webpack_require__.d = (exports, definition) => { - /******/ for (var key in definition) { - /******/ if ( - __webpack_require__.o(definition, key) && - !__webpack_require__.o(exports, key) - ) { - /******/ Object.defineProperty(exports, key, { - enumerable: true, - get: definition[key], - }); - /******/ - } - /******/ - } - /******/ - }; - /******/ - })(); /* webpack/runtime/hasOwnProperty shorthand */ - /******/ - /******/ /******/ (() => { - /******/ __webpack_require__.o = (obj, prop) => - Object.prototype.hasOwnProperty.call(obj, prop); - /******/ - })(); - /******/ - /************************************************************************/ - var __webpack_exports__ = {}; - - // EXPORTS - __webpack_require__.d(__webpack_exports__, { - default: () => /* binding */ flamegraph, - }); // CONCATENATED MODULE: ../node_modules/d3-selection/src/selector.js - - function none() {} - - /* harmony default export */ function selector(selector) { - return selector == null - ? none - : function () { - return this.querySelector(selector); - }; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/select.js - - /* harmony default export */ function selection_select(select) { - if (typeof select !== 'function') select = selector(select); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = new Array(m), - j = 0; - j < m; - ++j - ) { - for ( - var group = groups[j], - n = group.length, - subgroup = (subgroups[j] = new Array(n)), - node, - subnode, - i = 0; - i < n; - ++i - ) { - if ( - (node = group[i]) && - (subnode = select.call(node, node.__data__, i, group)) - ) { - if ('__data__' in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - } - } - } - - return new Selection(subgroups, this._parents); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/array.js - - // Given something array like (or null), returns something that is strictly an - // array. This is used to ensure that array-like objects passed to d3.selectAll - // or selection.selectAll are converted into proper arrays when creating a - // selection; we don’t ever want to create a selection backed by a live - // HTMLCollection or NodeList. However, note that selection.selectAll will use a - // static NodeList as a group, since it safely derived from querySelectorAll. - function array(x) { - return x == null ? [] : Array.isArray(x) ? x : Array.from(x); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selectorAll.js - - function empty() { - return []; - } - - /* harmony default export */ function selectorAll(selector) { - return selector == null - ? empty - : function () { - return this.querySelectorAll(selector); - }; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectAll.js - - function arrayAll(select) { - return function () { - return array(select.apply(this, arguments)); - }; - } - - /* harmony default export */ function selectAll(select) { - if (typeof select === 'function') select = arrayAll(select); - else select = selectorAll(select); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = [], - parents = [], - j = 0; - j < m; - ++j - ) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if ((node = group[i])) { - subgroups.push(select.call(node, node.__data__, i, group)); - parents.push(node); - } - } - } - - return new Selection(subgroups, parents); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/matcher.js - - /* harmony default export */ function matcher(selector) { - return function () { - return this.matches(selector); - }; - } - - function childMatcher(selector) { - return function (node) { - return node.matches(selector); - }; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectChild.js - - var find = Array.prototype.find; - - function childFind(match) { - return function () { - return find.call(this.children, match); - }; - } - - function childFirst() { - return this.firstElementChild; - } - - /* harmony default export */ function selectChild(match) { - return this.select( - match == null - ? childFirst - : childFind( - typeof match === 'function' ? match : childMatcher(match), - ), - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/selectChildren.js - - var filter = Array.prototype.filter; - - function children() { - return Array.from(this.children); - } - - function childrenFilter(match) { - return function () { - return filter.call(this.children, match); - }; - } - - /* harmony default export */ function selectChildren(match) { - return this.selectAll( - match == null - ? children - : childrenFilter( - typeof match === 'function' ? match : childMatcher(match), - ), - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/filter.js - - /* harmony default export */ function selection_filter(match) { - if (typeof match !== 'function') match = matcher(match); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = new Array(m), - j = 0; - j < m; - ++j - ) { - for ( - var group = groups[j], - n = group.length, - subgroup = (subgroups[j] = []), - node, - i = 0; - i < n; - ++i - ) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Selection(subgroups, this._parents); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/sparse.js - - /* harmony default export */ function sparse(update) { - return new Array(update.length); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/enter.js - - /* harmony default export */ function enter() { - return new Selection( - this._enter || this._groups.map(sparse), - this._parents, - ); - } - - function EnterNode(parent, datum) { - this.ownerDocument = parent.ownerDocument; - this.namespaceURI = parent.namespaceURI; - this._next = null; - this._parent = parent; - this.__data__ = datum; - } - - EnterNode.prototype = { - constructor: EnterNode, - appendChild: function (child) { - return this._parent.insertBefore(child, this._next); - }, - insertBefore: function (child, next) { - return this._parent.insertBefore(child, next); - }, - querySelector: function (selector) { - return this._parent.querySelector(selector); - }, - querySelectorAll: function (selector) { - return this._parent.querySelectorAll(selector); - }, - }; // CONCATENATED MODULE: ../node_modules/d3-selection/src/constant.js - - /* harmony default export */ function src_constant(x) { - return function () { - return x; - }; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/data.js - - function bindIndex(parent, group, enter, update, exit, data) { - var i = 0, - node, - groupLength = group.length, - dataLength = data.length; - - // Put any non-null nodes that fit into update. - // Put any null nodes into enter. - // Put any remaining data into enter. - for (; i < dataLength; ++i) { - if ((node = group[i])) { - node.__data__ = data[i]; - update[i] = node; - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Put any non-null nodes that don’t fit into exit. - for (; i < groupLength; ++i) { - if ((node = group[i])) { - exit[i] = node; - } - } - } - - function bindKey(parent, group, enter, update, exit, data, key) { - var i, - node, - nodeByKeyValue = new Map(), - groupLength = group.length, - dataLength = data.length, - keyValues = new Array(groupLength), - keyValue; - - // Compute the key for each node. - // If multiple nodes have the same key, the duplicates are added to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i])) { - keyValues[i] = keyValue = - key.call(node, node.__data__, i, group) + ''; - if (nodeByKeyValue.has(keyValue)) { - exit[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - } - } - - // Compute the key for each datum. - // If there a node associated with this key, join and add it to update. - // If there is not (or the key is a duplicate), add it to enter. - for (i = 0; i < dataLength; ++i) { - keyValue = key.call(parent, data[i], i, data) + ''; - if ((node = nodeByKeyValue.get(keyValue))) { - update[i] = node; - node.__data__ = data[i]; - nodeByKeyValue.delete(keyValue); - } else { - enter[i] = new EnterNode(parent, data[i]); - } - } - - // Add any remaining nodes that were not bound to data to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i]) && nodeByKeyValue.get(keyValues[i]) === node) { - exit[i] = node; - } - } - } - - function datum(node) { - return node.__data__; - } - - /* harmony default export */ function data(value, key) { - if (!arguments.length) return Array.from(this, datum); - - var bind = key ? bindKey : bindIndex, - parents = this._parents, - groups = this._groups; - - if (typeof value !== 'function') value = src_constant(value); - - for ( - var m = groups.length, - update = new Array(m), - enter = new Array(m), - exit = new Array(m), - j = 0; - j < m; - ++j - ) { - var parent = parents[j], - group = groups[j], - groupLength = group.length, - data = arraylike( - value.call(parent, parent && parent.__data__, j, parents), - ), - dataLength = data.length, - enterGroup = (enter[j] = new Array(dataLength)), - updateGroup = (update[j] = new Array(dataLength)), - exitGroup = (exit[j] = new Array(groupLength)); - - bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); - - // Now connect the enter nodes to their following update node, such that - // appendChild can insert the materialized enter node before this node, - // rather than at the end of the parent node. - for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { - if ((previous = enterGroup[i0])) { - if (i0 >= i1) i1 = i0 + 1; - while (!(next = updateGroup[i1]) && ++i1 < dataLength); - previous._next = next || null; - } - } - } - - update = new Selection(update, parents); - update._enter = enter; - update._exit = exit; - return update; - } - - // Given some data, this returns an array-like view of it: an object that - // exposes a length property and allows numeric indexing. Note that unlike - // selectAll, this isn’t worried about “live” collections because the resulting - // array will only be used briefly while data is being bound. (It is possible to - // cause the data to change while iterating by using a key function, but please - // don’t; we’d rather avoid a gratuitous copy.) - function arraylike(data) { - return typeof data === 'object' && 'length' in data - ? data // Array, TypedArray, NodeList, array-like - : Array.from(data); // Map, Set, iterable, string, or anything else - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/exit.js - - /* harmony default export */ function exit() { - return new Selection( - this._exit || this._groups.map(sparse), - this._parents, - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/join.js - - /* harmony default export */ function join(onenter, onupdate, onexit) { - var enter = this.enter(), - update = this, - exit = this.exit(); - if (typeof onenter === 'function') { - enter = onenter(enter); - if (enter) enter = enter.selection(); - } else { - enter = enter.append(onenter + ''); - } - if (onupdate != null) { - update = onupdate(update); - if (update) update = update.selection(); - } - if (onexit == null) exit.remove(); - else onexit(exit); - return enter && update ? enter.merge(update).order() : update; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/merge.js - - /* harmony default export */ function merge(context) { - var selection = context.selection ? context.selection() : context; - - for ( - var groups0 = this._groups, - groups1 = selection._groups, - m0 = groups0.length, - m1 = groups1.length, - m = Math.min(m0, m1), - merges = new Array(m0), - j = 0; - j < m; - ++j - ) { - for ( - var group0 = groups0[j], - group1 = groups1[j], - n = group0.length, - merge = (merges[j] = new Array(n)), - node, - i = 0; - i < n; - ++i - ) { - if ((node = group0[i] || group1[i])) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Selection(merges, this._parents); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/order.js - - /* harmony default export */ function order() { - for (var groups = this._groups, j = -1, m = groups.length; ++j < m; ) { - for ( - var group = groups[j], i = group.length - 1, next = group[i], node; - --i >= 0; - - ) { - if ((node = group[i])) { - if (next && node.compareDocumentPosition(next) ^ 4) - next.parentNode.insertBefore(node, next); - next = node; - } - } - } - - return this; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/sort.js - - /* harmony default export */ function sort(compare) { - if (!compare) compare = ascending; - - function compareNode(a, b) { - return a && b ? compare(a.__data__, b.__data__) : !a - !b; - } - - for ( - var groups = this._groups, - m = groups.length, - sortgroups = new Array(m), - j = 0; - j < m; - ++j - ) { - for ( - var group = groups[j], - n = group.length, - sortgroup = (sortgroups[j] = new Array(n)), - node, - i = 0; - i < n; - ++i - ) { - if ((node = group[i])) { - sortgroup[i] = node; - } - } - sortgroup.sort(compareNode); - } - - return new Selection(sortgroups, this._parents).order(); - } - - function ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/call.js - - /* harmony default export */ function call() { - var callback = arguments[0]; - arguments[0] = this; - callback.apply(null, arguments); - return this; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/nodes.js - - /* harmony default export */ function nodes() { - return Array.from(this); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/node.js - - /* harmony default export */ function node() { - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { - var node = group[i]; - if (node) return node; - } - } - - return null; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/size.js - - /* harmony default export */ function size() { - let size = 0; - for (const node of this) ++size; // eslint-disable-line no-unused-vars - return size; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/empty.js - - /* harmony default export */ function selection_empty() { - return !this.node(); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/each.js - - /* harmony default export */ function each(callback) { - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if ((node = group[i])) callback.call(node, node.__data__, i, group); - } - } - - return this; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/namespaces.js - - var xhtml = 'http://www.w3.org/1999/xhtml'; - - /* harmony default export */ const namespaces = { - svg: 'http://www.w3.org/2000/svg', - xhtml: xhtml, - xlink: 'http://www.w3.org/1999/xlink', - xml: 'http://www.w3.org/XML/1998/namespace', - xmlns: 'http://www.w3.org/2000/xmlns/', - }; // CONCATENATED MODULE: ../node_modules/d3-selection/src/namespace.js - - /* harmony default export */ function namespace(name) { - var prefix = (name += ''), - i = prefix.indexOf(':'); - if (i >= 0 && (prefix = name.slice(0, i)) !== 'xmlns') - name = name.slice(i + 1); - return namespaces.hasOwnProperty(prefix) - ? { space: namespaces[prefix], local: name } - : name; // eslint-disable-line no-prototype-builtins - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/attr.js - - function attrRemove(name) { - return function () { - this.removeAttribute(name); - }; - } - - function attrRemoveNS(fullname) { - return function () { - this.removeAttributeNS(fullname.space, fullname.local); - }; - } - - function attrConstant(name, value) { - return function () { - this.setAttribute(name, value); - }; - } - - function attrConstantNS(fullname, value) { - return function () { - this.setAttributeNS(fullname.space, fullname.local, value); - }; - } - - function attrFunction(name, value) { - return function () { - var v = value.apply(this, arguments); - if (v == null) this.removeAttribute(name); - else this.setAttribute(name, v); - }; - } - - function attrFunctionNS(fullname, value) { - return function () { - var v = value.apply(this, arguments); - if (v == null) this.removeAttributeNS(fullname.space, fullname.local); - else this.setAttributeNS(fullname.space, fullname.local, v); - }; - } - - /* harmony default export */ function attr(name, value) { - var fullname = namespace(name); - - if (arguments.length < 2) { - var node = this.node(); - return fullname.local - ? node.getAttributeNS(fullname.space, fullname.local) - : node.getAttribute(fullname); - } - - return this.each( - (value == null - ? fullname.local - ? attrRemoveNS - : attrRemove - : typeof value === 'function' - ? fullname.local - ? attrFunctionNS - : attrFunction - : fullname.local - ? attrConstantNS - : attrConstant)(fullname, value), - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/window.js - - /* harmony default export */ function src_window(node) { - return ( - (node.ownerDocument && node.ownerDocument.defaultView) || // node is a Node - (node.document && node) || // node is a Window - node.defaultView - ); // node is a Document - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/style.js - - function styleRemove(name) { - return function () { - this.style.removeProperty(name); - }; - } - - function styleConstant(name, value, priority) { - return function () { - this.style.setProperty(name, value, priority); - }; - } - - function styleFunction(name, value, priority) { - return function () { - var v = value.apply(this, arguments); - if (v == null) this.style.removeProperty(name); - else this.style.setProperty(name, v, priority); - }; - } - - /* harmony default export */ function style(name, value, priority) { - return arguments.length > 1 - ? this.each( - (value == null - ? styleRemove - : typeof value === 'function' - ? styleFunction - : styleConstant)(name, value, priority == null ? '' : priority), - ) - : styleValue(this.node(), name); - } - - function styleValue(node, name) { - return ( - node.style.getPropertyValue(name) || - src_window(node).getComputedStyle(node, null).getPropertyValue(name) - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/property.js - - function propertyRemove(name) { - return function () { - delete this[name]; - }; - } - - function propertyConstant(name, value) { - return function () { - this[name] = value; - }; - } - - function propertyFunction(name, value) { - return function () { - var v = value.apply(this, arguments); - if (v == null) delete this[name]; - else this[name] = v; - }; - } - - /* harmony default export */ function property(name, value) { - return arguments.length > 1 - ? this.each( - (value == null - ? propertyRemove - : typeof value === 'function' - ? propertyFunction - : propertyConstant)(name, value), - ) - : this.node()[name]; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/classed.js - - function classArray(string) { - return string.trim().split(/^|\s+/); - } - - function classList(node) { - return node.classList || new ClassList(node); - } - - function ClassList(node) { - this._node = node; - this._names = classArray(node.getAttribute('class') || ''); - } - - ClassList.prototype = { - add: function (name) { - var i = this._names.indexOf(name); - if (i < 0) { - this._names.push(name); - this._node.setAttribute('class', this._names.join(' ')); - } - }, - remove: function (name) { - var i = this._names.indexOf(name); - if (i >= 0) { - this._names.splice(i, 1); - this._node.setAttribute('class', this._names.join(' ')); - } - }, - contains: function (name) { - return this._names.indexOf(name) >= 0; - }, - }; - - function classedAdd(node, names) { - var list = classList(node), - i = -1, - n = names.length; - while (++i < n) list.add(names[i]); - } - - function classedRemove(node, names) { - var list = classList(node), - i = -1, - n = names.length; - while (++i < n) list.remove(names[i]); - } - - function classedTrue(names) { - return function () { - classedAdd(this, names); - }; - } - - function classedFalse(names) { - return function () { - classedRemove(this, names); - }; - } - - function classedFunction(names, value) { - return function () { - (value.apply(this, arguments) ? classedAdd : classedRemove)( - this, - names, - ); - }; - } - - /* harmony default export */ function classed(name, value) { - var names = classArray(name + ''); - - if (arguments.length < 2) { - var list = classList(this.node()), - i = -1, - n = names.length; - while (++i < n) if (!list.contains(names[i])) return false; - return true; - } - - return this.each( - (typeof value === 'function' - ? classedFunction - : value - ? classedTrue - : classedFalse)(names, value), - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/text.js - - function textRemove() { - this.textContent = ''; - } - - function textConstant(value) { - return function () { - this.textContent = value; - }; - } - - function textFunction(value) { - return function () { - var v = value.apply(this, arguments); - this.textContent = v == null ? '' : v; - }; - } - - /* harmony default export */ function selection_text(value) { - return arguments.length - ? this.each( - value == null - ? textRemove - : (typeof value === 'function' ? textFunction : textConstant)( - value, - ), - ) - : this.node().textContent; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/html.js - - function htmlRemove() { - this.innerHTML = ''; - } - - function htmlConstant(value) { - return function () { - this.innerHTML = value; - }; - } - - function htmlFunction(value) { - return function () { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? '' : v; - }; - } - - /* harmony default export */ function html(value) { - return arguments.length - ? this.each( - value == null - ? htmlRemove - : (typeof value === 'function' ? htmlFunction : htmlConstant)( - value, - ), - ) - : this.node().innerHTML; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/raise.js - - function raise() { - if (this.nextSibling) this.parentNode.appendChild(this); - } - - /* harmony default export */ function selection_raise() { - return this.each(raise); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/lower.js - - function lower() { - if (this.previousSibling) - this.parentNode.insertBefore(this, this.parentNode.firstChild); - } - - /* harmony default export */ function selection_lower() { - return this.each(lower); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/creator.js - - function creatorInherit(name) { - return function () { - var document = this.ownerDocument, - uri = this.namespaceURI; - return uri === xhtml && document.documentElement.namespaceURI === xhtml - ? document.createElement(name) - : document.createElementNS(uri, name); - }; - } - - function creatorFixed(fullname) { - return function () { - return this.ownerDocument.createElementNS( - fullname.space, - fullname.local, - ); - }; - } - - /* harmony default export */ function creator(name) { - var fullname = namespace(name); - return (fullname.local ? creatorFixed : creatorInherit)(fullname); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/append.js - - /* harmony default export */ function append(name) { - var create = typeof name === 'function' ? name : creator(name); - return this.select(function () { - return this.appendChild(create.apply(this, arguments)); - }); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/insert.js - - function constantNull() { - return null; - } - - /* harmony default export */ function insert(name, before) { - var create = typeof name === 'function' ? name : creator(name), - select = - before == null - ? constantNull - : typeof before === 'function' - ? before - : selector(before); - return this.select(function () { - return this.insertBefore( - create.apply(this, arguments), - select.apply(this, arguments) || null, - ); - }); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/remove.js - - function remove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - } - - /* harmony default export */ function selection_remove() { - return this.each(remove); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/clone.js - - function selection_cloneShallow() { - var clone = this.cloneNode(false), - parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; - } - - function selection_cloneDeep() { - var clone = this.cloneNode(true), - parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; - } - - /* harmony default export */ function clone(deep) { - return this.select(deep ? selection_cloneDeep : selection_cloneShallow); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/datum.js - - /* harmony default export */ function selection_datum(value) { - return arguments.length - ? this.property('__data__', value) - : this.node().__data__; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/on.js - - function contextListener(listener) { - return function (event) { - listener.call(this, event, this.__data__); - }; - } - - function parseTypenames(typenames) { - return typenames - .trim() - .split(/^|\s+/) - .map(function (t) { - var name = '', - i = t.indexOf('.'); - if (i >= 0) (name = t.slice(i + 1)), (t = t.slice(0, i)); - return { type: t, name: name }; - }); - } - - function onRemove(typename) { - return function () { - var on = this.__on; - if (!on) return; - for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { - if ( - ((o = on[j]), - (!typename.type || o.type === typename.type) && - o.name === typename.name) - ) { - this.removeEventListener(o.type, o.listener, o.options); - } else { - on[++i] = o; - } - } - if (++i) on.length = i; - else delete this.__on; - }; - } - - function onAdd(typename, value, options) { - return function () { - var on = this.__on, - o, - listener = contextListener(value); - if (on) - for (var j = 0, m = on.length; j < m; ++j) { - if ( - (o = on[j]).type === typename.type && - o.name === typename.name - ) { - this.removeEventListener(o.type, o.listener, o.options); - this.addEventListener( - o.type, - (o.listener = listener), - (o.options = options), - ); - o.value = value; - return; - } - } - this.addEventListener(typename.type, listener, options); - o = { - type: typename.type, - name: typename.name, - value: value, - listener: listener, - options: options, - }; - if (!on) this.__on = [o]; - else on.push(o); - }; - } - - /* harmony default export */ function on(typename, value, options) { - var typenames = parseTypenames(typename + ''), - i, - n = typenames.length, - t; - - if (arguments.length < 2) { - var on = this.node().__on; - if (on) - for (var j = 0, m = on.length, o; j < m; ++j) { - for (i = 0, o = on[j]; i < n; ++i) { - if ((t = typenames[i]).type === o.type && t.name === o.name) { - return o.value; - } - } - } - return; - } - - on = value ? onAdd : onRemove; - for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options)); - return this; - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/dispatch.js - - function dispatchEvent(node, type, params) { - var window = src_window(node), - event = window.CustomEvent; - - if (typeof event === 'function') { - event = new event(type, params); - } else { - event = window.document.createEvent('Event'); - if (params) - event.initEvent(type, params.bubbles, params.cancelable), - (event.detail = params.detail); - else event.initEvent(type, false, false); - } - - node.dispatchEvent(event); - } - - function dispatchConstant(type, params) { - return function () { - return dispatchEvent(this, type, params); - }; - } - - function dispatchFunction(type, params) { - return function () { - return dispatchEvent(this, type, params.apply(this, arguments)); - }; - } - - /* harmony default export */ function dispatch(type, params) { - return this.each( - (typeof params === 'function' ? dispatchFunction : dispatchConstant)( - type, - params, - ), - ); - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/iterator.js - - /* harmony default export */ function* iterator() { - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if ((node = group[i])) yield node; - } - } - } // CONCATENATED MODULE: ../node_modules/d3-selection/src/selection/index.js - - var root = [null]; - - function Selection(groups, parents) { - this._groups = groups; - this._parents = parents; - } - - function selection() { - return new Selection([[document.documentElement]], root); - } - - function selection_selection() { - return this; - } - - Selection.prototype = selection.prototype = { - constructor: Selection, - select: selection_select, - selectAll: selectAll, - selectChild: selectChild, - selectChildren: selectChildren, - filter: selection_filter, - data: data, - enter: enter, - exit: exit, - join: join, - merge: merge, - selection: selection_selection, - order: order, - sort: sort, - call: call, - nodes: nodes, - node: node, - size: size, - empty: selection_empty, - each: each, - attr: attr, - style: style, - property: property, - classed: classed, - text: selection_text, - html: html, - raise: selection_raise, - lower: selection_lower, - append: append, - insert: insert, - remove: selection_remove, - clone: clone, - datum: selection_datum, - on: on, - dispatch: dispatch, - [Symbol.iterator]: iterator, - }; - - /* harmony default export */ const src_selection = selection; // CONCATENATED MODULE: ../node_modules/d3-selection/src/select.js - - /* harmony default export */ function src_select(selector) { - return typeof selector === 'string' - ? new Selection( - [[document.querySelector(selector)]], - [document.documentElement], - ) - : new Selection([[selector]], root); - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatDecimal.js - - /* harmony default export */ function formatDecimal(x) { - return Math.abs((x = Math.round(x))) >= 1e21 - ? x.toLocaleString('en').replace(/,/g, '') - : x.toString(10); - } - - // Computes the decimal coefficient and exponent of the specified number x with - // significant digits p, where x is positive and p is in [1, 21] or undefined. - // For example, formatDecimalParts(1.23) returns ["123", 0]. - function formatDecimalParts(x, p) { - if ( - (i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf( - 'e', - )) < 0 - ) - return null; // NaN, ±Infinity - var i, - coefficient = x.slice(0, i); - - // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ - // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). - return [ - coefficient.length > 1 - ? coefficient[0] + coefficient.slice(2) - : coefficient, - +x.slice(i + 1), - ]; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/exponent.js - - /* harmony default export */ function exponent(x) { - return (x = formatDecimalParts(Math.abs(x))), x ? x[1] : NaN; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatGroup.js - - /* harmony default export */ function formatGroup(grouping, thousands) { - return function (value, width) { - var i = value.length, - t = [], - j = 0, - g = grouping[0], - length = 0; - - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring((i -= g), i + g)); - if ((length += g + 1) > width) break; - g = grouping[(j = (j + 1) % grouping.length)]; - } - - return t.reverse().join(thousands); - }; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatNumerals.js - - /* harmony default export */ function formatNumerals(numerals) { - return function (value) { - return value.replace(/[0-9]/g, function (i) { - return numerals[+i]; - }); - }; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatSpecifier.js - - // [[fill]align][sign][symbol][0][width][,][.precision][~][type] - var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; - - function formatSpecifier(specifier) { - if (!(match = re.exec(specifier))) - throw new Error('invalid format: ' + specifier); - var match; - return new FormatSpecifier({ - fill: match[1], - align: match[2], - sign: match[3], - symbol: match[4], - zero: match[5], - width: match[6], - comma: match[7], - precision: match[8] && match[8].slice(1), - trim: match[9], - type: match[10], - }); - } - - formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof - - function FormatSpecifier(specifier) { - this.fill = specifier.fill === undefined ? ' ' : specifier.fill + ''; - this.align = specifier.align === undefined ? '>' : specifier.align + ''; - this.sign = specifier.sign === undefined ? '-' : specifier.sign + ''; - this.symbol = specifier.symbol === undefined ? '' : specifier.symbol + ''; - this.zero = !!specifier.zero; - this.width = specifier.width === undefined ? undefined : +specifier.width; - this.comma = !!specifier.comma; - this.precision = - specifier.precision === undefined ? undefined : +specifier.precision; - this.trim = !!specifier.trim; - this.type = specifier.type === undefined ? '' : specifier.type + ''; - } - - FormatSpecifier.prototype.toString = function () { - return ( - this.fill + - this.align + - this.sign + - this.symbol + - (this.zero ? '0' : '') + - (this.width === undefined ? '' : Math.max(1, this.width | 0)) + - (this.comma ? ',' : '') + - (this.precision === undefined - ? '' - : '.' + Math.max(0, this.precision | 0)) + - (this.trim ? '~' : '') + - this.type - ); - }; // CONCATENATED MODULE: ../node_modules/d3-format/src/formatTrim.js - - // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. - /* harmony default export */ function formatTrim(s) { - out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { - switch (s[i]) { - case '.': - i0 = i1 = i; - break; - case '0': - if (i0 === 0) i0 = i; - i1 = i; - break; - default: - if (!+s[i]) break out; - if (i0 > 0) i0 = 0; - break; - } - } - return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatPrefixAuto.js - - var prefixExponent; - - /* harmony default export */ function formatPrefixAuto(x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ''; - var coefficient = d[0], - exponent = d[1], - i = - exponent - - (prefixExponent = - Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + - 1, - n = coefficient.length; - return i === n - ? coefficient - : i > n - ? coefficient + new Array(i - n + 1).join('0') - : i > 0 - ? coefficient.slice(0, i) + '.' + coefficient.slice(i) - : '0.' + - new Array(1 - i).join('0') + - formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y! - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatRounded.js - - /* harmony default export */ function formatRounded(x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ''; - var coefficient = d[0], - exponent = d[1]; - return exponent < 0 - ? '0.' + new Array(-exponent).join('0') + coefficient - : coefficient.length > exponent + 1 - ? coefficient.slice(0, exponent + 1) + - '.' + - coefficient.slice(exponent + 1) - : coefficient + new Array(exponent - coefficient.length + 2).join('0'); - } // CONCATENATED MODULE: ../node_modules/d3-format/src/formatTypes.js - - /* harmony default export */ const formatTypes = { - '%': (x, p) => (x * 100).toFixed(p), - b: (x) => Math.round(x).toString(2), - c: (x) => x + '', - d: formatDecimal, - e: (x, p) => x.toExponential(p), - f: (x, p) => x.toFixed(p), - g: (x, p) => x.toPrecision(p), - o: (x) => Math.round(x).toString(8), - p: (x, p) => formatRounded(x * 100, p), - r: formatRounded, - s: formatPrefixAuto, - X: (x) => Math.round(x).toString(16).toUpperCase(), - x: (x) => Math.round(x).toString(16), - }; // CONCATENATED MODULE: ../node_modules/d3-format/src/identity.js - - /* harmony default export */ function identity(x) { - return x; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/locale.js - - var map = Array.prototype.map, - prefixes = [ - 'y', - 'z', - 'a', - 'f', - 'p', - 'n', - 'µ', - 'm', - '', - 'k', - 'M', - 'G', - 'T', - 'P', - 'E', - 'Z', - 'Y', - ]; - - /* harmony default export */ function locale(locale) { - var group = - locale.grouping === undefined || locale.thousands === undefined - ? identity - : formatGroup( - map.call(locale.grouping, Number), - locale.thousands + '', - ), - currencyPrefix = - locale.currency === undefined ? '' : locale.currency[0] + '', - currencySuffix = - locale.currency === undefined ? '' : locale.currency[1] + '', - decimal = locale.decimal === undefined ? '.' : locale.decimal + '', - numerals = - locale.numerals === undefined - ? identity - : formatNumerals(map.call(locale.numerals, String)), - percent = locale.percent === undefined ? '%' : locale.percent + '', - minus = locale.minus === undefined ? '−' : locale.minus + '', - nan = locale.nan === undefined ? 'NaN' : locale.nan + ''; - - function newFormat(specifier) { - specifier = formatSpecifier(specifier); - - var fill = specifier.fill, - align = specifier.align, - sign = specifier.sign, - symbol = specifier.symbol, - zero = specifier.zero, - width = specifier.width, - comma = specifier.comma, - precision = specifier.precision, - trim = specifier.trim, - type = specifier.type; - - // The "n" type is an alias for ",g". - if (type === 'n') (comma = true), (type = 'g'); - // The "" type, and any invalid type, is an alias for ".12~g". - else if (!formatTypes[type]) - precision === undefined && (precision = 12), - (trim = true), - (type = 'g'); - - // If zero fill is specified, padding goes after sign and before digits. - if (zero || (fill === '0' && align === '=')) - (zero = true), (fill = '0'), (align = '='); - - // Compute the prefix and suffix. - // For SI-prefix, the suffix is lazily computed. - var prefix = - symbol === '$' - ? currencyPrefix - : symbol === '#' && /[boxX]/.test(type) - ? '0' + type.toLowerCase() - : '', - suffix = - symbol === '$' ? currencySuffix : /[%p]/.test(type) ? percent : ''; - - // What format function should we use? - // Is this an integer type? - // Can this type generate exponential notation? - var formatType = formatTypes[type], - maybeSuffix = /[defgprs%]/.test(type); - - // Set the default precision if not specified, - // or clamp the specified precision to the supported range. - // For significant precision, it must be in [1, 21]. - // For fixed precision, it must be in [0, 20]. - precision = - precision === undefined - ? 6 - : /[gprs]/.test(type) - ? Math.max(1, Math.min(21, precision)) - : Math.max(0, Math.min(20, precision)); - - function format(value) { - var valuePrefix = prefix, - valueSuffix = suffix, - i, - n, - c; - - if (type === 'c') { - valueSuffix = formatType(value) + valueSuffix; - value = ''; - } else { - value = +value; - - // Determine the sign. -0 is not less than 0, but 1 / -0 is! - var valueNegative = value < 0 || 1 / value < 0; - - // Perform the initial formatting. - value = isNaN(value) ? nan : formatType(Math.abs(value), precision); - - // Trim insignificant zeros. - if (trim) value = formatTrim(value); - - // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. - if (valueNegative && +value === 0 && sign !== '+') - valueNegative = false; - - // Compute the prefix and suffix. - valuePrefix = - (valueNegative - ? sign === '(' - ? sign - : minus - : sign === '-' || sign === '(' - ? '' - : sign) + valuePrefix; - valueSuffix = - (type === 's' ? prefixes[8 + prefixExponent / 3] : '') + - valueSuffix + - (valueNegative && sign === '(' ? ')' : ''); - - // Break the formatted value into the integer “value” part that can be - // grouped, and fractional or exponential “suffix” part that is not. - if (maybeSuffix) { - (i = -1), (n = value.length); - while (++i < n) { - if (((c = value.charCodeAt(i)), 48 > c || c > 57)) { - valueSuffix = - (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + - valueSuffix; - value = value.slice(0, i); - break; - } - } - } - } - - // If the fill character is not "0", grouping is applied before padding. - if (comma && !zero) value = group(value, Infinity); - - // Compute the padding. - var length = valuePrefix.length + value.length + valueSuffix.length, - padding = - length < width ? new Array(width - length + 1).join(fill) : ''; - - // If the fill character is "0", grouping is applied after padding. - if (comma && zero) - (value = group( - padding + value, - padding.length ? width - valueSuffix.length : Infinity, - )), - (padding = ''); - - // Reconstruct the final output based on the desired alignment. - switch (align) { - case '<': - value = valuePrefix + value + valueSuffix + padding; - break; - case '=': - value = valuePrefix + padding + value + valueSuffix; - break; - case '^': - value = - padding.slice(0, (length = padding.length >> 1)) + - valuePrefix + - value + - valueSuffix + - padding.slice(length); - break; - default: - value = padding + valuePrefix + value + valueSuffix; - break; - } - - return numerals(value); - } - - format.toString = function () { - return specifier + ''; - }; - - return format; - } - - function formatPrefix(specifier, value) { - var f = newFormat( - ((specifier = formatSpecifier(specifier)), - (specifier.type = 'f'), - specifier), - ), - e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, - k = Math.pow(10, -e), - prefix = prefixes[8 + e / 3]; - return function (value) { - return f(k * value) + prefix; - }; - } - - return { - format: newFormat, - formatPrefix: formatPrefix, - }; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/defaultLocale.js - - var defaultLocale_locale; - var format; - var formatPrefix; - - defaultLocale({ - thousands: ',', - grouping: [3], - currency: ['$', ''], - }); - - function defaultLocale(definition) { - defaultLocale_locale = locale(definition); - format = defaultLocale_locale.format; - formatPrefix = defaultLocale_locale.formatPrefix; - return defaultLocale_locale; - } // CONCATENATED MODULE: ../node_modules/d3-array/src/ascending.js - - function ascending_ascending(a, b) { - return a == null || b == null - ? NaN - : a < b - ? -1 - : a > b - ? 1 - : a >= b - ? 0 - : NaN; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/treemap/round.js - - /* harmony default export */ function treemap_round(node) { - node.x0 = Math.round(node.x0); - node.y0 = Math.round(node.y0); - node.x1 = Math.round(node.x1); - node.y1 = Math.round(node.y1); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/treemap/dice.js - - /* harmony default export */ function dice(parent, x0, y0, x1, y1) { - var nodes = parent.children, - node, - i = -1, - n = nodes.length, - k = parent.value && (x1 - x0) / parent.value; - - while (++i < n) { - (node = nodes[i]), (node.y0 = y0), (node.y1 = y1); - (node.x0 = x0), (node.x1 = x0 += node.value * k); - } - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/partition.js - - /* harmony default export */ function partition() { - var dx = 1, - dy = 1, - padding = 0, - round = false; - - function partition(root) { - var n = root.height + 1; - root.x0 = root.y0 = padding; - root.x1 = dx; - root.y1 = dy / n; - root.eachBefore(positionNode(dy, n)); - if (round) root.eachBefore(treemap_round); - return root; - } - - function positionNode(dy, n) { - return function (node) { - if (node.children) { - dice( - node, - node.x0, - (dy * (node.depth + 1)) / n, - node.x1, - (dy * (node.depth + 2)) / n, - ); - } - var x0 = node.x0, - y0 = node.y0, - x1 = node.x1 - padding, - y1 = node.y1 - padding; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - node.x0 = x0; - node.y0 = y0; - node.x1 = x1; - node.y1 = y1; - }; - } - - partition.round = function (x) { - return arguments.length ? ((round = !!x), partition) : round; - }; - - partition.size = function (x) { - return arguments.length - ? ((dx = +x[0]), (dy = +x[1]), partition) - : [dx, dy]; - }; - - partition.padding = function (x) { - return arguments.length ? ((padding = +x), partition) : padding; - }; - - return partition; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/count.js - - function count(node) { - var sum = 0, - children = node.children, - i = children && children.length; - if (!i) sum = 1; - else while (--i >= 0) sum += children[i].value; - node.value = sum; - } - - /* harmony default export */ function hierarchy_count() { - return this.eachAfter(count); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/each.js - - /* harmony default export */ function hierarchy_each(callback, that) { - let index = -1; - for (const node of this) { - callback.call(that, node, ++index, this); - } - return this; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/eachBefore.js - - /* harmony default export */ function eachBefore(callback, that) { - var node = this, - nodes = [node], - children, - i, - index = -1; - while ((node = nodes.pop())) { - callback.call(that, node, ++index, this); - if ((children = node.children)) { - for (i = children.length - 1; i >= 0; --i) { - nodes.push(children[i]); - } - } - } - return this; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/eachAfter.js - - /* harmony default export */ function eachAfter(callback, that) { - var node = this, - nodes = [node], - next = [], - children, - i, - n, - index = -1; - while ((node = nodes.pop())) { - next.push(node); - if ((children = node.children)) { - for (i = 0, n = children.length; i < n; ++i) { - nodes.push(children[i]); - } - } - } - while ((node = next.pop())) { - callback.call(that, node, ++index, this); - } - return this; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/find.js - - /* harmony default export */ function hierarchy_find(callback, that) { - let index = -1; - for (const node of this) { - if (callback.call(that, node, ++index, this)) { - return node; - } - } - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/sum.js - - /* harmony default export */ function sum(value) { - return this.eachAfter(function (node) { - var sum = +value(node.data) || 0, - children = node.children, - i = children && children.length; - while (--i >= 0) sum += children[i].value; - node.value = sum; - }); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/sort.js - - /* harmony default export */ function hierarchy_sort(compare) { - return this.eachBefore(function (node) { - if (node.children) { - node.children.sort(compare); - } - }); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/path.js - - /* harmony default export */ function path(end) { - var start = this, - ancestor = leastCommonAncestor(start, end), - nodes = [start]; - while (start !== ancestor) { - start = start.parent; - nodes.push(start); - } - var k = nodes.length; - while (end !== ancestor) { - nodes.splice(k, 0, end); - end = end.parent; - } - return nodes; - } - - function leastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = a.ancestors(), - bNodes = b.ancestors(), - c = null; - a = aNodes.pop(); - b = bNodes.pop(); - while (a === b) { - c = a; - a = aNodes.pop(); - b = bNodes.pop(); - } - return c; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/ancestors.js - - /* harmony default export */ function ancestors() { - var node = this, - nodes = [node]; - while ((node = node.parent)) { - nodes.push(node); - } - return nodes; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/descendants.js - - /* harmony default export */ function descendants() { - return Array.from(this); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/leaves.js - - /* harmony default export */ function leaves() { - var leaves = []; - this.eachBefore(function (node) { - if (!node.children) { - leaves.push(node); - } - }); - return leaves; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/links.js - - /* harmony default export */ function links() { - var root = this, - links = []; - root.each(function (node) { - if (node !== root) { - // Don’t include the root’s parent, if any. - links.push({ source: node.parent, target: node }); - } - }); - return links; - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/iterator.js - - /* harmony default export */ function* hierarchy_iterator() { - var node = this, - current, - next = [node], - children, - i, - n; - do { - (current = next.reverse()), (next = []); - while ((node = current.pop())) { - yield node; - if ((children = node.children)) { - for (i = 0, n = children.length; i < n; ++i) { - next.push(children[i]); - } - } - } - } while (next.length); - } // CONCATENATED MODULE: ../node_modules/d3-hierarchy/src/hierarchy/index.js - - function hierarchy(data, children) { - if (data instanceof Map) { - data = [undefined, data]; - if (children === undefined) children = mapChildren; - } else if (children === undefined) { - children = objectChildren; - } - - var root = new Node(data), - node, - nodes = [root], - child, - childs, - i, - n; - - while ((node = nodes.pop())) { - if ( - (childs = children(node.data)) && - (n = (childs = Array.from(childs)).length) - ) { - node.children = childs; - for (i = n - 1; i >= 0; --i) { - nodes.push((child = childs[i] = new Node(childs[i]))); - child.parent = node; - child.depth = node.depth + 1; - } - } - } - - return root.eachBefore(computeHeight); - } - - function node_copy() { - return hierarchy(this).eachBefore(copyData); - } - - function objectChildren(d) { - return d.children; - } - - function mapChildren(d) { - return Array.isArray(d) ? d[1] : null; - } - - function copyData(node) { - if (node.data.value !== undefined) node.value = node.data.value; - node.data = node.data.data; - } - - function computeHeight(node) { - var height = 0; - do node.height = height; - while ((node = node.parent) && node.height < ++height); - } - - function Node(data) { - this.data = data; - this.depth = this.height = 0; - this.parent = null; - } - - Node.prototype = hierarchy.prototype = { - constructor: Node, - count: hierarchy_count, - each: hierarchy_each, - eachAfter: eachAfter, - eachBefore: eachBefore, - find: hierarchy_find, - sum: sum, - sort: hierarchy_sort, - path: path, - ancestors: ancestors, - descendants: descendants, - leaves: leaves, - links: links, - copy: node_copy, - [Symbol.iterator]: hierarchy_iterator, - }; // CONCATENATED MODULE: ../node_modules/d3-array/src/ticks.js - - var e10 = Math.sqrt(50), - e5 = Math.sqrt(10), - e2 = Math.sqrt(2); - - function ticks(start, stop, count) { - var reverse, - i = -1, - n, - ticks, - step; - - (stop = +stop), (start = +start), (count = +count); - if (start === stop && count > 0) return [start]; - if ((reverse = stop < start)) (n = start), (start = stop), (stop = n); - if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) - return []; - - if (step > 0) { - let r0 = Math.round(start / step), - r1 = Math.round(stop / step); - if (r0 * step < start) ++r0; - if (r1 * step > stop) --r1; - ticks = new Array((n = r1 - r0 + 1)); - while (++i < n) ticks[i] = (r0 + i) * step; - } else { - step = -step; - let r0 = Math.round(start * step), - r1 = Math.round(stop * step); - if (r0 / step < start) ++r0; - if (r1 / step > stop) --r1; - ticks = new Array((n = r1 - r0 + 1)); - while (++i < n) ticks[i] = (r0 + i) / step; - } - - if (reverse) ticks.reverse(); - - return ticks; - } - - function tickIncrement(start, stop, count) { - var step = (stop - start) / Math.max(0, count), - power = Math.floor(Math.log(step) / Math.LN10), - error = step / Math.pow(10, power); - return power >= 0 - ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * - Math.pow(10, power) - : -Math.pow(10, -power) / - (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); - } - - function tickStep(start, stop, count) { - var step0 = Math.abs(stop - start) / Math.max(0, count), - step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), - error = step0 / step1; - if (error >= e10) step1 *= 10; - else if (error >= e5) step1 *= 5; - else if (error >= e2) step1 *= 2; - return stop < start ? -step1 : step1; - } // CONCATENATED MODULE: ../node_modules/d3-array/src/bisector.js - - function bisector(f) { - let delta = f; - let compare1 = f; - let compare2 = f; - - if (f.length !== 2) { - delta = (d, x) => f(d) - x; - compare1 = ascending_ascending; - compare2 = (d, x) => ascending_ascending(f(d), x); - } - - function left(a, x, lo = 0, hi = a.length) { - if (lo < hi) { - if (compare1(x, x) !== 0) return hi; - do { - const mid = (lo + hi) >>> 1; - if (compare2(a[mid], x) < 0) lo = mid + 1; - else hi = mid; - } while (lo < hi); - } - return lo; - } - - function right(a, x, lo = 0, hi = a.length) { - if (lo < hi) { - if (compare1(x, x) !== 0) return hi; - do { - const mid = (lo + hi) >>> 1; - if (compare2(a[mid], x) <= 0) lo = mid + 1; - else hi = mid; - } while (lo < hi); - } - return lo; - } - - function center(a, x, lo = 0, hi = a.length) { - const i = left(a, x, lo, hi - 1); - return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; - } - - return { left, center, right }; - } // CONCATENATED MODULE: ../node_modules/d3-array/src/number.js - - function number(x) { - return x === null ? NaN : +x; - } - - function* numbers(values, valueof) { - if (valueof === undefined) { - for (let value of values) { - if (value != null && (value = +value) >= value) { - yield value; - } - } - } else { - let index = -1; - for (let value of values) { - if ( - (value = valueof(value, ++index, values)) != null && - (value = +value) >= value - ) { - yield value; - } - } - } - } // CONCATENATED MODULE: ../node_modules/d3-array/src/bisect.js - - const ascendingBisect = bisector(ascending_ascending); - const bisectRight = ascendingBisect.right; - const bisectLeft = ascendingBisect.left; - const bisectCenter = bisector(number).center; - /* harmony default export */ const bisect = bisectRight; // CONCATENATED MODULE: ../node_modules/d3-color/src/define.js - - /* harmony default export */ function src_define( - constructor, - factory, - prototype, - ) { - constructor.prototype = factory.prototype = prototype; - prototype.constructor = constructor; - } - - function extend(parent, definition) { - var prototype = Object.create(parent.prototype); - for (var key in definition) prototype[key] = definition[key]; - return prototype; - } // CONCATENATED MODULE: ../node_modules/d3-color/src/color.js - - function Color() {} - - var darker = 0.7; - var brighter = 1 / darker; - - var reI = '\\s*([+-]?\\d+)\\s*', - reN = '\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*', - reP = '\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*', - reHex = /^#([0-9a-f]{3,8})$/, - reRgbInteger = new RegExp('^rgb\\(' + [reI, reI, reI] + '\\)$'), - reRgbPercent = new RegExp('^rgb\\(' + [reP, reP, reP] + '\\)$'), - reRgbaInteger = new RegExp('^rgba\\(' + [reI, reI, reI, reN] + '\\)$'), - reRgbaPercent = new RegExp('^rgba\\(' + [reP, reP, reP, reN] + '\\)$'), - reHslPercent = new RegExp('^hsl\\(' + [reN, reP, reP] + '\\)$'), - reHslaPercent = new RegExp('^hsla\\(' + [reN, reP, reP, reN] + '\\)$'); - - var named = { - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - rebeccapurple: 0x663399, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32, - }; - - src_define(Color, color, { - copy: function (channels) { - return Object.assign(new this.constructor(), this, channels); - }, - displayable: function () { - return this.rgb().displayable(); - }, - hex: color_formatHex, // Deprecated! Use color.formatHex. - formatHex: color_formatHex, - formatHsl: color_formatHsl, - formatRgb: color_formatRgb, - toString: color_formatRgb, - }); - - function color_formatHex() { - return this.rgb().formatHex(); - } - - function color_formatHsl() { - return hslConvert(this).formatHsl(); - } - - function color_formatRgb() { - return this.rgb().formatRgb(); - } - - function color(format) { - var m, l; - format = (format + '').trim().toLowerCase(); - return (m = reHex.exec(format)) - ? ((l = m[1].length), - (m = parseInt(m[1], 16)), - l === 6 - ? rgbn(m) // #ff0000 - : l === 3 - ? new Rgb( - ((m >> 8) & 0xf) | ((m >> 4) & 0xf0), - ((m >> 4) & 0xf) | (m & 0xf0), - ((m & 0xf) << 4) | (m & 0xf), - 1, - ) // #f00 - : l === 8 - ? rgba( - (m >> 24) & 0xff, - (m >> 16) & 0xff, - (m >> 8) & 0xff, - (m & 0xff) / 0xff, - ) // #ff000000 - : l === 4 - ? rgba( - ((m >> 12) & 0xf) | ((m >> 8) & 0xf0), - ((m >> 8) & 0xf) | ((m >> 4) & 0xf0), - ((m >> 4) & 0xf) | (m & 0xf0), - (((m & 0xf) << 4) | (m & 0xf)) / 0xff, - ) // #f000 - : null) // invalid hex - : (m = reRgbInteger.exec(format)) - ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) - : (m = reRgbPercent.exec(format)) - ? new Rgb((m[1] * 255) / 100, (m[2] * 255) / 100, (m[3] * 255) / 100, 1) // rgb(100%, 0%, 0%) - : (m = reRgbaInteger.exec(format)) - ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) - : (m = reRgbaPercent.exec(format)) - ? rgba((m[1] * 255) / 100, (m[2] * 255) / 100, (m[3] * 255) / 100, m[4]) // rgb(100%, 0%, 0%, 1) - : (m = reHslPercent.exec(format)) - ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) - : (m = reHslaPercent.exec(format)) - ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) - : named.hasOwnProperty(format) - ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins - : format === 'transparent' - ? new Rgb(NaN, NaN, NaN, 0) - : null; - } - - function rgbn(n) { - return new Rgb((n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff, 1); - } - - function rgba(r, g, b, a) { - if (a <= 0) r = g = b = NaN; - return new Rgb(r, g, b, a); - } - - function rgbConvert(o) { - if (!(o instanceof Color)) o = color(o); - if (!o) return new Rgb(); - o = o.rgb(); - return new Rgb(o.r, o.g, o.b, o.opacity); - } - - function color_rgb(r, g, b, opacity) { - return arguments.length === 1 - ? rgbConvert(r) - : new Rgb(r, g, b, opacity == null ? 1 : opacity); - } - - function Rgb(r, g, b, opacity) { - this.r = +r; - this.g = +g; - this.b = +b; - this.opacity = +opacity; - } - - src_define( - Rgb, - color_rgb, - extend(Color, { - brighter: function (k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - darker: function (k) { - k = k == null ? darker : Math.pow(darker, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - rgb: function () { - return this; - }, - displayable: function () { - return ( - -0.5 <= this.r && - this.r < 255.5 && - -0.5 <= this.g && - this.g < 255.5 && - -0.5 <= this.b && - this.b < 255.5 && - 0 <= this.opacity && - this.opacity <= 1 - ); - }, - hex: rgb_formatHex, // Deprecated! Use color.formatHex. - formatHex: rgb_formatHex, - formatRgb: rgb_formatRgb, - toString: rgb_formatRgb, - }), - ); - - function rgb_formatHex() { - return '#' + hex(this.r) + hex(this.g) + hex(this.b); - } - - function rgb_formatRgb() { - var a = this.opacity; - a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return ( - (a === 1 ? 'rgb(' : 'rgba(') + - Math.max(0, Math.min(255, Math.round(this.r) || 0)) + - ', ' + - Math.max(0, Math.min(255, Math.round(this.g) || 0)) + - ', ' + - Math.max(0, Math.min(255, Math.round(this.b) || 0)) + - (a === 1 ? ')' : ', ' + a + ')') - ); - } - - function hex(value) { - value = Math.max(0, Math.min(255, Math.round(value) || 0)); - return (value < 16 ? '0' : '') + value.toString(16); - } - - function hsla(h, s, l, a) { - if (a <= 0) h = s = l = NaN; - else if (l <= 0 || l >= 1) h = s = NaN; - else if (s <= 0) h = NaN; - return new Hsl(h, s, l, a); - } - - function hslConvert(o) { - if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Color)) o = color(o); - if (!o) return new Hsl(); - if (o instanceof Hsl) return o; - o = o.rgb(); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - h = NaN, - s = max - min, - l = (max + min) / 2; - if (s) { - if (r === max) h = (g - b) / s + (g < b) * 6; - else if (g === max) h = (b - r) / s + 2; - else h = (r - g) / s + 4; - s /= l < 0.5 ? max + min : 2 - max - min; - h *= 60; - } else { - s = l > 0 && l < 1 ? 0 : h; - } - return new Hsl(h, s, l, o.opacity); - } - - function hsl(h, s, l, opacity) { - return arguments.length === 1 - ? hslConvert(h) - : new Hsl(h, s, l, opacity == null ? 1 : opacity); - } - - function Hsl(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; - } - - src_define( - Hsl, - hsl, - extend(Color, { - brighter: function (k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - darker: function (k) { - k = k == null ? darker : Math.pow(darker, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function () { - var h = (this.h % 360) + (this.h < 0) * 360, - s = isNaN(h) || isNaN(this.s) ? 0 : this.s, - l = this.l, - m2 = l + (l < 0.5 ? l : 1 - l) * s, - m1 = 2 * l - m2; - return new Rgb( - hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), - hsl2rgb(h, m1, m2), - hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), - this.opacity, - ); - }, - displayable: function () { - return ( - ((0 <= this.s && this.s <= 1) || isNaN(this.s)) && - 0 <= this.l && - this.l <= 1 && - 0 <= this.opacity && - this.opacity <= 1 - ); - }, - formatHsl: function () { - var a = this.opacity; - a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return ( - (a === 1 ? 'hsl(' : 'hsla(') + - (this.h || 0) + - ', ' + - (this.s || 0) * 100 + - '%, ' + - (this.l || 0) * 100 + - '%' + - (a === 1 ? ')' : ', ' + a + ')') - ); - }, - }), - ); - - /* From FvD 13.37, CSS Color Module Level 3 */ - function hsl2rgb(h, m1, m2) { - return ( - (h < 60 - ? m1 + ((m2 - m1) * h) / 60 - : h < 180 - ? m2 - : h < 240 - ? m1 + ((m2 - m1) * (240 - h)) / 60 - : m1) * 255 - ); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/basis.js - - function basis(t1, v0, v1, v2, v3) { - var t2 = t1 * t1, - t3 = t2 * t1; - return ( - ((1 - 3 * t1 + 3 * t2 - t3) * v0 + - (4 - 6 * t2 + 3 * t3) * v1 + - (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + - t3 * v3) / - 6 - ); - } - - /* harmony default export */ function src_basis(values) { - var n = values.length - 1; - return function (t) { - var i = - t <= 0 ? (t = 0) : t >= 1 ? ((t = 1), n - 1) : Math.floor(t * n), - v1 = values[i], - v2 = values[i + 1], - v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, - v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; - return basis((t - i / n) * n, v0, v1, v2, v3); - }; - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/basisClosed.js - - /* harmony default export */ function basisClosed(values) { - var n = values.length; - return function (t) { - var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), - v0 = values[(i + n - 1) % n], - v1 = values[i % n], - v2 = values[(i + 1) % n], - v3 = values[(i + 2) % n]; - return basis((t - i / n) * n, v0, v1, v2, v3); - }; - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/constant.js - - /* harmony default export */ const d3_interpolate_src_constant = ( - x, - ) => () => x; // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/color.js - - function linear(a, d) { - return function (t) { - return a + t * d; - }; - } - - function exponential(a, b, y) { - return ( - (a = Math.pow(a, y)), - (b = Math.pow(b, y) - a), - (y = 1 / y), - function (t) { - return Math.pow(a + t * b, y); - } - ); - } - - function hue(a, b) { - var d = b - a; - return d - ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) - : constant(isNaN(a) ? b : a); - } - - function gamma(y) { - return (y = +y) === 1 - ? nogamma - : function (a, b) { - return b - a - ? exponential(a, b, y) - : d3_interpolate_src_constant(isNaN(a) ? b : a); - }; - } - - function nogamma(a, b) { - var d = b - a; - return d ? linear(a, d) : d3_interpolate_src_constant(isNaN(a) ? b : a); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/rgb.js - - /* harmony default export */ const rgb = (function rgbGamma(y) { - var color = gamma(y); - - function rgb(start, end) { - var r = color((start = color_rgb(start)).r, (end = color_rgb(end)).r), - g = color(start.g, end.g), - b = color(start.b, end.b), - opacity = nogamma(start.opacity, end.opacity); - return function (t) { - start.r = r(t); - start.g = g(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ''; - }; - } - - rgb.gamma = rgbGamma; - - return rgb; - })(1); - - function rgbSpline(spline) { - return function (colors) { - var n = colors.length, - r = new Array(n), - g = new Array(n), - b = new Array(n), - i, - color; - for (i = 0; i < n; ++i) { - color = color_rgb(colors[i]); - r[i] = color.r || 0; - g[i] = color.g || 0; - b[i] = color.b || 0; - } - r = spline(r); - g = spline(g); - b = spline(b); - color.opacity = 1; - return function (t) { - color.r = r(t); - color.g = g(t); - color.b = b(t); - return color + ''; - }; - }; - } - - var rgbBasis = rgbSpline(src_basis); - var rgbBasisClosed = rgbSpline(basisClosed); // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/array.js - - /* harmony default export */ function src_array(a, b) { - return (isNumberArray(b) ? numberArray : genericArray)(a, b); - } - - function genericArray(a, b) { - var nb = b ? b.length : 0, - na = a ? Math.min(nb, a.length) : 0, - x = new Array(na), - c = new Array(nb), - i; - - for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]); - for (; i < nb; ++i) c[i] = b[i]; - - return function (t) { - for (i = 0; i < na; ++i) c[i] = x[i](t); - return c; - }; - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/date.js - - /* harmony default export */ function date(a, b) { - var d = new Date(); - return ( - (a = +a), - (b = +b), - function (t) { - return d.setTime(a * (1 - t) + b * t), d; - } - ); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/number.js - - /* harmony default export */ function src_number(a, b) { - return ( - (a = +a), - (b = +b), - function (t) { - return a * (1 - t) + b * t; - } - ); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/object.js - - /* harmony default export */ function object(a, b) { - var i = {}, - c = {}, - k; - - if (a === null || typeof a !== 'object') a = {}; - if (b === null || typeof b !== 'object') b = {}; - - for (k in b) { - if (k in a) { - i[k] = value(a[k], b[k]); - } else { - c[k] = b[k]; - } - } - - return function (t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/string.js - - var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, - reB = new RegExp(reA.source, 'g'); - - function zero(b) { - return function () { - return b; - }; - } - - function one(b) { - return function (t) { - return b(t) + ''; - }; - } - - /* harmony default export */ function string(a, b) { - var bi = (reA.lastIndex = reB.lastIndex = 0), // scan index for next number in b - am, // current match in a - bm, // current match in b - bs, // string preceding current number in b, if any - i = -1, // index in s - s = [], // string constants and placeholders - q = []; // number interpolators - - // Coerce inputs to strings. - (a = a + ''), (b = b + ''); - - // Interpolate pairs of numbers in a & b. - while ((am = reA.exec(a)) && (bm = reB.exec(b))) { - if ((bs = bm.index) > bi) { - // a string precedes the next number in b - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; - // coalesce with previous string - else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { - // numbers in a & b match - if (s[i]) s[i] += bm; - // coalesce with previous string - else s[++i] = bm; - } else { - // interpolate non-matching numbers - s[++i] = null; - q.push({ i: i, x: src_number(am, bm) }); - } - bi = reB.lastIndex; - } - - // Add remains of b. - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; - // coalesce with previous string - else s[++i] = bs; - } - - // Special optimization for only a single match. - // Otherwise, interpolate each of the numbers and rejoin the string. - return s.length < 2 - ? q[0] - ? one(q[0].x) - : zero(b) - : ((b = q.length), - function (t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(''); - }); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/numberArray.js - - /* harmony default export */ function src_numberArray(a, b) { - if (!b) b = []; - var n = a ? Math.min(b.length, a.length) : 0, - c = b.slice(), - i; - return function (t) { - for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; - return c; - }; - } - - function numberArray_isNumberArray(x) { - return ArrayBuffer.isView(x) && !(x instanceof DataView); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/value.js - - /* harmony default export */ function value(a, b) { - var t = typeof b, - c; - return b == null || t === 'boolean' - ? d3_interpolate_src_constant(b) - : (t === 'number' - ? src_number - : t === 'string' - ? (c = color(b)) - ? ((b = c), rgb) - : string - : b instanceof color - ? rgb - : b instanceof Date - ? date - : numberArray_isNumberArray(b) - ? src_numberArray - : Array.isArray(b) - ? genericArray - : (typeof b.valueOf !== 'function' && - typeof b.toString !== 'function') || - isNaN(b) - ? object - : src_number)(a, b); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/round.js - - /* harmony default export */ function round(a, b) { - return ( - (a = +a), - (b = +b), - function (t) { - return Math.round(a * (1 - t) + b * t); - } - ); - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/constant.js - - function constants(x) { - return function () { - return x; - }; - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/number.js - - function number_number(x) { - return +x; - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/continuous.js - - var unit = [0, 1]; - - function continuous_identity(x) { - return x; - } - - function normalize(a, b) { - return (b -= a = +a) - ? function (x) { - return (x - a) / b; - } - : constants(isNaN(b) ? NaN : 0.5); - } - - function clamper(a, b) { - var t; - if (a > b) (t = a), (a = b), (b = t); - return function (x) { - return Math.max(a, Math.min(b, x)); - }; - } - - // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. - // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. - function bimap(domain, range, interpolate) { - var d0 = domain[0], - d1 = domain[1], - r0 = range[0], - r1 = range[1]; - if (d1 < d0) (d0 = normalize(d1, d0)), (r0 = interpolate(r1, r0)); - else (d0 = normalize(d0, d1)), (r0 = interpolate(r0, r1)); - return function (x) { - return r0(d0(x)); - }; - } - - function polymap(domain, range, interpolate) { - var j = Math.min(domain.length, range.length) - 1, - d = new Array(j), - r = new Array(j), - i = -1; - - // Reverse descending domains. - if (domain[j] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - - while (++i < j) { - d[i] = normalize(domain[i], domain[i + 1]); - r[i] = interpolate(range[i], range[i + 1]); - } - - return function (x) { - var i = bisect(domain, x, 1, j) - 1; - return r[i](d[i](x)); - }; - } - - function copy(source, target) { - return target - .domain(source.domain()) - .range(source.range()) - .interpolate(source.interpolate()) - .clamp(source.clamp()) - .unknown(source.unknown()); - } - - function transformer() { - var domain = unit, - range = unit, - interpolate = value, - transform, - untransform, - unknown, - clamp = continuous_identity, - piecewise, - output, - input; - - function rescale() { - var n = Math.min(domain.length, range.length); - if (clamp !== continuous_identity) - clamp = clamper(domain[0], domain[n - 1]); - piecewise = n > 2 ? polymap : bimap; - output = input = null; - return scale; - } - - function scale(x) { - return x == null || isNaN((x = +x)) - ? unknown - : ( - output || - (output = piecewise(domain.map(transform), range, interpolate)) - )(transform(clamp(x))); - } - - scale.invert = function (y) { - return clamp( - untransform( - ( - input || - (input = piecewise(range, domain.map(transform), src_number)) - )(y), - ), - ); - }; - - scale.domain = function (_) { - return arguments.length - ? ((domain = Array.from(_, number_number)), rescale()) - : domain.slice(); - }; - - scale.range = function (_) { - return arguments.length - ? ((range = Array.from(_)), rescale()) - : range.slice(); - }; - - scale.rangeRound = function (_) { - return (range = Array.from(_)), (interpolate = round), rescale(); - }; - - scale.clamp = function (_) { - return arguments.length - ? ((clamp = _ ? true : continuous_identity), rescale()) - : clamp !== continuous_identity; - }; - - scale.interpolate = function (_) { - return arguments.length ? ((interpolate = _), rescale()) : interpolate; - }; - - scale.unknown = function (_) { - return arguments.length ? ((unknown = _), scale) : unknown; - }; - - return function (t, u) { - (transform = t), (untransform = u); - return rescale(); - }; - } - - function continuous() { - return transformer()(continuous_identity, continuous_identity); - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/init.js - - function initRange(domain, range) { - switch (arguments.length) { - case 0: - break; - case 1: - this.range(domain); - break; - default: - this.range(range).domain(domain); - break; - } - return this; - } - - function initInterpolator(domain, interpolator) { - switch (arguments.length) { - case 0: - break; - case 1: { - if (typeof domain === 'function') this.interpolator(domain); - else this.range(domain); - break; - } - default: { - this.domain(domain); - if (typeof interpolator === 'function') - this.interpolator(interpolator); - else this.range(interpolator); - break; - } - } - return this; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/precisionPrefix.js - - /* harmony default export */ function precisionPrefix(step, value) { - return Math.max( - 0, - Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - - exponent(Math.abs(step)), - ); - } // CONCATENATED MODULE: ../node_modules/d3-format/src/precisionRound.js - - /* harmony default export */ function precisionRound(step, max) { - (step = Math.abs(step)), (max = Math.abs(max) - step); - return Math.max(0, exponent(max) - exponent(step)) + 1; - } // CONCATENATED MODULE: ../node_modules/d3-format/src/precisionFixed.js - - /* harmony default export */ function precisionFixed(step) { - return Math.max(0, -exponent(Math.abs(step))); - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/tickFormat.js - - function tickFormat(start, stop, count, specifier) { - var step = tickStep(start, stop, count), - precision; - specifier = formatSpecifier(specifier == null ? ',f' : specifier); - switch (specifier.type) { - case 's': { - var value = Math.max(Math.abs(start), Math.abs(stop)); - if ( - specifier.precision == null && - !isNaN((precision = precisionPrefix(step, value))) - ) - specifier.precision = precision; - return formatPrefix(specifier, value); - } - case '': - case 'e': - case 'g': - case 'p': - case 'r': { - if ( - specifier.precision == null && - !isNaN( - (precision = precisionRound( - step, - Math.max(Math.abs(start), Math.abs(stop)), - )), - ) - ) - specifier.precision = precision - (specifier.type === 'e'); - break; - } - case 'f': - case '%': { - if ( - specifier.precision == null && - !isNaN((precision = precisionFixed(step))) - ) - specifier.precision = precision - (specifier.type === '%') * 2; - break; - } - } - return format(specifier); - } // CONCATENATED MODULE: ../node_modules/d3-scale/src/linear.js - - function linearish(scale) { - var domain = scale.domain; - - scale.ticks = function (count) { - var d = domain(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; - - scale.tickFormat = function (count, specifier) { - var d = domain(); - return tickFormat( - d[0], - d[d.length - 1], - count == null ? 10 : count, - specifier, - ); - }; - - scale.nice = function (count) { - if (count == null) count = 10; - - var d = domain(); - var i0 = 0; - var i1 = d.length - 1; - var start = d[i0]; - var stop = d[i1]; - var prestep; - var step; - var maxIter = 10; - - if (stop < start) { - (step = start), (start = stop), (stop = step); - (step = i0), (i0 = i1), (i1 = step); - } - - while (maxIter-- > 0) { - step = tickIncrement(start, stop, count); - if (step === prestep) { - d[i0] = start; - d[i1] = stop; - return domain(d); - } else if (step > 0) { - start = Math.floor(start / step) * step; - stop = Math.ceil(stop / step) * step; - } else if (step < 0) { - start = Math.ceil(start * step) / step; - stop = Math.floor(stop * step) / step; - } else { - break; - } - prestep = step; - } - - return scale; - }; - - return scale; - } - - function linear_linear() { - var scale = continuous(); - - scale.copy = function () { - return copy(scale, linear_linear()); - }; - - initRange.apply(scale, arguments); - - return linearish(scale); - } // CONCATENATED MODULE: ../node_modules/d3-ease/src/cubic.js - - function cubicIn(t) { - return t * t * t; - } - - function cubicOut(t) { - return --t * t * t + 1; - } - - function cubicInOut(t) { - return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; - } // CONCATENATED MODULE: ../node_modules/d3-dispatch/src/dispatch.js - - var noop = { value: () => {} }; - - function dispatch_dispatch() { - for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { - if (!(t = arguments[i] + '') || t in _ || /[\s.]/.test(t)) - throw new Error('illegal type: ' + t); - _[t] = []; - } - return new Dispatch(_); - } - - function Dispatch(_) { - this._ = _; - } - - function dispatch_parseTypenames(typenames, types) { - return typenames - .trim() - .split(/^|\s+/) - .map(function (t) { - var name = '', - i = t.indexOf('.'); - if (i >= 0) (name = t.slice(i + 1)), (t = t.slice(0, i)); - if (t && !types.hasOwnProperty(t)) - throw new Error('unknown type: ' + t); - return { type: t, name: name }; - }); - } - - Dispatch.prototype = dispatch_dispatch.prototype = { - constructor: Dispatch, - on: function (typename, callback) { - var _ = this._, - T = dispatch_parseTypenames(typename + '', _), - t, - i = -1, - n = T.length; - - // If no callback was specified, return the callback of the given type and name. - if (arguments.length < 2) { - while (++i < n) - if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) - return t; - return; - } - - // If a type was specified, set the callback for the given type and name. - // Otherwise, if a null callback was specified, remove callbacks of the given name. - if (callback != null && typeof callback !== 'function') - throw new Error('invalid callback: ' + callback); - while (++i < n) { - if ((t = (typename = T[i]).type)) - _[t] = set(_[t], typename.name, callback); - else if (callback == null) - for (t in _) _[t] = set(_[t], typename.name, null); - } - - return this; - }, - copy: function () { - var copy = {}, - _ = this._; - for (var t in _) copy[t] = _[t].slice(); - return new Dispatch(copy); - }, - call: function (type, that) { - if ((n = arguments.length - 2) > 0) - for (var args = new Array(n), i = 0, n, t; i < n; ++i) - args[i] = arguments[i + 2]; - if (!this._.hasOwnProperty(type)) - throw new Error('unknown type: ' + type); - for (t = this._[type], i = 0, n = t.length; i < n; ++i) - t[i].value.apply(that, args); - }, - apply: function (type, that, args) { - if (!this._.hasOwnProperty(type)) - throw new Error('unknown type: ' + type); - for (var t = this._[type], i = 0, n = t.length; i < n; ++i) - t[i].value.apply(that, args); - }, - }; - - function get(type, name) { - for (var i = 0, n = type.length, c; i < n; ++i) { - if ((c = type[i]).name === name) { - return c.value; - } - } - } - - function set(type, name, callback) { - for (var i = 0, n = type.length; i < n; ++i) { - if (type[i].name === name) { - (type[i] = noop), (type = type.slice(0, i).concat(type.slice(i + 1))); - break; - } - } - if (callback != null) type.push({ name: name, value: callback }); - return type; - } - - /* harmony default export */ const src_dispatch = dispatch_dispatch; // CONCATENATED MODULE: ../node_modules/d3-timer/src/timer.js - - var timer_frame = 0, // is an animation frame pending? - timeout = 0, // is a timeout pending? - interval = 0, // are any timers active? - pokeDelay = 1000, // how frequently we check for clock skew - taskHead, - taskTail, - clockLast = 0, - clockNow = 0, - clockSkew = 0, - clock = - typeof performance === 'object' && performance.now ? performance : Date, - setFrame = - typeof window === 'object' && window.requestAnimationFrame - ? window.requestAnimationFrame.bind(window) - : function (f) { - setTimeout(f, 17); - }; - - function now() { - return ( - clockNow || (setFrame(clearNow), (clockNow = clock.now() + clockSkew)) - ); - } - - function clearNow() { - clockNow = 0; - } - - function Timer() { - this._call = this._time = this._next = null; - } - - Timer.prototype = timer.prototype = { - constructor: Timer, - restart: function (callback, delay, time) { - if (typeof callback !== 'function') - throw new TypeError('callback is not a function'); - time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); - if (!this._next && taskTail !== this) { - if (taskTail) taskTail._next = this; - else taskHead = this; - taskTail = this; - } - this._call = callback; - this._time = time; - sleep(); - }, - stop: function () { - if (this._call) { - this._call = null; - this._time = Infinity; - sleep(); - } - }, - }; - - function timer(callback, delay, time) { - var t = new Timer(); - t.restart(callback, delay, time); - return t; - } - - function timerFlush() { - now(); // Get the current time, if not already set. - ++timer_frame; // Pretend we’ve set an alarm, if we haven’t already. - var t = taskHead, - e; - while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e); - t = t._next; - } - --timer_frame; - } - - function wake() { - clockNow = (clockLast = clock.now()) + clockSkew; - timer_frame = timeout = 0; - try { - timerFlush(); - } finally { - timer_frame = 0; - nap(); - clockNow = 0; - } - } - - function poke() { - var now = clock.now(), - delay = now - clockLast; - if (delay > pokeDelay) (clockSkew -= delay), (clockLast = now); - } - - function nap() { - var t0, - t1 = taskHead, - t2, - time = Infinity; - while (t1) { - if (t1._call) { - if (time > t1._time) time = t1._time; - (t0 = t1), (t1 = t1._next); - } else { - (t2 = t1._next), (t1._next = null); - t1 = t0 ? (t0._next = t2) : (taskHead = t2); - } - } - taskTail = t0; - sleep(time); - } - - function sleep(time) { - if (timer_frame) return; // Soonest alarm already set, or will be. - if (timeout) timeout = clearTimeout(timeout); - var delay = time - clockNow; // Strictly less than if we recomputed clockNow. - if (delay > 24) { - if (time < Infinity) - timeout = setTimeout(wake, time - clock.now() - clockSkew); - if (interval) interval = clearInterval(interval); - } else { - if (!interval) - (clockLast = clock.now()), (interval = setInterval(poke, pokeDelay)); - (timer_frame = 1), setFrame(wake); - } - } // CONCATENATED MODULE: ../node_modules/d3-timer/src/timeout.js - - /* harmony default export */ function src_timeout(callback, delay, time) { - var t = new Timer(); - delay = delay == null ? 0 : +delay; - t.restart( - (elapsed) => { - t.stop(); - callback(elapsed + delay); - }, - delay, - time, - ); - return t; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/schedule.js - - var emptyOn = src_dispatch('start', 'end', 'cancel', 'interrupt'); - var emptyTween = []; - - var CREATED = 0; - var SCHEDULED = 1; - var STARTING = 2; - var STARTED = 3; - var RUNNING = 4; - var ENDING = 5; - var ENDED = 6; - - /* harmony default export */ function schedule( - node, - name, - id, - index, - group, - timing, - ) { - var schedules = node.__transition; - if (!schedules) node.__transition = {}; - else if (id in schedules) return; - create(node, id, { - name: name, - index: index, // For context during callback. - group: group, // For context during callback. - on: emptyOn, - tween: emptyTween, - time: timing.time, - delay: timing.delay, - duration: timing.duration, - ease: timing.ease, - timer: null, - state: CREATED, - }); - } - - function init(node, id) { - var schedule = schedule_get(node, id); - if (schedule.state > CREATED) - throw new Error('too late; already scheduled'); - return schedule; - } - - function schedule_set(node, id) { - var schedule = schedule_get(node, id); - if (schedule.state > STARTED) - throw new Error('too late; already running'); - return schedule; - } - - function schedule_get(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id])) - throw new Error('transition not found'); - return schedule; - } - - function create(node, id, self) { - var schedules = node.__transition, - tween; - - // Initialize the self timer when the transition is created. - // Note the actual delay is not known until the first callback! - schedules[id] = self; - self.timer = timer(schedule, 0, self.time); - - function schedule(elapsed) { - self.state = SCHEDULED; - self.timer.restart(start, self.delay, self.time); - - // If the elapsed delay is less than our first sleep, start immediately. - if (self.delay <= elapsed) start(elapsed - self.delay); - } - - function start(elapsed) { - var i, j, n, o; - - // If the state is not SCHEDULED, then we previously errored on start. - if (self.state !== SCHEDULED) return stop(); - - for (i in schedules) { - o = schedules[i]; - if (o.name !== self.name) continue; - - // While this element already has a starting transition during this frame, - // defer starting an interrupting transition until that transition has a - // chance to tick (and possibly end); see d3/d3-transition#54! - if (o.state === STARTED) return src_timeout(start); - - // Interrupt the active transition, if any. - if (o.state === RUNNING) { - o.state = ENDED; - o.timer.stop(); - o.on.call('interrupt', node, node.__data__, o.index, o.group); - delete schedules[i]; - } - - // Cancel any pre-empted transitions. - else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - o.on.call('cancel', node, node.__data__, o.index, o.group); - delete schedules[i]; - } - } - - // Defer the first tick to end of the current frame; see d3/d3#1576. - // Note the transition may be canceled after start and before the first tick! - // Note this must be scheduled before the start event; see d3/d3-transition#16! - // Assuming this is successful, subsequent callbacks go straight to tick. - src_timeout(function () { - if (self.state === STARTED) { - self.state = RUNNING; - self.timer.restart(tick, self.delay, self.time); - tick(elapsed); - } - }); - - // Dispatch the start event. - // Note this must be done before the tween are initialized. - self.state = STARTING; - self.on.call('start', node, node.__data__, self.index, self.group); - if (self.state !== STARTING) return; // interrupted - self.state = STARTED; - - // Initialize the tween, deleting null tween. - tween = new Array((n = self.tween.length)); - for (i = 0, j = -1; i < n; ++i) { - if ( - (o = self.tween[i].value.call( - node, - node.__data__, - self.index, - self.group, - )) - ) { - tween[++j] = o; - } - } - tween.length = j + 1; - } - - function tick(elapsed) { - var t = - elapsed < self.duration - ? self.ease.call(null, elapsed / self.duration) - : (self.timer.restart(stop), (self.state = ENDING), 1), - i = -1, - n = tween.length; - - while (++i < n) { - tween[i].call(node, t); - } - - // Dispatch the end event. - if (self.state === ENDING) { - self.on.call('end', node, node.__data__, self.index, self.group); - stop(); - } - } - - function stop() { - self.state = ENDED; - self.timer.stop(); - delete schedules[id]; - for (var i in schedules) return; // eslint-disable-line no-unused-vars - delete node.__transition; - } - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/interrupt.js - - /* harmony default export */ function interrupt(node, name) { - var schedules = node.__transition, - schedule, - active, - empty = true, - i; - - if (!schedules) return; - - name = name == null ? null : name + ''; - - for (i in schedules) { - if ((schedule = schedules[i]).name !== name) { - empty = false; - continue; - } - active = schedule.state > STARTING && schedule.state < ENDING; - schedule.state = ENDED; - schedule.timer.stop(); - schedule.on.call( - active ? 'interrupt' : 'cancel', - node, - node.__data__, - schedule.index, - schedule.group, - ); - delete schedules[i]; - } - - if (empty) delete node.__transition; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/interrupt.js - - /* harmony default export */ function selection_interrupt(name) { - return this.each(function () { - interrupt(this, name); - }); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/decompose.js - - var degrees = 180 / Math.PI; - - var decompose_identity = { - translateX: 0, - translateY: 0, - rotate: 0, - skewX: 0, - scaleX: 1, - scaleY: 1, - }; - - /* harmony default export */ function decompose(a, b, c, d, e, f) { - var scaleX, scaleY, skewX; - if ((scaleX = Math.sqrt(a * a + b * b))) (a /= scaleX), (b /= scaleX); - if ((skewX = a * c + b * d)) (c -= a * skewX), (d -= b * skewX); - if ((scaleY = Math.sqrt(c * c + d * d))) - (c /= scaleY), (d /= scaleY), (skewX /= scaleY); - if (a * d < b * c) - (a = -a), (b = -b), (skewX = -skewX), (scaleX = -scaleX); - return { - translateX: e, - translateY: f, - rotate: Math.atan2(b, a) * degrees, - skewX: Math.atan(skewX) * degrees, - scaleX: scaleX, - scaleY: scaleY, - }; - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/parse.js - - var svgNode; - - /* eslint-disable no-undef */ - function parseCss(value) { - const m = new (typeof DOMMatrix === 'function' - ? DOMMatrix - : WebKitCSSMatrix)(value + ''); - return m.isIdentity - ? decompose_identity - : decompose(m.a, m.b, m.c, m.d, m.e, m.f); - } - - function parseSvg(value) { - if (value == null) return decompose_identity; - if (!svgNode) - svgNode = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - svgNode.setAttribute('transform', value); - if (!(value = svgNode.transform.baseVal.consolidate())) - return decompose_identity; - value = value.matrix; - return decompose(value.a, value.b, value.c, value.d, value.e, value.f); - } // CONCATENATED MODULE: ../node_modules/d3-interpolate/src/transform/index.js - - function interpolateTransform(parse, pxComma, pxParen, degParen) { - function pop(s) { - return s.length ? s.pop() + ' ' : ''; - } - - function translate(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push('translate(', null, pxComma, null, pxParen); - q.push( - { i: i - 4, x: src_number(xa, xb) }, - { i: i - 2, x: src_number(ya, yb) }, - ); - } else if (xb || yb) { - s.push('translate(' + xb + pxComma + yb + pxParen); - } - } - - function rotate(a, b, s, q) { - if (a !== b) { - if (a - b > 180) b += 360; - else if (b - a > 180) a += 360; // shortest path - q.push({ - i: s.push(pop(s) + 'rotate(', null, degParen) - 2, - x: src_number(a, b), - }); - } else if (b) { - s.push(pop(s) + 'rotate(' + b + degParen); - } - } - - function skewX(a, b, s, q) { - if (a !== b) { - q.push({ - i: s.push(pop(s) + 'skewX(', null, degParen) - 2, - x: src_number(a, b), - }); - } else if (b) { - s.push(pop(s) + 'skewX(' + b + degParen); - } - } - - function scale(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push(pop(s) + 'scale(', null, ',', null, ')'); - q.push( - { i: i - 4, x: src_number(xa, xb) }, - { i: i - 2, x: src_number(ya, yb) }, - ); - } else if (xb !== 1 || yb !== 1) { - s.push(pop(s) + 'scale(' + xb + ',' + yb + ')'); - } - } - - return function (a, b) { - var s = [], // string constants and placeholders - q = []; // number interpolators - (a = parse(a)), (b = parse(b)); - translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); - rotate(a.rotate, b.rotate, s, q); - skewX(a.skewX, b.skewX, s, q); - scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); - a = b = null; // gc - return function (t) { - var i = -1, - n = q.length, - o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(''); - }; - }; - } - - var interpolateTransformCss = interpolateTransform( - parseCss, - 'px, ', - 'px)', - 'deg)', - ); - var interpolateTransformSvg = interpolateTransform( - parseSvg, - ', ', - ')', - ')', - ); // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/tween.js - - function tweenRemove(id, name) { - var tween0, tween1; - return function () { - var schedule = schedule_set(this, id), - tween = schedule.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = tween0 = tween; - for (var i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1 = tween1.slice(); - tween1.splice(i, 1); - break; - } - } - } - - schedule.tween = tween1; - }; - } - - function tweenFunction(id, name, value) { - var tween0, tween1; - if (typeof value !== 'function') throw new Error(); - return function () { - var schedule = schedule_set(this, id), - tween = schedule.tween; - - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = (tween0 = tween).slice(); - for ( - var t = { name: name, value: value }, i = 0, n = tween1.length; - i < n; - ++i - ) { - if (tween1[i].name === name) { - tween1[i] = t; - break; - } - } - if (i === n) tween1.push(t); - } - - schedule.tween = tween1; - }; - } - - /* harmony default export */ function tween(name, value) { - var id = this._id; - - name += ''; - - if (arguments.length < 2) { - var tween = schedule_get(this.node(), id).tween; - for (var i = 0, n = tween.length, t; i < n; ++i) { - if ((t = tween[i]).name === name) { - return t.value; - } - } - return null; - } - - return this.each( - (value == null ? tweenRemove : tweenFunction)(id, name, value), - ); - } - - function tweenValue(transition, name, value) { - var id = transition._id; - - transition.each(function () { - var schedule = schedule_set(this, id); - (schedule.value || (schedule.value = {}))[name] = value.apply( - this, - arguments, - ); - }); - - return function (node) { - return schedule_get(node, id).value[name]; - }; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/interpolate.js - - /* harmony default export */ function interpolate(a, b) { - var c; - return (typeof b === 'number' - ? src_number - : b instanceof color - ? rgb - : (c = color(b)) - ? ((b = c), rgb) - : string)(a, b); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/attr.js - - function attr_attrRemove(name) { - return function () { - this.removeAttribute(name); - }; - } - - function attr_attrRemoveNS(fullname) { - return function () { - this.removeAttributeNS(fullname.space, fullname.local); - }; - } - - function attr_attrConstant(name, interpolate, value1) { - var string00, - string1 = value1 + '', - interpolate0; - return function () { - var string0 = this.getAttribute(name); - return string0 === string1 - ? null - : string0 === string00 - ? interpolate0 - : (interpolate0 = interpolate((string00 = string0), value1)); - }; - } - - function attr_attrConstantNS(fullname, interpolate, value1) { - var string00, - string1 = value1 + '', - interpolate0; - return function () { - var string0 = this.getAttributeNS(fullname.space, fullname.local); - return string0 === string1 - ? null - : string0 === string00 - ? interpolate0 - : (interpolate0 = interpolate((string00 = string0), value1)); - }; - } - - function attr_attrFunction(name, interpolate, value) { - var string00, string10, interpolate0; - return function () { - var string0, - value1 = value(this), - string1; - if (value1 == null) return void this.removeAttribute(name); - string0 = this.getAttribute(name); - string1 = value1 + ''; - return string0 === string1 - ? null - : string0 === string00 && string1 === string10 - ? interpolate0 - : ((string10 = string1), - (interpolate0 = interpolate((string00 = string0), value1))); - }; - } - - function attr_attrFunctionNS(fullname, interpolate, value) { - var string00, string10, interpolate0; - return function () { - var string0, - value1 = value(this), - string1; - if (value1 == null) - return void this.removeAttributeNS(fullname.space, fullname.local); - string0 = this.getAttributeNS(fullname.space, fullname.local); - string1 = value1 + ''; - return string0 === string1 - ? null - : string0 === string00 && string1 === string10 - ? interpolate0 - : ((string10 = string1), - (interpolate0 = interpolate((string00 = string0), value1))); - }; - } - - /* harmony default export */ function transition_attr(name, value) { - var fullname = namespace(name), - i = fullname === 'transform' ? interpolateTransformSvg : interpolate; - return this.attrTween( - name, - typeof value === 'function' - ? (fullname.local ? attr_attrFunctionNS : attr_attrFunction)( - fullname, - i, - tweenValue(this, 'attr.' + name, value), - ) - : value == null - ? (fullname.local ? attr_attrRemoveNS : attr_attrRemove)(fullname) - : (fullname.local ? attr_attrConstantNS : attr_attrConstant)( - fullname, - i, - value, - ), - ); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/attrTween.js - - function attrInterpolate(name, i) { - return function (t) { - this.setAttribute(name, i.call(this, t)); - }; - } - - function attrInterpolateNS(fullname, i) { - return function (t) { - this.setAttributeNS(fullname.space, fullname.local, i.call(this, t)); - }; - } - - function attrTweenNS(fullname, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i); - return t0; - } - tween._value = value; - return tween; - } - - function attrTween(name, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i); - return t0; - } - tween._value = value; - return tween; - } - - /* harmony default export */ function transition_attrTween(name, value) { - var key = 'attr.' + name; - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== 'function') throw new Error(); - var fullname = namespace(name); - return this.tween( - key, - (fullname.local ? attrTweenNS : attrTween)(fullname, value), - ); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/delay.js - - function delayFunction(id, value) { - return function () { - init(this, id).delay = +value.apply(this, arguments); - }; - } - - function delayConstant(id, value) { - return ( - (value = +value), - function () { - init(this, id).delay = value; - } - ); - } - - /* harmony default export */ function delay(value) { - var id = this._id; - - return arguments.length - ? this.each( - (typeof value === 'function' ? delayFunction : delayConstant)( - id, - value, - ), - ) - : schedule_get(this.node(), id).delay; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/duration.js - - function durationFunction(id, value) { - return function () { - schedule_set(this, id).duration = +value.apply(this, arguments); - }; - } - - function durationConstant(id, value) { - return ( - (value = +value), - function () { - schedule_set(this, id).duration = value; - } - ); - } - - /* harmony default export */ function duration(value) { - var id = this._id; - - return arguments.length - ? this.each( - (typeof value === 'function' ? durationFunction : durationConstant)( - id, - value, - ), - ) - : schedule_get(this.node(), id).duration; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/ease.js - - function easeConstant(id, value) { - if (typeof value !== 'function') throw new Error(); - return function () { - schedule_set(this, id).ease = value; - }; - } - - /* harmony default export */ function ease(value) { - var id = this._id; - - return arguments.length - ? this.each(easeConstant(id, value)) - : schedule_get(this.node(), id).ease; - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/easeVarying.js - - function easeVarying(id, value) { - return function () { - var v = value.apply(this, arguments); - if (typeof v !== 'function') throw new Error(); - schedule_set(this, id).ease = v; - }; - } - - /* harmony default export */ function transition_easeVarying(value) { - if (typeof value !== 'function') throw new Error(); - return this.each(easeVarying(this._id, value)); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/filter.js - - /* harmony default export */ function transition_filter(match) { - if (typeof match !== 'function') match = matcher(match); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = new Array(m), - j = 0; - j < m; - ++j - ) { - for ( - var group = groups[j], - n = group.length, - subgroup = (subgroups[j] = []), - node, - i = 0; - i < n; - ++i - ) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } - - return new Transition(subgroups, this._parents, this._name, this._id); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/merge.js - - /* harmony default export */ function transition_merge(transition) { - if (transition._id !== this._id) throw new Error(); - - for ( - var groups0 = this._groups, - groups1 = transition._groups, - m0 = groups0.length, - m1 = groups1.length, - m = Math.min(m0, m1), - merges = new Array(m0), - j = 0; - j < m; - ++j - ) { - for ( - var group0 = groups0[j], - group1 = groups1[j], - n = group0.length, - merge = (merges[j] = new Array(n)), - node, - i = 0; - i < n; - ++i - ) { - if ((node = group0[i] || group1[i])) { - merge[i] = node; - } - } - } - - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } - - return new Transition(merges, this._parents, this._name, this._id); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/on.js - - function start(name) { - return (name + '') - .trim() - .split(/^|\s+/) - .every(function (t) { - var i = t.indexOf('.'); - if (i >= 0) t = t.slice(0, i); - return !t || t === 'start'; - }); - } - - function onFunction(id, name, listener) { - var on0, - on1, - sit = start(name) ? init : schedule_set; - return function () { - var schedule = sit(this, id), - on = schedule.on; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); - - schedule.on = on1; - }; - } - - /* harmony default export */ function transition_on(name, listener) { - var id = this._id; - - return arguments.length < 2 - ? schedule_get(this.node(), id).on.on(name) - : this.each(onFunction(id, name, listener)); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/remove.js - - function removeFunction(id) { - return function () { - var parent = this.parentNode; - for (var i in this.__transition) if (+i !== id) return; - if (parent) parent.removeChild(this); - }; - } - - /* harmony default export */ function transition_remove() { - return this.on('end.remove', removeFunction(this._id)); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/select.js - - /* harmony default export */ function transition_select(select) { - var name = this._name, - id = this._id; - - if (typeof select !== 'function') select = selector(select); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = new Array(m), - j = 0; - j < m; - ++j - ) { - for ( - var group = groups[j], - n = group.length, - subgroup = (subgroups[j] = new Array(n)), - node, - subnode, - i = 0; - i < n; - ++i - ) { - if ( - (node = group[i]) && - (subnode = select.call(node, node.__data__, i, group)) - ) { - if ('__data__' in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - schedule( - subgroup[i], - name, - id, - i, - subgroup, - schedule_get(node, id), - ); - } - } - } - - return new Transition(subgroups, this._parents, name, id); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/selectAll.js - - /* harmony default export */ function transition_selectAll(select) { - var name = this._name, - id = this._id; - - if (typeof select !== 'function') select = selectorAll(select); - - for ( - var groups = this._groups, - m = groups.length, - subgroups = [], - parents = [], - j = 0; - j < m; - ++j - ) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if ((node = group[i])) { - for ( - var children = select.call(node, node.__data__, i, group), - child, - inherit = schedule_get(node, id), - k = 0, - l = children.length; - k < l; - ++k - ) { - if ((child = children[k])) { - schedule(child, name, id, k, children, inherit); - } - } - subgroups.push(children); - parents.push(node); - } - } - } - - return new Transition(subgroups, parents, name, id); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/selection.js - - var selection_Selection = src_selection.prototype.constructor; - - /* harmony default export */ function transition_selection() { - return new selection_Selection(this._groups, this._parents); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/style.js - - function styleNull(name, interpolate) { - var string00, string10, interpolate0; - return function () { - var string0 = styleValue(this, name), - string1 = (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 - ? null - : string0 === string00 && string1 === string10 - ? interpolate0 - : (interpolate0 = interpolate( - (string00 = string0), - (string10 = string1), - )); - }; - } - - function style_styleRemove(name) { - return function () { - this.style.removeProperty(name); - }; - } - - function style_styleConstant(name, interpolate, value1) { - var string00, - string1 = value1 + '', - interpolate0; - return function () { - var string0 = styleValue(this, name); - return string0 === string1 - ? null - : string0 === string00 - ? interpolate0 - : (interpolate0 = interpolate((string00 = string0), value1)); - }; - } - - function style_styleFunction(name, interpolate, value) { - var string00, string10, interpolate0; - return function () { - var string0 = styleValue(this, name), - value1 = value(this), - string1 = value1 + ''; - if (value1 == null) - string1 = value1 = - (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 - ? null - : string0 === string00 && string1 === string10 - ? interpolate0 - : ((string10 = string1), - (interpolate0 = interpolate((string00 = string0), value1))); - }; - } - - function styleMaybeRemove(id, name) { - var on0, - on1, - listener0, - key = 'style.' + name, - event = 'end.' + key, - remove; - return function () { - var schedule = schedule_set(this, id), - on = schedule.on, - listener = - schedule.value[key] == null - ? remove || (remove = style_styleRemove(name)) - : undefined; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0 || listener0 !== listener) - (on1 = (on0 = on).copy()).on(event, (listener0 = listener)); - - schedule.on = on1; - }; - } - - /* harmony default export */ function transition_style( - name, - value, - priority, - ) { - var i = - (name += '') === 'transform' ? interpolateTransformCss : interpolate; - return value == null - ? this.styleTween(name, styleNull(name, i)).on( - 'end.style.' + name, - style_styleRemove(name), - ) - : typeof value === 'function' - ? this.styleTween( - name, - style_styleFunction( - name, - i, - tweenValue(this, 'style.' + name, value), - ), - ).each(styleMaybeRemove(this._id, name)) - : this.styleTween( - name, - style_styleConstant(name, i, value), - priority, - ).on('end.style.' + name, null); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/styleTween.js - - function styleInterpolate(name, i, priority) { - return function (t) { - this.style.setProperty(name, i.call(this, t), priority); - }; - } - - function styleTween(name, value, priority) { - var t, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority); - return t; - } - tween._value = value; - return tween; - } - - /* harmony default export */ function transition_styleTween( - name, - value, - priority, - ) { - var key = 'style.' + (name += ''); - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== 'function') throw new Error(); - return this.tween( - key, - styleTween(name, value, priority == null ? '' : priority), - ); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/text.js - - function text_textConstant(value) { - return function () { - this.textContent = value; - }; - } - - function text_textFunction(value) { - return function () { - var value1 = value(this); - this.textContent = value1 == null ? '' : value1; - }; - } - - /* harmony default export */ function transition_text(value) { - return this.tween( - 'text', - typeof value === 'function' - ? text_textFunction(tweenValue(this, 'text', value)) - : text_textConstant(value == null ? '' : value + ''), - ); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/textTween.js - - function textInterpolate(i) { - return function (t) { - this.textContent = i.call(this, t); - }; - } - - function textTween(value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && textInterpolate(i); - return t0; - } - tween._value = value; - return tween; - } - - /* harmony default export */ function transition_textTween(value) { - var key = 'text'; - if (arguments.length < 1) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== 'function') throw new Error(); - return this.tween(key, textTween(value)); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/transition.js - - /* harmony default export */ function transition() { - var name = this._name, - id0 = this._id, - id1 = newId(); - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if ((node = group[i])) { - var inherit = schedule_get(node, id0); - schedule(node, name, id1, i, group, { - time: inherit.time + inherit.delay + inherit.duration, - delay: 0, - duration: inherit.duration, - ease: inherit.ease, - }); - } - } - } - - return new Transition(groups, this._parents, name, id1); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/end.js - - /* harmony default export */ function end() { - var on0, - on1, - that = this, - id = that._id, - size = that.size(); - return new Promise(function (resolve, reject) { - var cancel = { value: reject }, - end = { - value: function () { - if (--size === 0) resolve(); - }, - }; - - that.each(function () { - var schedule = schedule_set(this, id), - on = schedule.on; - - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) { - on1 = (on0 = on).copy(); - on1._.cancel.push(cancel); - on1._.interrupt.push(cancel); - on1._.end.push(end); - } - - schedule.on = on1; - }); - - // The selection was empty, resolve end immediately - if (size === 0) resolve(); - }); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/transition/index.js - - var id = 0; - - function Transition(groups, parents, name, id) { - this._groups = groups; - this._parents = parents; - this._name = name; - this._id = id; - } - - function transition_transition(name) { - return src_selection().transition(name); - } - - function newId() { - return ++id; - } - - var selection_prototype = src_selection.prototype; - - Transition.prototype = transition_transition.prototype = { - constructor: Transition, - select: transition_select, - selectAll: transition_selectAll, - selectChild: selection_prototype.selectChild, - selectChildren: selection_prototype.selectChildren, - filter: transition_filter, - merge: transition_merge, - selection: transition_selection, - transition: transition, - call: selection_prototype.call, - nodes: selection_prototype.nodes, - node: selection_prototype.node, - size: selection_prototype.size, - empty: selection_prototype.empty, - each: selection_prototype.each, - on: transition_on, - attr: transition_attr, - attrTween: transition_attrTween, - style: transition_style, - styleTween: transition_styleTween, - text: transition_text, - textTween: transition_textTween, - remove: transition_remove, - tween: tween, - delay: delay, - duration: duration, - ease: ease, - easeVarying: transition_easeVarying, - end: end, - [Symbol.iterator]: selection_prototype[Symbol.iterator], - }; // CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/transition.js - - var defaultTiming = { - time: null, // Set on use. - delay: 0, - duration: 250, - ease: cubicInOut, - }; - - function inherit(node, id) { - var timing; - while (!(timing = node.__transition) || !(timing = timing[id])) { - if (!(node = node.parentNode)) { - throw new Error(`transition ${id} not found`); - } - } - return timing; - } - - /* harmony default export */ function selection_transition(name) { - var id, timing; - - if (name instanceof Transition) { - (id = name._id), (name = name._name); - } else { - (id = newId()), - ((timing = defaultTiming).time = now()), - (name = name == null ? null : name + ''); - } - - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if ((node = group[i])) { - schedule(node, name, id, i, group, timing || inherit(node, id)); - } - } - } - - return new Transition(groups, this._parents, name, id); - } // CONCATENATED MODULE: ../node_modules/d3-transition/src/selection/index.js - - src_selection.prototype.interrupt = selection_interrupt; - src_selection.prototype.transition = selection_transition; // CONCATENATED MODULE: ../node_modules/d3-transition/src/index.js // CONCATENATED MODULE: ./colorUtils.js - - function generateHash(name) { - // Return a vector (0.0->1.0) that is a hash of the input string. - // The hash is computed to favor early characters over later ones, so - // that strings with similar starts have similar vectors. Only the first - // 6 characters are considered. - const MAX_CHAR = 6; - - let hash = 0; - let maxHash = 0; - let weight = 1; - const mod = 10; - - if (name) { - for (let i = 0; i < name.length; i++) { - if (i > MAX_CHAR) { - break; - } - hash += weight * (name.charCodeAt(i) % mod); - maxHash += weight * (mod - 1); - weight *= 0.7; - } - if (maxHash > 0) { - hash = hash / maxHash; - } - } - return hash; - } - - function generateColorVector(name) { - let vector = 0; - if (name) { - const nameArr = name.split('`'); - if (nameArr.length > 1) { - name = nameArr[nameArr.length - 1]; // drop module name if present - } - name = name.split('(')[0]; // drop extra info - vector = generateHash(name); - } - return vector; - } // CONCATENATED MODULE: ./colorScheme.js - - function calculateColor(hue, vector) { - let r; - let g; - let b; - - if (hue === 'red') { - r = 200 + Math.round(55 * vector); - g = 50 + Math.round(80 * vector); - b = g; - } else if (hue === 'orange') { - r = 190 + Math.round(65 * vector); - g = 90 + Math.round(65 * vector); - b = 0; - } else if (hue === 'yellow') { - r = 175 + Math.round(55 * vector); - g = r; - b = 50 + Math.round(20 * vector); - } else if (hue === 'green') { - r = 50 + Math.round(60 * vector); - g = 200 + Math.round(55 * vector); - b = r; - } else if (hue === 'pastelgreen') { - // rgb(163,195,72) - rgb(238,244,221) - r = 163 + Math.round(75 * vector); - g = 195 + Math.round(49 * vector); - b = 72 + Math.round(149 * vector); - } else if (hue === 'blue') { - // rgb(91,156,221) - rgb(217,232,247) - r = 91 + Math.round(126 * vector); - g = 156 + Math.round(76 * vector); - b = 221 + Math.round(26 * vector); - } else if (hue === 'aqua') { - r = 50 + Math.round(60 * vector); - g = 165 + Math.round(55 * vector); - b = g; - } else if (hue === 'cold') { - r = 0 + Math.round(55 * (1 - vector)); - g = 0 + Math.round(230 * (1 - vector)); - b = 200 + Math.round(55 * vector); - } else { - // original warm palette - r = 200 + Math.round(55 * vector); - g = 0 + Math.round(230 * (1 - vector)); - b = 0 + Math.round(55 * (1 - vector)); - } - - return 'rgb(' + r + ',' + g + ',' + b + ')'; - } // CONCATENATED MODULE: ./flamegraph.js - - /* harmony default export */ function flamegraph() { - let w = 960; // graph width - let h = null; // graph height - let c = 18; // cell height - let selection = null; // selection - let tooltip = null; // tooltip - let title = ''; // graph title - let transitionDuration = 750; - let transitionEase = cubicInOut; // tooltip offset - let sort = false; - let inverted = false; // invert the graph direction - let clickHandler = null; - let hoverHandler = null; - let minFrameSize = 0; - let detailsElement = null; - let searchDetails = null; - let selfValue = false; - let resetHeightOnZoom = false; - let scrollOnZoom = false; - let minHeight = null; - let computeDelta = false; - let colorHue = null; - - let getName = function (d) { - return d.data.n || d.data.name; - }; - - let getValue = function (d) { - if ('v' in d) { - return d.v; - } else { - return d.value; - } - }; - - let getChildren = function (d) { - return d.c || d.children; - }; - - let getLibtype = function (d) { - return d.data.l || d.data.libtype; - }; - - let getDelta = function (d) { - if ('d' in d.data) { - return d.data.d; - } else { - return d.data.delta; - } - }; - - let searchHandler = function (searchResults, searchSum, totalValue) { - searchDetails = () => { - if (detailsElement) { - detailsElement.textContent = - 'search: ' + - searchSum + - ' of ' + - totalValue + - ' total time ( ' + - format('.3f')(100 * (searchSum / totalValue), 3) + - '%)'; - } - }; - searchDetails(); - }; - const originalSearchHandler = searchHandler; - - let searchMatch = (d, term, ignoreCase = false) => { - if (!term) { - return false; - } - let label = getName(d); - if (ignoreCase) { - term = term.toLowerCase(); - label = label.toLowerCase(); - } - const re = new RegExp(term); - return typeof label !== 'undefined' && label && label.match(re); - }; - const originalSearchMatch = searchMatch; - - let detailsHandler = function (d) { - if (detailsElement) { - if (d) { - detailsElement.textContent = d; - } else { - if (typeof searchDetails === 'function') { - searchDetails(); - } else { - detailsElement.textContent = ''; - } - } - } - }; - const originalDetailsHandler = detailsHandler; - - let labelHandler = function (d) { - return ( - getName(d) + - ' (' + - format('.3f')(100 * (d.x1 - d.x0), 3) + - '%, ' + - getValue(d) + - ' ms)' - ); - }; - - let colorMapper = function (d) { - return d.highlight ? '#E600E6' : colorHash(getName(d), getLibtype(d)); - }; - const originalColorMapper = colorMapper; - - function colorHash(name, libtype) { - // Return a color for the given name and library type. The library type - // selects the hue, and the name is hashed to a color in that hue. - - // default when libtype is not in use - let hue = colorHue || 'warm'; - - if (!colorHue && !(typeof libtype === 'undefined' || libtype === '')) { - // Select hue. Order is important. - hue = 'red'; - if (typeof name !== 'undefined' && name && name.match(/::/)) { - hue = 'yellow'; - } - if (libtype === 'kernel') { - hue = 'orange'; - } else if (libtype === 'jit') { - hue = 'green'; - } else if (libtype === 'inlined') { - hue = 'aqua'; - } - } - - const vector = generateColorVector(name); - return calculateColor(hue, vector); - } - - function show(d) { - d.data.fade = false; - d.data.hide = false; - if (d.children) { - d.children.forEach(show); - } - } - - function hideSiblings(node) { - let child = node; - let parent = child.parent; - let children, i, sibling; - while (parent) { - children = parent.children; - i = children.length; - while (i--) { - sibling = children[i]; - if (sibling !== child) { - sibling.data.hide = true; - } - } - child = parent; - parent = child.parent; - } - } - - function fadeAncestors(d) { - if (d.parent) { - d.parent.data.fade = true; - fadeAncestors(d.parent); - } - } - - function zoom(d) { - if (tooltip) tooltip.hide(); - hideSiblings(d); - show(d); - fadeAncestors(d); - update(); - if (scrollOnZoom) { - const chartOffset = src_select(this).select('svg')._groups[0][0] - .parentNode.offsetTop; - const maxFrames = (window.innerHeight - chartOffset) / c; - const frameOffset = (d.height - maxFrames + 10) * c; - window.scrollTo({ - top: chartOffset + frameOffset, - left: 0, - behavior: 'smooth', - }); - } - if (typeof clickHandler === 'function') { - clickHandler(d); - } - } - - function searchTree(d, term) { - const results = []; - let sum = 0; - - function searchInner(d, foundParent) { - let found = false; - - if (searchMatch(d, term)) { - d.highlight = true; - found = true; - if (!foundParent) { - sum += getValue(d); - } - results.push(d); - } else { - d.highlight = false; - } - - if (getChildren(d)) { - getChildren(d).forEach(function (child) { - searchInner(child, foundParent || found); - }); - } - } - searchInner(d, false); - - return [results, sum]; - } - - function findTree(d, id) { - if (d.id === id) { - return d; - } else { - const children = getChildren(d); - if (children) { - for (let i = 0; i < children.length; i++) { - const found = findTree(children[i], id); - if (found) { - return found; - } - } - } - } - } - - function clear(d) { - d.highlight = false; - if (getChildren(d)) { - getChildren(d).forEach(function (child) { - clear(child); - }); - } - } - - function doSort(a, b) { - if (typeof sort === 'function') { - return sort(a, b); - } else if (sort) { - return ascending_ascending(getName(a), getName(b)); - } - } - - const p = partition(); - - function filterNodes(root) { - let nodeList = root.descendants(); - if (minFrameSize > 0) { - const kx = w / (root.x1 - root.x0); - nodeList = nodeList.filter(function (el) { - return (el.x1 - el.x0) * kx > minFrameSize; - }); - } - return nodeList; - } - - function update() { - selection.each(function (root) { - const x = linear_linear().range([0, w]); - const y = linear_linear().range([0, c]); - - reappraiseNode(root); - - if (sort) root.sort(doSort); - - p(root); - - const kx = w / (root.x1 - root.x0); - function width(d) { - return (d.x1 - d.x0) * kx; - } - - const descendants = filterNodes(root); - const svg = src_select(this).select('svg'); - svg.attr('width', w); - - let g = svg.selectAll('g').data(descendants, function (d) { - return d.id; - }); - - // if height is not set: set height on first update, after nodes were filtered by minFrameSize - if (!h || resetHeightOnZoom) { - const maxDepth = Math.max.apply( - null, - descendants.map(function (n) { - return n.depth; - }), - ); - - h = (maxDepth + 3) * c; - if (h < minHeight) h = minHeight; - - svg.attr('height', h); - } - - g.transition() - .duration(transitionDuration) - .ease(transitionEase) - .attr('transform', function (d) { - return ( - 'translate(' + - x(d.x0) + - ',' + - (inverted ? y(d.depth) : h - y(d.depth) - c) + - ')' - ); - }); - - g.select('rect') - .transition() - .duration(transitionDuration) - .ease(transitionEase) - .attr('width', width); - - const node = g - .enter() - .append('svg:g') - .attr('transform', function (d) { - return ( - 'translate(' + - x(d.x0) + - ',' + - (inverted ? y(d.depth) : h - y(d.depth) - c) + - ')' - ); - }); - - node - .append('svg:rect') - .transition() - .delay(transitionDuration / 2) - .attr('width', width); - - if (!tooltip) { - node.append('svg:title'); - } - - node.append('foreignObject').append('xhtml:div'); - - // Now we have to re-select to see the new elements (why?). - g = svg.selectAll('g').data(descendants, function (d) { - return d.id; - }); - - g.attr('width', width) - .attr('height', function (d) { - return c; - }) - .attr('name', function (d) { - return getName(d); - }) - .attr('class', function (d) { - return d.data.fade ? 'frame fade' : 'frame'; - }); - - g.select('rect') - .attr('height', function (d) { - return c; - }) - .attr('fill', function (d) { - return colorMapper(d); - }); - - if (!tooltip) { - g.select('title').text(labelHandler); - } - - g.select('foreignObject') - .attr('width', width) - .attr('height', function (d) { - return c; - }) - .select('div') - .attr('class', 'd3-flame-graph-label') - .style('display', function (d) { - return width(d) < 35 ? 'none' : 'block'; - }) - .transition() - .delay(transitionDuration) - .text(getName); - - g.on('click', (_, d) => { - zoom(d); - }); - - g.exit().remove(); - - g.on('mouseover', function (_, d) { - if (tooltip) tooltip.show(d, this); - detailsHandler(labelHandler(d)); - if (typeof hoverHandler === 'function') { - hoverHandler(d); - } - }).on('mouseout', function () { - if (tooltip) tooltip.hide(); - detailsHandler(null); - }); - }); - } - - function merge(data, samples) { - samples.forEach(function (sample) { - const node = data.find(function (element) { - return element.name === sample.name; - }); - - if (node) { - node.value += sample.value; - if (sample.children) { - if (!node.children) { - node.children = []; - } - merge(node.children, sample.children); - } - } else { - data.push(sample); - } - }); - } - - function forEachNode(node, f) { - f(node); - let children = node.children; - if (children) { - const stack = [children]; - let count, child, grandChildren; - while (stack.length) { - children = stack.pop(); - count = children.length; - while (count--) { - child = children[count]; - f(child); - grandChildren = child.children; - if (grandChildren) { - stack.push(grandChildren); - } - } - } - } - } - - function adoptNode(node) { - let id = 0; - forEachNode(node, function (n) { - n.id = id++; - }); - } - - function reappraiseNode(root) { - let node, - children, - grandChildren, - childrenValue, - i, - j, - child, - childValue; - const stack = []; - const included = []; - const excluded = []; - const compoundValue = !selfValue; - let item = root.data; - if (item.hide) { - root.value = 0; - children = root.children; - if (children) { - excluded.push(children); - } - } else { - root.value = item.fade ? 0 : getValue(item); - stack.push(root); - } - // First DFS pass: - // 1. Update node.value with node's self value - // 2. Populate excluded list with children under hidden nodes - // 3. Populate included list with children under visible nodes - while ((node = stack.pop())) { - children = node.children; - if (children && (i = children.length)) { - childrenValue = 0; - while (i--) { - child = children[i]; - item = child.data; - if (item.hide) { - child.value = 0; - grandChildren = child.children; - if (grandChildren) { - excluded.push(grandChildren); - } - continue; - } - if (item.fade) { - child.value = 0; - } else { - childValue = getValue(item); - child.value = childValue; - childrenValue += childValue; - } - stack.push(child); - } - // Here second part of `&&` is actually checking for `node.data.fade`. However, - // checking for node.value is faster and presents more oportunities for JS optimizer. - if (compoundValue && node.value) { - node.value -= childrenValue; - } - included.push(children); - } - } - // Postorder traversal to compute compound value of each visible node. - i = included.length; - while (i--) { - children = included[i]; - childrenValue = 0; - j = children.length; - while (j--) { - childrenValue += children[j].value; - } - children[0].parent.value += childrenValue; - } - // Continue DFS to set value of all hidden nodes to 0. - while (excluded.length) { - children = excluded.pop(); - j = children.length; - while (j--) { - child = children[j]; - child.value = 0; - grandChildren = child.children; - if (grandChildren) { - excluded.push(grandChildren); - } - } - } - } - - function processData() { - selection.datum((data) => { - if (data.constructor.name !== 'Node') { - // creating a root hierarchical structure - const root = hierarchy(data, getChildren); - - // augumenting nodes with ids - adoptNode(root); - - // calculate actual value - reappraiseNode(root); - - // store value for later use - root.originalValue = root.value; - - // computing deltas for differentials - if (computeDelta) { - root.eachAfter((node) => { - let sum = getDelta(node); - const children = node.children; - let i = children && children.length; - while (--i >= 0) sum += children[i].delta; - node.delta = sum; - }); - } - - // setting the bound data for the selection - return root; - } - }); - } - - function chart(s) { - if (!arguments.length) { - return chart; - } - - // saving the selection on `.call` - selection = s; - - // processing raw data to be used in the chart - processData(); - - // create chart svg - selection.each(function (data) { - if (src_select(this).select('svg').size() === 0) { - const svg = src_select(this) - .append('svg:svg') - .attr('width', w) - .attr('class', 'partition d3-flame-graph'); - - if (h) { - if (h < minHeight) h = minHeight; - svg.attr('height', h); - } - - svg - .append('svg:text') - .attr('class', 'title') - .attr('text-anchor', 'middle') - .attr('y', '25') - .attr('x', w / 2) - .attr('fill', '#808080') - .text(title); - - if (tooltip) svg.call(tooltip); - } - }); - - // first draw - update(); - } - - chart.height = function (_) { - if (!arguments.length) { - return h; - } - h = _; - return chart; - }; - - chart.minHeight = function (_) { - if (!arguments.length) { - return minHeight; - } - minHeight = _; - return chart; - }; - - chart.width = function (_) { - if (!arguments.length) { - return w; - } - w = _; - return chart; - }; - - chart.cellHeight = function (_) { - if (!arguments.length) { - return c; - } - c = _; - return chart; - }; - - chart.tooltip = function (_) { - if (!arguments.length) { - return tooltip; - } - if (typeof _ === 'function') { - tooltip = _; - } - return chart; - }; - - chart.title = function (_) { - if (!arguments.length) { - return title; - } - title = _; - return chart; - }; - - chart.transitionDuration = function (_) { - if (!arguments.length) { - return transitionDuration; - } - transitionDuration = _; - return chart; - }; - - chart.transitionEase = function (_) { - if (!arguments.length) { - return transitionEase; - } - transitionEase = _; - return chart; - }; - - chart.sort = function (_) { - if (!arguments.length) { - return sort; - } - sort = _; - return chart; - }; - - chart.inverted = function (_) { - if (!arguments.length) { - return inverted; - } - inverted = _; - return chart; - }; - - chart.computeDelta = function (_) { - if (!arguments.length) { - return computeDelta; - } - computeDelta = _; - return chart; - }; - - chart.setLabelHandler = function (_) { - if (!arguments.length) { - return labelHandler; - } - labelHandler = _; - return chart; - }; - // Kept for backwards compatibility. - chart.label = chart.setLabelHandler; - - chart.search = function (term) { - const searchResults = []; - let searchSum = 0; - let totalValue = 0; - selection.each(function (data) { - const res = searchTree(data, term); - searchResults.push(...res[0]); - searchSum += res[1]; - totalValue += data.originalValue; - }); - searchHandler(searchResults, searchSum, totalValue); - update(); - }; - - chart.findById = function (id) { - if (typeof id === 'undefined' || id === null) { - return null; - } - let found = null; - selection.each(function (data) { - if (found === null) { - found = findTree(data, id); - } - }); - return found; - }; - - chart.clear = function () { - detailsHandler(null); - selection.each(function (root) { - clear(root); - update(); - }); - }; - - chart.zoomTo = function (d) { - zoom(d); - }; - - chart.resetZoom = function () { - selection.each(function (root) { - zoom(root); // zoom to root - }); - }; - - chart.onClick = function (_) { - if (!arguments.length) { - return clickHandler; - } - clickHandler = _; - return chart; - }; - - chart.onHover = function (_) { - if (!arguments.length) { - return hoverHandler; - } - hoverHandler = _; - return chart; - }; - - chart.merge = function (data) { - if (!selection) { - return chart; - } - - // TODO: Fix merge with zoom - // Merging a zoomed chart doesn't work properly, so - // clearing zoom before merge. - // To apply zoom on merge, we would need to set hide - // and fade on new data according to current data. - // New ids are generated for the whole data structure, - // so previous ids might not be the same. For merge to - // work with zoom, previous ids should be maintained. - this.resetZoom(); - - // Clear search details - // Merge requires a new search, updating data and - // the details handler with search results. - // Since we don't store the search term, can't - // perform search again. - searchDetails = null; - detailsHandler(null); - - selection.datum((root) => { - merge([root.data], [data]); - return root.data; - }); - processData(); - update(); - return chart; - }; - - chart.update = function (data) { - if (!selection) { - return chart; - } - if (data) { - selection.datum(data); - processData(); - } - update(); - return chart; - }; - - chart.destroy = function () { - if (!selection) { - return chart; - } - if (tooltip) { - tooltip.hide(); - if (typeof tooltip.destroy === 'function') { - tooltip.destroy(); - } - } - selection.selectAll('svg').remove(); - return chart; - }; - - chart.setColorMapper = function (_) { - if (!arguments.length) { - colorMapper = originalColorMapper; - return chart; - } - colorMapper = (d) => { - const originalColor = originalColorMapper(d); - return _(d, originalColor); - }; - return chart; - }; - // Kept for backwards compatibility. - chart.color = chart.setColorMapper; - - chart.setColorHue = function (_) { - if (!arguments.length) { - colorHue = null; - return chart; - } - colorHue = _; - return chart; - }; - - chart.minFrameSize = function (_) { - if (!arguments.length) { - return minFrameSize; - } - minFrameSize = _; - return chart; - }; - - chart.setDetailsElement = function (_) { - if (!arguments.length) { - return detailsElement; - } - detailsElement = _; - return chart; - }; - // Kept for backwards compatibility. - chart.details = chart.setDetailsElement; - - chart.selfValue = function (_) { - if (!arguments.length) { - return selfValue; - } - selfValue = _; - return chart; - }; - - chart.resetHeightOnZoom = function (_) { - if (!arguments.length) { - return resetHeightOnZoom; - } - resetHeightOnZoom = _; - return chart; - }; - - chart.scrollOnZoom = function (_) { - if (!arguments.length) { - return scrollOnZoom; - } - scrollOnZoom = _; - return chart; - }; - - chart.getName = function (_) { - if (!arguments.length) { - return getName; - } - getName = _; - return chart; - }; - - chart.getValue = function (_) { - if (!arguments.length) { - return getValue; - } - getValue = _; - return chart; - }; - - chart.getChildren = function (_) { - if (!arguments.length) { - return getChildren; - } - getChildren = _; - return chart; - }; - - chart.getLibtype = function (_) { - if (!arguments.length) { - return getLibtype; - } - getLibtype = _; - return chart; - }; - - chart.getDelta = function (_) { - if (!arguments.length) { - return getDelta; - } - getDelta = _; - return chart; - }; - - chart.setSearchHandler = function (_) { - if (!arguments.length) { - searchHandler = originalSearchHandler; - return chart; - } - searchHandler = _; - return chart; - }; - - chart.setDetailsHandler = function (_) { - if (!arguments.length) { - detailsHandler = originalDetailsHandler; - return chart; - } - detailsHandler = _; - return chart; - }; - - chart.setSearchMatch = function (_) { - if (!arguments.length) { - searchMatch = originalSearchMatch; - return chart; - } - searchMatch = _; - return chart; - }; - - return chart; - } - - __webpack_exports__ = __webpack_exports__['default']; - /******/ return __webpack_exports__; - /******/ - })(); -}); diff --git a/development/charts/table/index.html b/development/charts/table/index.html deleted file mode 100644 index 8fa7c604f91b..000000000000 --- a/development/charts/table/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - -
-
- - - - - - - -
S.NoNameTotalTime
-
-
- - diff --git a/development/charts/table/jquery.min.js b/development/charts/table/jquery.min.js deleted file mode 100644 index 8cdc80eb85d8..000000000000 --- a/development/charts/table/jquery.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * jQuery JavaScript Library v1.6.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Jun 30 14:16:56 2011 -0400 - */ -(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. -shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j -)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/development/highlights/index.js b/development/highlights/index.js index 2616d602633e..9efd3073d031 100644 --- a/development/highlights/index.js +++ b/development/highlights/index.js @@ -9,7 +9,7 @@ async function getHighlights({ artifactBase }) { // here we assume the PR base branch ("target") is `main` in lieu of doing // a query against the github api which requires an access token // see https://discuss.circleci.com/t/how-to-retrieve-a-pull-requests-base-branch-name-github/36911 - const changedFiles = await getChangedFiles({ target: 'main' }); + const changedFiles = await getChangedFiles({ target: 'origin/main' }); console.log(`detected changed files vs main:`); for (const filename of changedFiles) { console.log(` ${filename}`); diff --git a/development/metamaskbot-build-announce.js b/development/metamaskbot-build-announce.js index f85d64faa887..e463da31aaec 100755 --- a/development/metamaskbot-build-announce.js +++ b/development/metamaskbot-build-announce.js @@ -5,7 +5,6 @@ const path = require('path'); // Fetch is part of node js in future versions, thus triggering no-shadow // eslint-disable-next-line no-shadow const fetch = require('node-fetch'); -const glob = require('fast-glob'); const VERSION = require('../package.json').version; const { getHighlights } = require('./highlights'); @@ -38,104 +37,100 @@ function getPercentageChange(from, to) { return parseFloat(((to - from) / Math.abs(from)) * 100).toFixed(2); } +/** + * Check whether an artifact exists, + * + * @param {string} url - The URL of the artifact to check. + * @returns True if the artifact exists, false if it doesn't + */ +async function artifactExists(url) { + // Using a regular GET request here rather than HEAD because for some reason CircleCI always + // returns 404 for HEAD requests. + const response = await fetch(url); + return response.ok; +} + async function start() { const { - GITHUB_COMMENT_TOKEN, - CIRCLE_PULL_REQUEST, - CIRCLE_SHA1, + PR_COMMENT_TOKEN, + PR_NUMBER, + HEAD_COMMIT_HASH, + MERGE_BASE_COMMIT_HASH, CIRCLE_BUILD_NUM, CIRCLE_WORKFLOW_JOB_ID, - PARENT_COMMIT, } = process.env; - console.log('CIRCLE_PULL_REQUEST', CIRCLE_PULL_REQUEST); - console.log('CIRCLE_SHA1', CIRCLE_SHA1); + console.log('PR_NUMBER', PR_NUMBER); + console.log('HEAD_COMMIT_HASH', HEAD_COMMIT_HASH); + console.log('MERGE_BASE_COMMIT_HASH', MERGE_BASE_COMMIT_HASH); console.log('CIRCLE_BUILD_NUM', CIRCLE_BUILD_NUM); console.log('CIRCLE_WORKFLOW_JOB_ID', CIRCLE_WORKFLOW_JOB_ID); - console.log('PARENT_COMMIT', PARENT_COMMIT); - if (!CIRCLE_PULL_REQUEST) { - console.warn(`No pull request detected for commit "${CIRCLE_SHA1}"`); + if (!PR_NUMBER) { + console.warn(`No pull request detected for commit "${HEAD_COMMIT_HASH}"`); return; } - const CIRCLE_PR_NUMBER = CIRCLE_PULL_REQUEST.split('/').pop(); - const SHORT_SHA1 = CIRCLE_SHA1.slice(0, 7); + const SHORT_SHA1 = HEAD_COMMIT_HASH.slice(0, 7); const BUILD_LINK_BASE = `https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0`; // build the github comment content // links to extension builds - const platforms = ['chrome', 'firefox']; - const buildLinks = platforms - .map((platform) => { - const url = - platform === 'firefox' - ? `${BUILD_LINK_BASE}/builds-mv2/metamask-${platform}-${VERSION}.zip` - : `${BUILD_LINK_BASE}/builds/metamask-${platform}-${VERSION}.zip`; - return `${platform}`; - }) - .join(', '); - const betaBuildLinks = `chrome`; - const flaskBuildLinks = platforms - .map((platform) => { - const url = - platform === 'firefox' - ? `${BUILD_LINK_BASE}/builds-flask-mv2/metamask-flask-${platform}-${VERSION}-flask.0.zip` - : `${BUILD_LINK_BASE}/builds-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`; - return `${platform}`; - }) - .join(', '); - const mmiBuildLinks = platforms - .map((platform) => { - const url = `${BUILD_LINK_BASE}/builds-mmi/metamask-mmi-${platform}-${VERSION}-mmi.0.zip`; - return `${platform}`; - }) - .join(', '); - const testBuildLinks = platforms - .map((platform) => { - const url = - platform === 'firefox' - ? `${BUILD_LINK_BASE}/builds-test-mv2/metamask-${platform}-${VERSION}.zip` - : `${BUILD_LINK_BASE}/builds-test/metamask-${platform}-${VERSION}.zip`; - return `${platform}`; - }) - .join(', '); - const testFlaskBuildLinks = platforms - .map((platform) => { - const url = - platform === 'firefox' - ? `${BUILD_LINK_BASE}/builds-test-flask-mv2/metamask-flask-${platform}-${VERSION}-flask.0.zip` - : `${BUILD_LINK_BASE}/builds-test-flask/metamask-flask-${platform}-${VERSION}-flask.0.zip`; + const buildMap = { + builds: { + chrome: `${BUILD_LINK_BASE}/builds/metamask-chrome-${VERSION}.zip`, + firefox: `${BUILD_LINK_BASE}/builds-mv2/metamask-firefox-${VERSION}.zip`, + }, + 'builds (flask)': { + chrome: `${BUILD_LINK_BASE}/builds-flask/metamask-flask-chrome-${VERSION}-flask.0.zip`, + firefox: `${BUILD_LINK_BASE}/builds-flask-mv2/metamask-flask-firefox-${VERSION}-flask.0.zip`, + }, + 'builds (MMI)': { + chrome: `${BUILD_LINK_BASE}/builds-mmi/metamask-mmi-chrome-${VERSION}-mmi.0.zip`, + }, + 'builds (test)': { + chrome: `${BUILD_LINK_BASE}/builds-test/metamask-chrome-${VERSION}.zip`, + firefox: `${BUILD_LINK_BASE}/builds-test-mv2/metamask-firefox-${VERSION}.zip`, + }, + 'builds (test-flask)': { + chrome: `${BUILD_LINK_BASE}/builds-test-flask/metamask-flask-chrome-${VERSION}-flask.0.zip`, + firefox: `${BUILD_LINK_BASE}/builds-test-flask-mv2/metamask-flask-firefox-${VERSION}-flask.0.zip`, + }, + }; + + const buildContentRows = Object.entries(buildMap).map(([label, builds]) => { + const buildLinks = Object.entries(builds).map(([platform, url]) => { return `${platform}`; - }) - .join(', '); + }); + return `${label}: ${buildLinks.join(', ')}`; + }); // links to bundle browser builds const bundles = {}; - const fileType = '.html'; const sourceMapRoot = '/build-artifacts/source-map-explorer/'; - const bundleFiles = await glob(`.${sourceMapRoot}*${fileType}`); - - bundleFiles.forEach((bundleFile) => { - const fileName = bundleFile.split(sourceMapRoot)[1]; - const bundleName = fileName.split(fileType)[0]; - const url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileName}`; - let fileRoot = bundleName; - let fileIndex = bundleName.match(/-[0-9]{1,}$/u)?.index; - - if (fileIndex) { - fileRoot = bundleName.slice(0, fileIndex); - fileIndex = bundleName.slice(fileIndex + 1, bundleName.length); - } - - const link = `${fileIndex || fileRoot}`; + const fileRoots = [ + 'background', + 'common', + 'ui', + 'content-script', + 'offscreen', + ]; - if (fileRoot in bundles) { + for (const fileRoot of fileRoots) { + bundles[fileRoot] = []; + let fileIndex = 0; + let url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileRoot}-${fileIndex}.html`; + console.log(`Verifying ${url}`); + while (await artifactExists(url)) { + const link = `${fileIndex}`; bundles[fileRoot].push(link); - } else { - bundles[fileRoot] = [link]; + + fileIndex += 1; + url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileRoot}-${fileIndex}.html`; + console.log(`Verifying ${url}`); } - }); + console.log(`Not found: ${url}`); + } const bundleMarkup = `
    ${Object.keys(bundles) .map((key) => `
  • ${key}: ${bundles[key].join(', ')}
  • `) @@ -144,9 +139,6 @@ async function start() { const bundleSizeDataUrl = 'https://raw.githubusercontent.com/MetaMask/extension_bundlesize_stats/main/stats/bundle_size_data.json'; - const coverageUrl = `${BUILD_LINK_BASE}/coverage/index.html`; - const coverageLink = `Report`; - const storybookUrl = `${BUILD_LINK_BASE}/storybook/index.html`; const storybookLink = `Storybook`; @@ -156,12 +148,6 @@ async function start() { // links to bundle browser builds const depVizUrl = `${BUILD_LINK_BASE}/build-artifacts/build-viz/index.html`; const depVizLink = `Build System`; - const moduleInitStatsBackgroundUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/initialisation/background/index.html`; - const moduleInitStatsBackgroundLink = `Background Module Init Stats`; - const moduleInitStatsUIUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/initialisation/ui/index.html`; - const moduleInitStatsUILink = `UI Init Stats`; - const moduleLoadStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/load_time/index.html`; - const moduleLoadStatsLink = `Module Load Stats`; const bundleSizeStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/bundle_size.json`; const bundleSizeStatsLink = `Bundle Size Stats`; const userActionsStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/benchmark/user_actions.json`; @@ -171,19 +157,10 @@ async function start() { const allArtifactsUrl = `https://circleci.com/gh/MetaMask/metamask-extension/${CIRCLE_BUILD_NUM}#artifacts/containers/0`; const contentRows = [ - `builds: ${buildLinks}`, - `builds (beta): ${betaBuildLinks}`, - `builds (flask): ${flaskBuildLinks}`, - `builds (MMI): ${mmiBuildLinks}`, - `builds (test): ${testBuildLinks}`, - `builds (test-flask): ${testFlaskBuildLinks}`, + ...buildContentRows, `build viz: ${depVizLink}`, - `mv3: ${moduleInitStatsBackgroundLink}`, - `mv3: ${moduleInitStatsUILink}`, - `mv3: ${moduleLoadStatsLink}`, `mv3: ${bundleSizeStatsLink}`, `mv2: ${userActionsStatsLink}`, - `code coverage: ${coverageLink}`, `storybook: ${storybookLink}`, `typescript migration: ${tsMigrationDashboardLink}`, `all artifacts`, @@ -198,8 +175,9 @@ async function start() { const exposedContent = `Builds ready [${SHORT_SHA1}]`; const artifactsBody = `
    ${exposedContent}${hiddenContent}
    \n\n`; + const benchmarkPlatforms = ['chrome']; const benchmarkResults = {}; - for (const platform of platforms) { + for (const platform of benchmarkPlatforms) { const benchmarkPath = path.resolve( __dirname, '..', @@ -328,7 +306,7 @@ async function start() { }; const devSizes = Object.keys(prSizes).reduce((sizes, part) => { - sizes[part] = devBundleSizeStats[PARENT_COMMIT][part] || 0; + sizes[part] = devBundleSizeStats[MERGE_BASE_COMMIT_HASH][part] || 0; return sizes; }, {}); @@ -379,7 +357,7 @@ async function start() { } const JSON_PAYLOAD = JSON.stringify({ body: commentBody }); - const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${CIRCLE_PR_NUMBER}/comments`; + const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${PR_NUMBER}/comments`; console.log(`Announcement:\n${commentBody}`); console.log(`Posting to: ${POST_COMMENT_URI}`); @@ -388,7 +366,7 @@ async function start() { body: JSON_PAYLOAD, headers: { 'User-Agent': 'metamaskbot', - Authorization: `token ${GITHUB_COMMENT_TOKEN}`, + Authorization: `token ${PR_COMMENT_TOKEN}`, }, }); if (!response.ok) { diff --git a/docs/lavamoat-policy-review-process.md b/docs/lavamoat-policy-review-process.md new file mode 100644 index 000000000000..097154e6c268 --- /dev/null +++ b/docs/lavamoat-policy-review-process.md @@ -0,0 +1,29 @@ +# LavaMoat Policy Review process in metamask-extension + +When there's a need to change policy (because of new or updated packages that require a different set of capabilities), please follow these steps: + +> In the initial soft-launch of the process the approval from policy reviewers is not mandatory, but it will be in the near future. + +### Engineer on the dev team: + 1. Notice the `Validate lavamoat policy*` PR status check fail because dependency updates or changes need a policy update. + 2. (optional) Generate an updated policy and give it a cursory look in local development whenever you’re testing the change. + - If you're confident your update is complete, you can push it to the PR branch. + 3. To generate a complete set of new policies, call `metamaskbot` for help: + - put `@metamaskbot update-policies` in a comment on the PR. When it produces changes, they need to be reviewed. The following steps assume update-policies produced changes. + - *Note the response from the bot points to instructions on how to review the policy for your convenience. https://lavamoat.github.io/guides/policy-diff/* + 4. Analyze the diff of policy.json and use the understanding of the codebase and change being made to decide whether the capabilities added make sense in that context. Leave a comment listing any doubts you have with brief explanations or if everything is in order \- saying so and explaining why the most powerful capabilities are there (like access to child_process.exec in node or network access in the browser) + *Remember the Security Reviewer comes with more security expertise but less intimate knowledge of the codebase and the change you’ve built, so you are the most qualified to know whether the dependency needs the powers detected by LavaMoat or not.* + - You can use these questions to guide your analysis: + 1. What new powers (globals and builtins) do you see? Why should the package be allowed to use these new powers? Explain if possible + 2. What new packages do you see? Did you intend to introduce them? If you didn’t, which package did? (can you see them in `packages` field in policy of any other package that you updated or introduced?) + - The comment is mandatory even if you don’t understand the policy change, in which case you’re expected to state so (it’s ok to not understand) + - Note: this could be enforced by a job that is only passing if the comment was made + - Note: we’d introduce more tooling to summarize and analyze policy and post that as a comment on the PR + 5. Mention `policy-reviewers` group in your comment. + policy-reviewers group includes security liaisons and their involvement is not limited to (but likely focused more around) their respective teams’ PRs. + +### L1 Security Reviewer: + 1. Look at the policy and the comment from the Developer. Approve the PR if they match and the policy change seems safe. Address questions the Developer had and discuss if the policy change doesn’t seem right. + 2. If changes are hard to explain or seem dangerous, escalate to a review of the dependency and its powers by mentioning `supply-chain` +### (optional) L2 Security Reviewer: + 1. Review the dependency in question and inform the PR reviewers whether it’s deemed malicious or safe. diff --git a/docs/testing.md b/docs/testing.md index 76c91ecfb368..5cc23dfb7c42 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -74,7 +74,6 @@ const generateGasEstimatorProps = (overrides) => ({ const generateAppState = (overrides) => ({ networkDropdownOpen: false, - gasIsLoading: false, isLoading: false, modal: { open: false, diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index ddd92183c786..7a6974a03193 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -5,144 +5,124 @@ "regeneratorRuntime": "write" } }, - "@ensdomains/content-hash": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { "globals": { - "console.warn": true + "WeakRef": true }, "packages": { - "@ensdomains/content-hash>cids": true, - "@ensdomains/content-hash>js-base64": true, - "@ensdomains/content-hash>multicodec": true, - "@ensdomains/content-hash>multihashes": true, - "browserify>buffer": true + "browserify": true } }, - "@ensdomains/content-hash>cids": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes": true, - "@ensdomains/content-hash>cids>uint8arrays": true, - "@ensdomains/content-hash>multicodec": true + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, + "browserify": true, + "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true } }, - "@ensdomains/content-hash>cids>multibase": { + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "SuppressedError": true + } + }, + "@ensdomains/content-hash": { + "globals": { + "console.warn": true }, "packages": { - "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true + "browserify>buffer": true, + "@ensdomains/content-hash>cids": true, + "@ensdomains/content-hash>js-base64": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>multihashes": true } }, - "@ensdomains/content-hash>cids>multihashes": { + "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes>varint": true, - "@ensdomains/content-hash>cids>uint8arrays": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>cids>uint8arrays": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "webpack>events": true } }, - "@ensdomains/content-hash>js-base64": { - "globals": { - "Base64": "write", - "TextDecoder": true, - "TextEncoder": true, - "atob": true, - "btoa": true, - "define": true - }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "browserify>buffer": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays": true, - "sass-embedded>varint": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays": { + "@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "Buffer": true, - "TextDecoder": true, "TextEncoder": true - }, - "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "console.warn": true, - "crypto.subtle.digest": true - } - }, - "@ensdomains/content-hash>multihashes": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase": true, - "@ensdomains/content-hash>multihashes>varint": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase>base-x": { + "@ethereumjs/tx": { "packages": { - "koa>content-disposition>safe-buffer": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, - "@ensdomains/content-hash>multihashes>web-encoding": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx": { "packages": { - "browserify>util": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@ethereumjs/tx": { + "eth-lattice-keyring>@ethereumjs/tx": { "packages": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, + "@ethersproject/providers": true, "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@ethereumjs/tx>@ethereumjs/common": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/providers": true, "browserify>buffer": true, - "webpack>events": true - } - }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { - "globals": { - "DO_NOT_EXPORT_CRC": true, - "define": true - } - }, - "@ethereumjs/tx>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "@ethereumjs/tx>@ethereumjs/util": { @@ -151,78 +131,83 @@ }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true, - "@ethereumjs/tx>ethereum-cryptography": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "webpack>events": true + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "@metamask/smart-transactions-controller>@ethereumjs/util": { "globals": { - "Headers": true, - "TextDecoder": true, - "URL": true, - "btoa": true, + "console.warn": true, "fetch": true }, "packages": { - "browserify>browserify-zlib": true, - "browserify>buffer": true, - "browserify>url": true, - "browserify>util": true, - "https-browserify": true, - "process": true, - "stream-http": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, - "@ethereumjs/tx>ethereum-cryptography": { + "@ethersproject/abi": { "globals": { - "TextDecoder": true, - "crypto": true + "console.log": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true, - "@noble/hashes": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { - "globals": { - "TextEncoder": true - }, + "ethers>@ethersproject/abstract-provider": { "packages": { - "@noble/hashes": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "ethers>@ethersproject/abstract-signer": { "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethersproject/abi": { - "globals": { - "console.log": true - }, + "ethers>@ethersproject/address": { "packages": { "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/rlp": true + } + }, + "ethers>@ethersproject/base64": { + "globals": { + "atob": true, + "btoa": true + }, + "packages": { + "@ethersproject/bytes": true + } + }, + "ethers>@ethersproject/basex": { + "packages": { + "@ethersproject/bytes": true, + "ethers>@ethersproject/properties": true } }, "@ethersproject/bignumber": { "packages": { "@ethersproject/bytes": true, - "bn.js": true, - "ethers>@ethersproject/logger": true + "ethers>@ethersproject/logger": true, + "bn.js": true } }, "@ethersproject/bytes": { @@ -230,17 +215,22 @@ "ethers>@ethersproject/logger": true } }, + "ethers>@ethersproject/constants": { + "packages": { + "@ethersproject/bignumber": true + } + }, "@ethersproject/contracts": { "globals": { "setTimeout": true }, "packages": { "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/abstract-provider": true, "ethers>@ethersproject/abstract-signer": true, "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/transactions": true @@ -248,10 +238,10 @@ }, "@ethersproject/hash": { "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/address": true, "ethers>@ethersproject/base64": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, @@ -260,9 +250,9 @@ }, "@ethersproject/hdnode": { "packages": { + "ethers>@ethersproject/basex": true, "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "ethers>@ethersproject/basex": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, @@ -273,1692 +263,1236 @@ "ethers>@ethersproject/wordlists": true } }, - "@ethersproject/providers": { - "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/json-wallets": { "packages": { - "@ethersproject/bignumber": true, + "ethers>@ethersproject/address": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/providers>bech32": true, - "@metamask/test-bundler>@ethersproject/networks": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "@ethersproject/providers>@ethersproject/random": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/json-wallets>aes-js": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true } }, - "@ethersproject/wallet": { + "ethers>@ethersproject/keccak256": { "packages": { "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/transactions": true + "eth-ens-namehash>js-sha3": true } }, - "@keystonehq/bc-ur-registry-eth": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "uuid": true + "ethers>@ethersproject/logger": { + "globals": { + "console": true } }, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { - "globals": { - "define": true - }, + "ethers>@ethersproject/providers>@ethersproject/networks": { "packages": { - "@ngraveio/bc-ur": true, - "@swc/helpers>tslib": true, - "browserify>buffer": true, - "buffer": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring": { + "@metamask/test-bundler>@ethersproject/networks": { "packages": { - "@ethereumjs/tx": true, - "@keystonehq/bc-ur-registry-eth": true, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, - "@keystonehq/metamask-airgapped-keyring>rlp": true, - "@metamask/obs-store": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { + "ethers>@ethersproject/pbkdf2": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "eth-lattice-keyring>rlp": true, - "uuid": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/sha2": true } }, - "@keystonehq/metamask-airgapped-keyring>rlp": { + "ethers>@ethersproject/properties": { "packages": { - "bn.js": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@lavamoat/lavadome-react": { + "@ethersproject/providers": { "globals": { - "Document.prototype": true, - "DocumentFragment.prototype": true, - "Element.prototype": true, - "Node.prototype": true, + "WebSocket": true, + "clearInterval": true, + "clearTimeout": true, + "console.log": true, "console.warn": true, - "document": true + "setInterval": true, + "setTimeout": true }, "packages": { - "react": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "@metamask/test-bundler>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "@ethersproject/providers>@ethersproject/web": true, + "@ethersproject/providers>bech32": true } }, - "@material-ui/core": { + "ethers>@ethersproject/providers": { "globals": { - "Image": true, - "_formatMuiErrorMessage": true, - "addEventListener": true, + "WebSocket": true, "clearInterval": true, "clearTimeout": true, - "console.error": true, + "console.log": true, "console.warn": true, - "document": true, - "getComputedStyle": true, - "getSelection": true, - "innerHeight": true, - "innerWidth": true, - "matchMedia": true, - "navigator": true, - "performance.now": true, - "removeEventListener": true, - "requestAnimationFrame": true, "setInterval": true, "setTimeout": true }, "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles": true, - "@material-ui/core>@material-ui/system": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "@material-ui/core>popper.js": true, - "@material-ui/core>react-transition-group": true, - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/providers>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/providers>@ethersproject/web": true, + "ethers>@ethersproject/providers>bech32": true } }, - "@material-ui/core>@material-ui/styles": { + "@ethersproject/providers>@ethersproject/random": { "globals": { - "console.error": true, - "console.warn": true, - "document.createComment": true, - "document.head": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, - "@material-ui/core>@material-ui/styles>jss-plugin-global": true, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, - "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "prop-types": true, - "react": true, - "react-redux>hoist-non-react-statics": true + "crypto.getRandomValues": true } }, - "@material-ui/core>@material-ui/styles>jss": { - "globals": { - "CSS": true, - "document.createElement": true, - "document.querySelector": true - }, + "ethers>@ethersproject/random": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { + "ethers>@ethersproject/rlp": { "packages": { - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { - "globals": { - "CSS": true - }, + "ethers>@ethersproject/sha2": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2>hash.js": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-global": { + "ethers>@ethersproject/signing-key": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/signing-key>elliptic": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": { + "ethers>@ethersproject/solidity": { "packages": { - "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { + "ethers>@ethersproject/strings": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { + "ethers>@ethersproject/transactions": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/signing-key": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { - "globals": { - "document.createElement": true, - "document.documentElement": true, - "getComputedStyle": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true - } - }, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": { - "globals": { - "document": true - } - }, - "@material-ui/core>@material-ui/system": { - "globals": { - "console.error": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/utils": true, - "prop-types": true - } - }, - "@material-ui/core>@material-ui/utils": { - "packages": { - "@babel/runtime": true, - "prop-types": true, - "prop-types>react-is": true - } - }, - "@material-ui/core>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator": true, - "requestAnimationFrame": true, - "setTimeout": true - } - }, - "@material-ui/core>react-transition-group": { - "globals": { - "Element": true, - "setTimeout": true - }, - "packages": { - "@material-ui/core>react-transition-group>dom-helpers": true, - "prop-types": true, - "react": true, - "react-dom": true - } - }, - "@material-ui/core>react-transition-group>dom-helpers": { - "packages": { - "@babel/runtime": true - } - }, - "@metamask/abi-utils": { - "packages": { - "@metamask/abi-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true - } - }, - "@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/accounts-controller": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/base-controller": true, - "@metamask/eth-snap-keyring": true, - "@metamask/keyring-api": true, - "@metamask/keyring-controller": true, - "@metamask/utils": true, - "uuid": true - } - }, - "@metamask/address-book-controller": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true - } - }, - "@metamask/announcement-controller": { - "packages": { - "@metamask/announcement-controller>@metamask/base-controller": true - } - }, - "@metamask/announcement-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/approval-controller": { - "globals": { - "console.info": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/rpc-errors": true, - "nanoid": true - } - }, - "@metamask/approval-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/assets-controllers": { - "globals": { - "AbortController": true, - "Headers": true, - "URL": true, - "URLSearchParams": true, - "clearInterval": true, - "clearTimeout": true, - "console.error": true, - "console.log": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/units": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/bignumber": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/abi-utils": true, - "@metamask/base-controller": true, - "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "bn.js": true, - "cockatiel": true, - "ethers>@ethersproject/address": true, - "lodash": true, - "single-call-balance-checker-abi": true, - "uuid": true - } - }, - "@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/browser-passworder": { - "globals": { - "CryptoKey": true, - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "@metamask/browser-passworder>@metamask/utils": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@metamask/browser-passworder>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@ethersproject/wallet": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/transactions": true } }, - "@metamask/controller-utils": { + "@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, "fetch": true, "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/controller-utils>@spruceid/siwe-parser": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/utils": true, - "bn.js": true, - "browserify>buffer": true, - "eslint>fast-deep-equal": true, - "eth-ens-namehash": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser": { - "globals": { - "console.error": true, - "console.log": true - }, - "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/controllers>web3": { - "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/ens-controller": { - "packages": { - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "punycode": true - } - }, - "@metamask/eth-json-rpc-filters": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/safe-event-emitter": true, - "pify": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-json-rpc-middleware": { + "ethers>@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, - "@metamask/eth-json-rpc-middleware>klona": true, - "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-sig-util": true, - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true - } - }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-json-rpc-provider": { - "packages": { - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true, - "uuid": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring": { + "ethers>@ethersproject/web": { "globals": { - "addEventListener": true, - "console.error": true, - "document.createElement": true, - "document.head.appendChild": true, + "clearTimeout": true, "fetch": true, - "removeEventListener": true + "setTimeout": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, - "@metamask/eth-sig-util": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "webpack>events": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "ethers>@ethersproject/wordlists": { + "packages": { + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { + "@metamask/notification-services-controller>firebase>@firebase/app": { "globals": { + "FinalizationRegistry": true, "console.warn": true }, "packages": { - "@ethersproject/abi": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, - "browserify>buffer": true, - "ethers>@ethersproject/rlp": true, - "semver": true + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true + "@metamask/notification-services-controller>firebase>@firebase/util": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { + "@metamask/notification-services-controller>firebase>@firebase/installations": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "BroadcastChannel": true, + "Headers": true, "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, + "console.error": true, + "crypto": true, + "fetch": true, + "msCrypto": true, + "navigator.onLine": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { - "globals": { - "console.warn": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { - "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": true, - "@metamask/ppom-validator>crypto-js": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { "globals": { - "console.warn": true + "console": true }, "packages": { - "wait-on>rxjs": true + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { + "@metamask/notification-services-controller>firebase>@firebase/messaging": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "Headers": true, + "Notification.maxActions": true, + "Notification.permission": true, + "Notification.requestPermission": true, + "PushSubscription.prototype.hasOwnProperty": true, + "ServiceWorkerRegistration": true, + "URL": true, + "addEventListener": true, + "atob": true, "btoa": true, + "clients.matchAll": true, + "clients.openWindow": true, "console.warn": true, "document": true, + "fetch": true, + "indexedDB": true, "location.href": true, + "location.origin": true, "navigator": true, + "origin.replace": true, + "registration.showNotification": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/providers": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/wordlists": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { - "globals": { - "__ledgerLogsListen": "write", - "console.error": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/installations": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { + "@metamask/notification-services-controller>firebase>@firebase/util": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "atob": true, + "browser": true, "btoa": true, - "console.warn": true, + "chrome": true, + "console": true, "document": true, - "location.href": true, + "indexedDB": true, "navigator": true, + "process": true, + "self": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, "process": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { - "globals": { - "crypto": true, - "define": true - } - }, - "@metamask/eth-query": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "watchify>xtend": true + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/bc-ur-registry-eth": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "eth-lattice-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-sig-util": { + "@keystonehq/bc-ur-registry-eth": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>@metamask/utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "uuid": true } }, - "@metamask/eth-sig-util>@metamask/utils": { + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "define": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ngraveio/bc-ur": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "buffer": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "tslib": true } }, - "@metamask/eth-sig-util>tweetnacl": { - "globals": { - "crypto": true, - "msCrypto": true, - "nacl": "write" - }, + "@keystonehq/metamask-airgapped-keyring": { "packages": { - "browserify>browser-resolve": true + "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, + "@keystonehq/bc-ur-registry-eth": true, + "@metamask/obs-store": true, + "browserify>buffer": true, + "webpack>events": true, + "@keystonehq/metamask-airgapped-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-snap-keyring": { + "chart.js>@kurkle/color": { "globals": { - "URL": true, - "console.error": true + "define": true + } + }, + "@lavamoat/lavadome-react": { + "globals": { + "Document.prototype": true, + "DocumentFragment.prototype": true, + "Element.prototype": true, + "Node.prototype": true, + "console.warn": true, + "document": true }, "packages": { - "@ethereumjs/tx": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/eth-snap-keyring>uuid": true, - "@metamask/keyring-api": true, - "@metamask/utils>@metamask/superstruct": true, - "webpack>events": true + "react": true } }, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { + "globals": { + "console.warn": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { + "packages": { + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, + "@metamask/ppom-validator>crypto-js": true } }, - "@metamask/eth-snap-keyring>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.warn": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ethersproject/abi": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/transactions": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, "browserify>buffer": true, - "nock>debug": true, "semver": true } }, - "@metamask/eth-snap-keyring>uuid": { - "globals": { - "crypto": true - } - }, - "@metamask/eth-token-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { "globals": { "console.warn": true }, "packages": { - "@babel/runtime": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, - "@metamask/eth-token-tracker>deep-equal": true, - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/safe-event-emitter": true, - "bn.js": true, - "human-standard-token-abi": true + "wait-on>rxjs": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { + "globals": { + "__ledgerLogsListen": "write", + "console.error": true + } + }, + "@material-ui/core": { "globals": { + "Image": true, + "_formatMuiErrorMessage": true, + "addEventListener": true, + "clearInterval": true, "clearTimeout": true, "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "getSelection": true, + "innerHeight": true, + "innerWidth": true, + "matchMedia": true, + "navigator": true, + "performance.now": true, + "removeEventListener": true, + "requestAnimationFrame": true, + "setInterval": true, "setTimeout": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true, - "pify": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles": true, + "@material-ui/core>@material-ui/system": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>popper.js": true, + "prop-types": true, + "react": true, + "react-dom": true, + "prop-types>react-is": true, + "@material-ui/core>react-transition-group": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { + "@material-ui/core>@material-ui/styles": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.error": true, + "console.warn": true, + "document.createComment": true, + "document.head": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-token-tracker>deep-equal": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, - "@metamask/eth-token-tracker>deep-equal>is-date-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, - "@metamask/eth-token-tracker>deep-equal>which-collection": true, - "@ngraveio/bc-ur>assert>object-is": true, - "browserify>util>is-arguments": true, - "browserify>util>which-typed-array": true, - "gulp>vinyl-fs>object.assign": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>regexp.prototype.flags": true, - "string.prototype.matchall>side-channel": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, + "@material-ui/core>@material-ui/styles>jss-plugin-global": true, + "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, + "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, + "@material-ui/core>@material-ui/styles>jss": true, + "prop-types": true, + "react": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { + "@material-ui/core>@material-ui/system": { + "globals": { + "console.error": true + }, "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true, - "browserify>util>is-arguments": true, - "eslint-plugin-react>array-includes>is-string": true, - "process": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>has-symbols": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "prop-types": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { - "globals": { - "StopIteration": true - }, + "@material-ui/core>@material-ui/utils": { "packages": { - "string.prototype.matchall>internal-slot": true + "@babel/runtime": true, + "prop-types": true, + "prop-types>react-is": true } }, - "@metamask/eth-token-tracker>deep-equal>is-date-object": { + "@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection": { + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-controller>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-trezor-keyring": { - "globals": { - "setTimeout": true - }, + "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "@trezor/connect-web": true, - "browserify>buffer": true, - "webpack>events": true + "@metamask/base-controller": true, + "@metamask/eth-snap-keyring": true, + "@metamask/keyring-api": true, + "@metamask/keyring-controller": true, + "@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "uuid": true } }, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "@metamask/address-book-controller": { "packages": { - "@metamask/eth-sig-util": true, - "@swc/helpers>tslib": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true } }, - "@metamask/eth-trezor-keyring>hdkey": { + "@metamask/announcement-controller": { "packages": { - "browserify>assert": true, - "crypto-browserify": true, - "ethereumjs-util>create-hash>ripemd160": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true + "@metamask/announcement-controller>@metamask/base-controller": true } }, - "@metamask/etherscan-link": { + "@metamask/approval-controller": { "globals": { - "URL": true + "console.info": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/rpc-errors": true, + "nanoid": true } }, - "@metamask/ethjs": { + "@metamask/assets-controllers": { "globals": { + "AbortController": true, + "Headers": true, + "URL": true, + "URLSearchParams": true, "clearInterval": true, - "setInterval": true + "clearTimeout": true, + "console.error": true, + "console.log": true, + "setInterval": true, + "setTimeout": true }, "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-provider-http": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/number-to-bn": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/abi-utils": true, + "@metamask/base-controller": true, + "@metamask/contract-metadata": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/metamask-eth-abis": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, "bn.js": true, - "browserify>buffer": true - } - }, - "@metamask/ethjs-contract": { - "packages": { - "@babel/runtime": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, - "promise-to-callback": true + "cockatiel": true, + "lodash": true, + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, + "single-call-balance-checker-abi": true, + "uuid": true } }, - "@metamask/ethjs-query": { + "@metamask/base-controller": { "globals": { - "console": true + "setTimeout": true }, "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format": true, - "@metamask/ethjs-query>@metamask/ethjs-rpc": true, - "promise-to-callback": true - } - }, - "@metamask/ethjs-query>@metamask/ethjs-format": { - "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "@metamask/ethjs>@metamask/number-to-bn": true + "immer": true } }, - "@metamask/ethjs-query>@metamask/ethjs-rpc": { + "@metamask/announcement-controller>@metamask/base-controller": { + "globals": { + "setTimeout": true + }, "packages": { - "promise-to-callback": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-filter": { + "@metamask/name-controller>@metamask/base-controller": { "globals": { - "clearInterval": true, - "setInterval": true - } - }, - "@metamask/ethjs>@metamask/ethjs-provider-http": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": { + "@metamask/rate-limit-controller>@metamask/base-controller": { "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/ethjs>@metamask/ethjs-unit": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/number-to-bn": true, - "bn.js": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-util": { + "@metamask/browser-passworder": { + "globals": { + "CryptoKey": true, + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, + "@metamask/browser-passworder>@metamask/utils": true, "browserify>buffer": true } }, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true - } - }, - "@metamask/ethjs>@metamask/number-to-bn": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "eth-keyring-controller>@metamask/browser-passworder": { + "globals": { + "crypto": true } }, - "@metamask/ethjs>ethjs-abi": { + "@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/ethjs>ethjs-abi>number-to-bn": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@metamask/ethjs-unit": true, + "@metamask/controller-utils>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, "bn.js": true, - "browserify>buffer": true + "browserify>buffer": true, + "eth-ens-namehash": true, + "eslint>fast-deep-equal": true } }, - "@metamask/ethjs>ethjs-abi>number-to-bn": { + "@metamask/ens-controller": { "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "punycode": true } }, - "@metamask/ethjs>js-sha3": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { "globals": { - "define": true + "clearTimeout": true, + "console.error": true, + "setTimeout": true }, "packages": { - "process": true + "@metamask/safe-event-emitter": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true, + "pify": true } }, - "@metamask/gas-fee-controller": { + "@metamask/network-controller>@metamask/eth-block-tracker": { "globals": { - "clearInterval": true, + "clearTimeout": true, "console.error": true, - "setInterval": true + "setTimeout": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "bn.js": true, - "uuid": true + "@metamask/safe-event-emitter": true, + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, - "@metamask/jazzicon": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring": { "globals": { - "document.createElement": true, - "document.createElementNS": true + "TextEncoder": true }, "packages": { - "@metamask/jazzicon>color": true, - "@metamask/jazzicon>mersenne-twister": true - } - }, - "@metamask/jazzicon>color": { - "packages": { - "@metamask/jazzicon>color>clone": true, - "@metamask/jazzicon>color>color-convert": true, - "@metamask/jazzicon>color>color-string": true - } - }, - "@metamask/jazzicon>color>clone": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/jazzicon>color>color-convert": { - "packages": { - "@metamask/jazzicon>color>color-convert>color-name": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-sig-util": true, + "@metamask/scure-bip39": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@metamask/jazzicon>color>color-string": { + "@metamask/eth-json-rpc-filters": { + "globals": { + "console.error": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/safe-event-emitter": true, + "@metamask/name-controller>async-mutex": true, + "pify": true } }, - "@metamask/json-rpc-engine": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "globals": { + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/json-rpc-engine>@metamask/utils": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true } }, - "@metamask/json-rpc-engine>@metamask/utils": { + "@metamask/eth-json-rpc-middleware": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true, + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>klona": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true } }, - "@metamask/json-rpc-middleware-stream": { - "globals": { - "console.warn": true, - "setTimeout": true - }, + "@metamask/eth-json-rpc-provider": { "packages": { - "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, "@metamask/safe-event-emitter": true, - "readable-stream": true + "uuid": true } }, - "@metamask/json-rpc-middleware-stream>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "addEventListener": true, + "console.error": true, + "document.createElement": true, + "document.head.appendChild": true, + "fetch": true, + "removeEventListener": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-api": { - "globals": { - "URL": true - }, + "@metamask/controller-utils>@metamask/eth-query": { "packages": { - "@metamask/keyring-api>@metamask/utils": true, - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-api>uuid": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/ppom-validator>json-rpc-random-id": true, + "watchify>xtend": true } }, - "@metamask/keyring-api>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/abi-utils": true, + "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-api>uuid": { - "globals": { - "crypto": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/base-controller": true, - "@metamask/browser-passworder": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>ethereumjs-wallet": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/utils": true + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": { - "globals": { - "TextEncoder": true - }, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, - "@metamask/scure-bip39": true, - "browserify>buffer": true + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/keyring-controller>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/eth-sig-util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, "crypto-browserify>randombytes": true } }, - "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "@metamask/eth-snap-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true }, "packages": { + "@ethereumjs/tx": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/keyring-api": true, + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-snap-keyring>@metamask/utils": true, + "webpack>events": true, + "@metamask/eth-snap-keyring>uuid": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": { + "@metamask/eth-token-tracker": { "globals": { - "URL": true + "console.warn": true }, "packages": { - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@babel/runtime": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true, + "@metamask/safe-event-emitter": true, + "bn.js": true, + "@metamask/eth-token-tracker>deep-equal": true, + "human-standard-token-abi": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { + "@metamask/eth-trezor-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, - "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, - "browserify>buffer": true, - "crypto-browserify": true, - "crypto-browserify>randombytes": true, - "eth-lattice-keyring>gridplus-sdk>aes-js": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "uuid": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { - "packages": { - "browserify>assert": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethers>@ethersproject/sha2>hash.js": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true, - "bn.js": true, - "browserify>assert": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, + "@trezor/connect-web": true, "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "@metamask/etherscan-link": { + "globals": { + "URL": true } }, - "@metamask/logging-controller": { + "eth-method-registry>@metamask/ethjs-contract": { "packages": { - "@metamask/base-controller": true, - "uuid": true + "@babel/runtime": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": true, + "eth-ens-namehash>js-sha3": true, + "promise-to-callback": true } }, - "@metamask/logo": { + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": { "globals": { - "addEventListener": true, - "document.body.appendChild": true, - "document.createElementNS": true, - "innerHeight": true, - "innerWidth": true, - "requestAnimationFrame": true - }, - "packages": { - "@metamask/logo>gl-mat4": true, - "@metamask/logo>gl-vec3": true - } - }, - "@metamask/message-manager": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "clearInterval": true, + "setInterval": true } }, - "@metamask/message-manager>jsonschema": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": { "packages": { - "browserify>url": true + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/name-controller": { + "eth-method-registry>@metamask/ethjs-query": { "globals": { - "fetch": true + "console": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/name-controller>@metamask/base-controller": true, - "@metamask/name-controller>@metamask/utils": true, - "@metamask/name-controller>async-mutex": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": true, + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": { "packages": { - "immer": true + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "bn.js": true } }, - "@metamask/name-controller>async-mutex": { - "globals": { - "clearTimeout": true, - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": { "packages": { - "@swc/helpers>tslib": true + "browserify>buffer": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/network-controller": { + "@metamask/gas-fee-controller": { "globals": { - "btoa": true, - "fetch": true, - "setTimeout": true + "clearInterval": true, + "console.error": true, + "setInterval": true }, "packages": { - "@metamask/base-controller": true, "@metamask/controller-utils": true, - "@metamask/eth-json-rpc-middleware": true, - "@metamask/eth-json-rpc-provider": true, - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-block-tracker": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "eslint>fast-deep-equal": true, - "reselect": true, - "uri-js": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "bn.js": true, "uuid": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker": { + "@metamask/jazzicon": { "globals": { - "clearTimeout": true, - "console.error": true, - "setTimeout": true + "document.createElement": true, + "document.createElementNS": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true + "@metamask/jazzicon>color": true, + "@metamask/jazzicon>mersenne-twister": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/json-rpc-engine": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/rpc-errors": true, + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-engine>@metamask/utils": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "@metamask/json-rpc-middleware-stream": { "globals": { - "fetch": true, + "console.warn": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-provider": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true, - "@metamask/rpc-errors": true + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { + "@metamask/snaps-sdk>@metamask/key-tree": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "crypto.subtle": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, + "@metamask/scure-bip39": true, + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/utils>@scure/base": true } }, - "@metamask/notification-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/keyring-api": { + "packages": { + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller": { - "globals": { - "Intl.NumberFormat": true, - "addEventListener": true, - "fetch": true, - "registration": true, - "removeEventListener": true - }, + "@metamask/profile-sync-controller>@metamask/keyring-api": { "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, - "@metamask/notification-services-controller>bignumber.js": true, - "@metamask/notification-services-controller>firebase": true, - "@metamask/profile-sync-controller": true, - "@metamask/utils": true, - "loglevel": true, - "uuid": true + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { - "globals": { - "SuppressedError": true + "@metamask/keyring-controller": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/base-controller": true, + "@metamask/browser-passworder": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, + "@metamask/keyring-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, + "@metamask/keyring-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "@metamask/keyring-controller>ethereumjs-wallet": true } }, - "@metamask/notification-services-controller>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { + "packages": { + "@metamask/keyring-snap-client": true } }, - "@metamask/notification-services-controller>firebase": { + "@metamask/keyring-snap-client": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/messaging": true + "@metamask/keyring-api": true, + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-snap-client>uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app": { + "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { - "FinalizationRegistry": true, - "console.warn": true + "URL": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { + "@metamask/logging-controller": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { + "@metamask/logo": { "globals": { - "console": true + "addEventListener": true, + "document.body.appendChild": true, + "document.createElementNS": true, + "innerHeight": true, + "innerWidth": true, + "requestAnimationFrame": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/logo>gl-mat4": true, + "@metamask/logo>gl-vec3": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": { + "@metamask/message-manager": { + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "uuid": true + } + }, + "@metamask/name-controller": { "globals": { - "DOMException": true, - "IDBCursor": true, - "IDBDatabase": true, - "IDBIndex": true, - "IDBObjectStore": true, - "IDBRequest": true, - "IDBTransaction": true, - "indexedDB.deleteDatabase": true, - "indexedDB.open": true + "fetch": true + }, + "packages": { + "@metamask/name-controller>@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/name-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true } }, - "@metamask/notification-services-controller>firebase>@firebase/installations": { + "@metamask/network-controller": { "globals": { - "BroadcastChannel": true, - "Headers": true, "btoa": true, - "console.error": true, - "crypto": true, "fetch": true, - "msCrypto": true, - "navigator.onLine": true, "setTimeout": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/network-controller>@metamask/eth-block-tracker": true, + "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, + "@metamask/eth-json-rpc-middleware": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true, + "@metamask/utils": true, + "eslint>fast-deep-equal": true, + "reselect": true, + "uri-js": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/messaging": { + "@metamask/transaction-controller>@metamask/nonce-tracker": { + "packages": { + "@ethersproject/providers": true, + "browserify>assert": true, + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true + } + }, + "@metamask/notification-services-controller": { "globals": { - "Headers": true, - "Notification.maxActions": true, - "Notification.permission": true, - "Notification.requestPermission": true, - "PushSubscription.prototype.hasOwnProperty": true, - "ServiceWorkerRegistration": true, - "URL": true, + "Intl.NumberFormat": true, "addEventListener": true, - "atob": true, - "btoa": true, - "clients.matchAll": true, - "clients.openWindow": true, - "console.warn": true, - "document": true, "fetch": true, - "indexedDB": true, - "location.href": true, - "location.origin": true, - "navigator": true, - "origin.replace": true, - "registration.showNotification": true, - "setTimeout": true + "registration": true, + "removeEventListener": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/installations": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true, - "@swc/helpers>tslib": true + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/profile-sync-controller": true, + "@metamask/utils": true, + "@metamask/notification-services-controller>bignumber.js": true, + "@metamask/notification-services-controller>firebase": true, + "loglevel": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/util": { - "globals": { - "atob": true, - "browser": true, - "btoa": true, - "chrome": true, - "console": true, - "document": true, - "indexedDB": true, - "navigator": true, - "process": true, - "self": true, - "setTimeout": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": { "packages": { - "process": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, "@metamask/object-multiplex": { @@ -1970,11 +1504,6 @@ "readable-stream": true } }, - "@metamask/object-multiplex>once": { - "packages": { - "@metamask/object-multiplex>once>wrappy": true - } - }, "@metamask/obs-store": { "packages": { "@metamask/safe-event-emitter": true, @@ -1990,38 +1519,18 @@ "@metamask/controller-utils": true, "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, + "@metamask/permission-controller>@metamask/utils": true, "deep-freeze-strict": true, "immer": true, "nanoid": true } }, - "@metamask/permission-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, "@metamask/permission-log-controller": { "packages": { "@metamask/base-controller": true, "@metamask/permission-log-controller>@metamask/utils": true } }, - "@metamask/permission-log-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, "@metamask/phishing-controller": { "globals": { "TextEncoder": true, @@ -2030,12 +1539,12 @@ "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/base-controller": true, "@metamask/controller-utils": true, "@noble/hashes": true, - "punycode": true, - "webpack-cli>fastest-levenshtein": true + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack-cli>fastest-levenshtein": true, + "punycode": true } }, "@metamask/polling-controller": { @@ -2054,84 +1563,32 @@ "globals": { "MessageEvent.prototype": true, "WorkerGlobalScope": true, - "addEventListener": true, - "browser": true, - "chrome": true, - "location.origin": true, - "postMessage": true, - "removeEventListener": true - }, - "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/ppom-validator": { - "globals": { - "URL": true, - "console.error": true, - "crypto": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/ppom-validator>crypto-js": true, - "@metamask/ppom-validator>elliptic": true, - "await-semaphore": true, - "browserify>buffer": true - } - }, - "@metamask/ppom-validator>crypto-js": { - "globals": { - "crypto": true, - "define": true, - "msCrypto": true - }, - "packages": { - "browserify>browser-resolve": true - } - }, - "@metamask/ppom-validator>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true - } - }, - "@metamask/ppom-validator>elliptic>brorand": { - "globals": { - "crypto": true, - "msCrypto": true + "addEventListener": true, + "browser": true, + "chrome": true, + "location.origin": true, + "postMessage": true, + "removeEventListener": true }, "packages": { - "browserify>browser-resolve": true + "@metamask/post-message-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/ppom-validator>elliptic>hmac-drbg": { + "@metamask/ppom-validator": { + "globals": { + "URL": true, + "console.error": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "ethers>@ethersproject/sha2>hash.js": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "await-semaphore": true, + "browserify>buffer": true, + "@metamask/ppom-validator>crypto-js": true, + "@metamask/ppom-validator>elliptic": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, "@metamask/preferences-controller": { @@ -2157,668 +1614,933 @@ }, "packages": { "@metamask/base-controller": true, + "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/keyring-controller": true, "@metamask/network-controller": true, - "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/profile-sync-controller>@noble/ciphers": true, - "@metamask/profile-sync-controller>siwe": true, "@noble/hashes": true, "browserify>buffer": true, - "loglevel": true + "loglevel": true, + "@metamask/profile-sync-controller>siwe": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api": { + "@metamask/queued-request-controller": { "packages": { - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": true, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/selected-network-controller": true, + "@metamask/utils": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { + "@metamask/rate-limit-controller": { + "globals": { + "setTimeout": true + }, + "packages": { + "@metamask/rate-limit-controller>@metamask/base-controller": true, + "@metamask/rate-limit-controller>@metamask/rpc-errors": true, + "@metamask/rate-limit-controller>@metamask/utils": true + } + }, + "@metamask/remote-feature-flag-controller": { + "packages": { + "@metamask/base-controller": true, + "cockatiel": true, + "uuid": true + } + }, + "@metamask/rpc-errors": { + "packages": { + "@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/rate-limit-controller>@metamask/rpc-errors": { + "packages": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "webpack>events": true + } + }, + "@metamask/scure-bip39": { "globals": { - "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/scure-bip39>@noble/hashes": true, + "@metamask/utils>@scure/base": true } }, - "@metamask/profile-sync-controller>@noble/ciphers": { + "@metamask/selected-network-controller": { + "packages": { + "@metamask/base-controller": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true + } + }, + "@metamask/signature-controller": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "crypto": true + "fetch": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller": true, + "@metamask/logging-controller": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "@metamask/message-manager>jsonschema": true, + "uuid": true } }, - "@metamask/profile-sync-controller>siwe": { + "@metamask/smart-transactions-controller": { "globals": { + "URLSearchParams": true, + "clearInterval": true, "console.error": true, - "console.warn": true + "console.log": true, + "fetch": true, + "setInterval": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random": true, - "ethers": true + "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethersproject/bytes": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "@metamask/transaction-controller": true, + "@metamask/smart-transactions-controller>bignumber.js": true, + "browserify>buffer": true, + "fast-json-patch": true, + "lodash": true } }, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "@metamask/snaps-controllers": { "globals": { - "console.error": true, - "console.log": true + "DecompressionStream": true, + "URL": true, + "clearTimeout": true, + "document.getElementById": true, + "fetch.bind": true, + "setTimeout": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/json-rpc-middleware-stream": true, + "@metamask/object-multiplex": true, + "@metamask/permission-controller": true, + "@metamask/post-message-stream": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/snaps-registry": true, + "@metamask/snaps-rpc-methods": true, + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/snaps-controllers>@metamask/utils": true, + "@metamask/snaps-controllers>@xstate/fsm": true, + "@metamask/name-controller>async-mutex": true, + "browserify>browserify-zlib": true, + "@metamask/snaps-controllers>concat-stream": true, + "eslint>fast-deep-equal": true, + "@metamask/snaps-controllers>get-npm-tarball-url": true, + "immer": true, + "luxon": true, + "nanoid": true, + "readable-stream": true, + "@metamask/snaps-controllers>readable-web-to-node-stream": true, + "semver": true, + "@metamask/snaps-controllers>tar-stream": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random": { + "@metamask/snaps-execution-environments": { "globals": { - "crypto": true, - "msCrypto": true + "document.getElementById": true }, "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, - "browserify>browser-resolve": true + "@metamask/post-message-stream": true, + "@metamask/snaps-utils": true, + "@metamask/utils": true, + "@metamask/snaps-execution-environments>@metamask/utils": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "@metamask/snaps-utils>@metamask/snaps-registry": { "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@noble/hashes": true } }, - "@metamask/queued-request-controller": { + "@metamask/snaps-rpc-methods": { "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, "@metamask/rpc-errors": true, - "@metamask/selected-network-controller": true, - "@metamask/utils": true + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-rpc-methods>@metamask/utils": true, + "@noble/hashes": true, + "luxon": true } }, - "@metamask/rate-limit-controller": { + "@metamask/snaps-sdk": { "globals": { + "fetch": true + }, + "packages": { + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-sdk>@metamask/utils": true + } + }, + "@metamask/snaps-utils": { + "globals": { + "File": true, + "FileReader": true, + "TextDecoder": true, + "TextEncoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "crypto": true, + "document.body.appendChild": true, + "document.createElement": true, + "fetch": true + }, + "packages": { + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/slip44": true, + "@metamask/snaps-sdk": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/utils": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "chalk": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>fast-xml-parser": true, + "@metamask/snaps-utils>marked": true, + "@metamask/snaps-utils>rfdc": true, + "semver": true, + "@metamask/snaps-utils>validate-npm-package-name": true + } + }, + "@metamask/transaction-controller": { + "globals": { + "clearTimeout": true, + "console.error": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/rate-limit-controller>@metamask/base-controller": true, - "@metamask/rate-limit-controller>@metamask/rpc-errors": true, - "@metamask/rate-limit-controller>@metamask/utils": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/abi": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/metamask-eth-abis": true, + "@metamask/network-controller": true, + "@metamask/transaction-controller>@metamask/nonce-tracker": true, + "@metamask/rpc-errors": true, + "@metamask/transaction-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "bn.js": true, + "browserify>buffer": true, + "eth-method-registry": true, + "webpack>events": true, + "fast-json-patch": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/base-controller": { + "@metamask/user-operation-controller": { "globals": { - "setTimeout": true + "fetch": true }, "packages": { - "immer": true - } - }, - "@metamask/rate-limit-controller>@metamask/rpc-errors": { - "packages": { - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/transaction-controller": true, + "@metamask/utils": true, + "bn.js": true, + "webpack>events": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rate-limit-controller>@metamask/utils": { + "@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/remote-feature-flag-controller": { - "packages": { - "@metamask/base-controller": true, - "cockatiel": true - } - }, - "@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true - } - }, - "@metamask/rpc-errors>@metamask/utils": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rpc-methods-flask>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/rpc-methods>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/safe-event-emitter": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39": { + "@metamask/browser-passworder>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/scure-bip39>@noble/hashes": true, - "@metamask/utils>@scure/base": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39>@noble/hashes": { + "@metamask/controller-utils>@metamask/utils": { "globals": { - "TextEncoder": true, - "crypto": true - } - }, - "@metamask/selected-network-controller": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/base-controller": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/keyring-controller": true, - "@metamask/logging-controller": true, - "@metamask/message-manager>jsonschema": true, - "@metamask/signature-controller>@metamask/eth-sig-util": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util": { + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/smart-transactions-controller": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { "globals": { - "URLSearchParams": true, - "clearInterval": true, - "console.error": true, - "console.log": true, - "fetch": true, - "setInterval": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bytes": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/transaction-controller": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "fast-json-patch": true, - "lodash": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { - "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { - "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/eth-json-rpc-middleware>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/util": { - "globals": { - "console.warn": true, - "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "webpack>events": true - } - }, - "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>bignumber.js": { + "@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "DecompressionStream": true, - "URL": true, - "clearTimeout": true, - "document.getElementById": true, - "fetch.bind": true, - "setTimeout": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, - "@metamask/json-rpc-middleware-stream": true, - "@metamask/object-multiplex": true, - "@metamask/permission-controller": true, - "@metamask/post-message-stream": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-controllers>@xstate/fsm": true, - "@metamask/snaps-controllers>concat-stream": true, - "@metamask/snaps-controllers>get-npm-tarball-url": true, - "@metamask/snaps-controllers>readable-web-to-node-stream": true, - "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-rpc-methods": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-utils": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/utils": true, - "browserify>browserify-zlib": true, - "eslint>fast-deep-equal": true, - "immer": true, - "nanoid": true, - "readable-stream": true, + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-controllers-flask>nanoid": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/snaps-controllers>concat-stream": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "readable-stream": true, - "terser>source-map-support>buffer-from": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>nanoid": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>readable-web-to-node-stream": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "readable-stream": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>b4a": true, - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx": true, - "browserify>browser-resolve": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>b4a": { + "@metamask/eth-snap-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx": { + "@metamask/json-rpc-engine>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true, - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { + "@metamask/json-rpc-middleware-stream>@metamask/utils": { "globals": { - "queueMicrotask": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-execution-environments": { + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": { "globals": { - "document.getElementById": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/post-message-stream": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-rpc-methods": { + "@metamask/keyring-api>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk": { + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk>@metamask/key-tree": { + "@metamask/keyring-controller>@metamask/utils": { "globals": { - "crypto.subtle": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/scure-bip39": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils": { + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { "globals": { - "File": true, - "FileReader": true, "TextDecoder": true, - "TextEncoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "crypto": true, - "document.body.appendChild": true, - "document.createElement": true, - "fetch": true + "TextEncoder": true }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils>@metamask/slip44": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>fast-xml-parser": true, - "@metamask/snaps-utils>marked": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, "@noble/hashes": true, - "chalk": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>cron-parser": { + "@metamask/permission-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>browser-resolve": true, - "luxon": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>fast-xml-parser": { + "@metamask/permission-log-controller>@metamask/utils": { "globals": { - "entityName": true, - "val": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/snaps-utils>fast-xml-parser>strnum": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>marked": { + "@metamask/post-message-stream>@metamask/utils": { "globals": { - "console.error": true, - "console.warn": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>rfdc": { + "@metamask/rate-limit-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>buffer": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name": { + "@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-utils>validate-npm-package-name>builtins": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name>builtins": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "process": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/test-bundler>@ethersproject/networks": { + "@metamask/snaps-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "ethers>@ethersproject/logger": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller": { + "@metamask/snaps-execution-environments>@metamask/utils": { "globals": { - "clearTimeout": true, - "console.error": true, - "fetch": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/abi": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/network-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller>@metamask/nonce-tracker": true, - "@metamask/utils": true, - "bn.js": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "eth-method-registry": true, - "fast-json-patch": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker": { + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true, - "browserify>assert": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { + "@metamask/snaps-rpc-methods>@metamask/utils": { "globals": { - "clearTimeout": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/user-operation-controller": { + "@metamask/snaps-sdk>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "bn.js": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/utils": { + "@metamask/snaps-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/utils>@scure/base": { + "@metamask/transaction-controller>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, "@ngraveio/bc-ur": { "packages": { "@ngraveio/bc-ur>@keystonehq/alias-sampling": true, + "browserify>assert": true, "@ngraveio/bc-ur>bignumber.js": true, + "browserify>buffer": true, "@ngraveio/bc-ur>cbor-sync": true, "@ngraveio/bc-ur>crc": true, "@ngraveio/bc-ur>jsbi": true, - "addons-linter>sha.js": true, - "browserify>assert": true, - "browserify>buffer": true + "addons-linter>sha.js": true } }, - "@ngraveio/bc-ur>assert>object-is": { + "@metamask/profile-sync-controller>@noble/ciphers": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "crypto": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { + "globals": { + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true } }, - "@ngraveio/bc-ur>bignumber.js": { + "@noble/hashes": { "globals": { - "crypto": true, - "define": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>cbor-sync": { + "@metamask/scure-bip39>@noble/hashes": { "globals": { - "define": true - }, - "packages": { - "browserify>buffer": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>crc": { - "packages": { - "browserify>buffer": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>jsbi": { + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": { "globals": { - "define": true + "TextEncoder": true, + "crypto": true } }, - "@noble/hashes": { + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { "globals": { "TextEncoder": true, "crypto": true @@ -2835,6 +2557,20 @@ "navigator.userAgent": true } }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "globals": { + "console.log": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "globals": { + "XMLHttpRequest": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + } + }, "@reduxjs/toolkit": { "globals": { "AbortController": true, @@ -2846,42 +2582,46 @@ "setTimeout": true }, "packages": { - "@reduxjs/toolkit>reselect": true, "immer": true, "process": true, "redux": true, - "redux-thunk": true - } - }, - "@segment/loosely-validate-event": { - "packages": { - "@segment/loosely-validate-event>component-type": true, - "@segment/loosely-validate-event>join-component": true, - "browserify>assert": true, - "browserify>buffer": true + "redux-thunk": true, + "@reduxjs/toolkit>reselect": true } }, - "@sentry/browser": { + "react-router-dom-v5-compat>@remix-run/router": { "globals": { - "PerformanceObserver.supportedEntryTypes": true, + "AbortController": true, + "DOMException": true, + "FormData": true, + "Headers": true, "Request": true, + "Response": true, "URL": true, - "XMLHttpRequest.prototype": true, - "__SENTRY_DEBUG__": true, - "__SENTRY_RELEASE__": true, - "addEventListener": true, - "console.error": true, - "indexedDB.open": true, - "performance.timeOrigin": true, - "setTimeout": true - }, + "URLSearchParams": true, + "console": true, + "document.defaultView": true + } + }, + "@metamask/utils>@scure/base": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "packages": { + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true, + "@metamask/utils>@scure/base": true + } + }, + "@segment/loosely-validate-event": { "packages": { - "@sentry/browser>@sentry-internal/browser-utils": true, - "@sentry/browser>@sentry-internal/feedback": true, - "@sentry/browser>@sentry-internal/replay": true, - "@sentry/browser>@sentry-internal/replay-canvas": true, - "@sentry/browser>@sentry/core": true, - "@sentry/utils": true + "browserify>assert": true, + "browserify>buffer": true, + "@segment/loosely-validate-event>component-type": true, + "@segment/loosely-validate-event>join-component": true } }, "@sentry/browser>@sentry-internal/browser-utils": { @@ -2920,6 +2660,25 @@ "@sentry/utils": true } }, + "@sentry/browser>@sentry-internal/replay-canvas": { + "globals": { + "Blob": true, + "HTMLCanvasElement": true, + "HTMLImageElement": true, + "ImageData": true, + "URL.createObjectURL": true, + "WeakRef": true, + "Worker": true, + "cancelAnimationFrame": true, + "console.error": true, + "createImageBitmap": true, + "document": true + }, + "packages": { + "@sentry/browser>@sentry/core": true, + "@sentry/utils": true + } + }, "@sentry/browser>@sentry-internal/replay": { "globals": { "Blob": true, @@ -2969,21 +2728,25 @@ "@sentry/utils": true } }, - "@sentry/browser>@sentry-internal/replay-canvas": { + "@sentry/browser": { "globals": { - "Blob": true, - "HTMLCanvasElement": true, - "HTMLImageElement": true, - "ImageData": true, - "URL.createObjectURL": true, - "WeakRef": true, - "Worker": true, - "cancelAnimationFrame": true, + "PerformanceObserver.supportedEntryTypes": true, + "Request": true, + "URL": true, + "XMLHttpRequest.prototype": true, + "__SENTRY_DEBUG__": true, + "__SENTRY_RELEASE__": true, + "addEventListener": true, "console.error": true, - "createImageBitmap": true, - "document": true + "indexedDB.open": true, + "performance.timeOrigin": true, + "setTimeout": true }, "packages": { + "@sentry/browser>@sentry-internal/browser-utils": true, + "@sentry/browser>@sentry-internal/feedback": true, + "@sentry/browser>@sentry-internal/replay-canvas": true, + "@sentry/browser>@sentry-internal/replay": true, "@sentry/browser>@sentry/core": true, "@sentry/utils": true } @@ -3079,20 +2842,61 @@ "btoa": true } }, - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { + "@metamask/controller-utils>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "react-markdown>unist-util-visit": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true } }, - "@storybook/addon-knobs>qs": { + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "string.prototype.matchall>side-channel": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true + } + }, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true } }, - "@swc/helpers>tslib": { + "@metamask/profile-sync-controller>siwe>@stablelib/random": { "globals": { - "SuppressedError": true, - "define": true + "crypto": true, + "msCrypto": true + }, + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, + "browserify>browser-resolve": true + } + }, + "@trezor/connect-web>@trezor/connect-common": { + "globals": { + "console.warn": true, + "localStorage.getItem": true, + "localStorage.setItem": true, + "navigator": true, + "setTimeout": true, + "window": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, + "@trezor/connect-web>@trezor/utils": true, + "tslib": true + } + }, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "packages": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "tslib": true } }, "@trezor/connect-web": { @@ -3119,35 +2923,20 @@ "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/connect-common": true, + "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/utils": true, - "webpack>events": true + "webpack>events": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect": { "packages": { - "@swc/helpers>tslib": true, "@trezor/connect-web>@trezor/connect>@trezor/protobuf": true, "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, "@trezor/connect-web>@trezor/connect>@trezor/transport": true, - "@trezor/connect-web>@trezor/utils": true - } - }, - "@trezor/connect-web>@trezor/connect-common": { - "globals": { - "console.warn": true, - "localStorage.getItem": true, - "localStorage.setItem": true, - "navigator": true, - "setTimeout": true, - "window": true - }, - "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, - "@trezor/connect-web>@trezor/utils": true + "@trezor/connect-web>@trezor/utils": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": { @@ -3163,157 +2952,248 @@ "screen.width": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true, - "process": true + "process": true, + "tslib": true, + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true } }, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, + "browserify>buffer": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, + "tslib": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { "globals": { - "define": true + "console.warn": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, + "browserify>buffer": true, + "ts-mixer": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "@trezor/connect-web>@trezor/utils": { + "globals": { + "AbortController": true, + "Intl.NumberFormat": true, + "clearInterval": true, + "clearTimeout": true, + "console.error": true, + "console.info": true, + "console.log": true, + "console.warn": true, + "setInterval": true, + "setTimeout": true + }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, - "browserify>buffer": true + "@trezor/connect-web>@trezor/utils>bignumber.js": true, + "browserify>buffer": true, + "webpack>events": true, + "tslib": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { + "@welldone-software/why-did-you-render": { "globals": { - "process": true, + "Element": true, + "console.group": true, + "console.groupCollapsed": true, + "console.groupEnd": true, + "console.log": true, + "console.warn": true, + "define": true, "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true + "lodash": true, + "react": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "@zxing/browser": { "globals": { - "console.log": true + "HTMLElement": true, + "HTMLImageElement": true, + "HTMLVideoElement": true, + "clearTimeout": true, + "console.error": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library": true + } + }, + "@zxing/library": { + "globals": { + "HTMLImageElement": true, + "HTMLVideoElement": true, + "TextDecoder": true, + "TextEncoder": true, + "URL.createObjectURL": true, + "btoa": true, + "console.log": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library>ts-custom-error": true + } + }, + "@lavamoat/lavapack>readable-stream>abort-controller": { + "globals": { + "AbortController": true + } + }, + "currency-formatter>accounting": { + "globals": { + "define": true + } + }, + "ethers>@ethersproject/json-wallets>aes-js": { + "globals": { + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>aes-js": { + "globals": { + "define": true + } + }, + "chalk>ansi-styles": { + "packages": { + "chalk>ansi-styles>color-convert": true + } + }, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { + "packages": { + "browserify>buffer": true + } + }, + "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true + } + }, + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "browserify>vm-browserify": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "browserify>assert": { "globals": { - "XMLHttpRequest": true + "Buffer": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + "react>object-assign": true, + "browserify>assert>util": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { + "@metamask/name-controller>async-mutex": { "globals": { - "console.warn": true + "clearTimeout": true, + "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, - "browserify>buffer": true, - "ts-mixer": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils": { + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { "globals": { - "AbortController": true, - "Intl.NumberFormat": true, - "clearInterval": true, "clearTimeout": true, - "console.error": true, - "console.info": true, - "console.log": true, - "console.warn": true, - "setInterval": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/utils>bignumber.js": true, - "browserify>buffer": true, - "webpack>events": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "string.prototype.matchall>es-abstract>available-typed-arrays": { + "packages": { + "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true } }, - "@welldone-software/why-did-you-render": { + "await-semaphore": { + "packages": { + "process": true, + "browserify>timers-browserify": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { "globals": { - "Element": true, - "console.group": true, - "console.groupCollapsed": true, - "console.groupEnd": true, - "console.log": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, - "define": true, + "document": true, + "location.href": true, + "navigator": true, "setTimeout": true }, "packages": { - "lodash": true, - "react": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/browser": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { "globals": { - "HTMLElement": true, - "HTMLImageElement": true, - "HTMLVideoElement": true, - "clearTimeout": true, - "console.error": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/library": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { "globals": { - "HTMLImageElement": true, - "HTMLVideoElement": true, - "TextDecoder": true, - "TextEncoder": true, - "URL.createObjectURL": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, "btoa": true, - "console.log": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library>ts-custom-error": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "addons-linter>sha.js": { - "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@metamask/snaps-controllers>tar-stream>b4a": { + "globals": { + "TextDecoder": true, + "TextEncoder": true } }, - "await-semaphore": { + "@ensdomains/content-hash>multihashes>multibase>base-x": { "packages": { - "browserify>timers-browserify": true, - "process": true - } - }, - "axios>form-data": { - "globals": { - "FormData": true + "koa>content-disposition>safe-buffer": true } }, "base32-encode": { @@ -3327,139 +3207,178 @@ "define": true } }, - "blo": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { "globals": { - "btoa": true + "crypto": true, + "define": true } }, - "bn.js": { + "@metamask/notification-services-controller>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "define": true } }, - "bowser": { + "@metamask/smart-transactions-controller>bignumber.js": { "globals": { + "crypto": true, "define": true } }, - "browserify>assert": { + "@ngraveio/bc-ur>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>assert>util": true, - "react>object-assign": true + "crypto": true, + "define": true } }, - "browserify>assert>util": { + "@trezor/connect-web>@trezor/utils>bignumber.js": { "globals": { - "console.error": true, - "console.log": true, - "console.trace": true, - "process": true - }, + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bitwise": { "packages": { - "browserify>assert>util>inherits": true, - "process": true + "browserify>buffer": true } }, - "browserify>browserify-zlib": { + "blo": { + "globals": { + "btoa": true + } + }, + "bn.js": { + "globals": { + "Buffer": true + }, "packages": { - "browserify>assert": true, - "browserify>browserify-zlib>pako": true, - "browserify>buffer": true, - "browserify>util": true, - "process": true, - "stream-browserify": true + "browserify>browser-resolve": true } }, - "browserify>buffer": { + "eth-lattice-keyring>gridplus-sdk>borc": { "globals": { "console": true }, "packages": { - "base64-js": true, - "buffer>ieee754": true + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, + "browserify>buffer": true, + "buffer>ieee754": true, + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true } }, - "browserify>punycode": { + "bowser": { "globals": { "define": true } }, - "browserify>string_decoder": { + "@metamask/ppom-validator>elliptic>brorand": { + "globals": { + "crypto": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "ethereumjs-util>ethereum-cryptography>browserify-aes": { "packages": { + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "pumpify>inherits": true, "koa>content-disposition>safe-buffer": true } }, - "browserify>timers-browserify": { - "globals": { - "clearInterval": true, - "clearTimeout": true, - "setInterval": true, - "setTimeout": true - }, + "crypto-browserify>browserify-cipher": { "packages": { - "process": true + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "crypto-browserify>browserify-cipher>browserify-des": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true } }, - "browserify>url": { + "crypto-browserify>browserify-cipher>browserify-des": { "packages": { - "@storybook/addon-knobs>qs": true, - "browserify>punycode": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>browserify-des>des.js": true, + "pumpify>inherits": true } }, - "browserify>util": { - "globals": { - "console.error": true, - "console.log": true, - "console.trace": true - }, + "crypto-browserify>public-encrypt>browserify-rsa": { "packages": { - "browserify>util>is-arguments": true, - "browserify>util>is-typed-array": true, - "browserify>util>which-typed-array": true, - "koa>is-generator-function": true, + "bn.js": true, + "browserify>buffer": true, + "crypto-browserify>randombytes": true + } + }, + "crypto-browserify>browserify-sign": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>create-hmac": true, + "@metamask/ppom-validator>elliptic": true, + "pumpify>inherits": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "stream-browserify": true + } + }, + "browserify>browserify-zlib": { + "packages": { + "browserify>assert": true, + "browserify>buffer": true, + "browserify>browserify-zlib>pako": true, "process": true, - "pumpify>inherits": true + "stream-browserify": true, + "browserify>util": true } }, - "browserify>util>is-arguments": { + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true } }, - "browserify>util>is-typed-array": { + "ethereumjs-util>ethereum-cryptography>bs58check": { "packages": { - "browserify>util>which-typed-array": true + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, + "ethereumjs-util>create-hash": true, + "koa>content-disposition>safe-buffer": true } }, - "browserify>util>which-typed-array": { + "buffer": { + "globals": { + "console": true + }, "packages": { - "browserify>util>which-typed-array>for-each": true, - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>available-typed-arrays": true, - "string.prototype.matchall>es-abstract>gopd": true + "base64-js": true, + "buffer>ieee754": true } }, - "browserify>util>which-typed-array>for-each": { + "terser>source-map-support>buffer-from": { "packages": { - "string.prototype.matchall>es-abstract>is-callable": true + "browserify>buffer": true } }, - "browserify>vm-browserify": { - "globals": { - "document.body.appendChild": true, - "document.body.removeChild": true, - "document.createElement": true + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "packages": { + "browserify>buffer": true } }, - "buffer": { + "browserify>buffer": { "globals": { "console": true }, @@ -3468,20 +3387,33 @@ "buffer>ieee754": true } }, - "chalk": { + "@metamask/snaps-utils>validate-npm-package-name>builtins": { "packages": { - "chalk>ansi-styles": true, - "chalk>supports-color": true + "process": true, + "semver": true } }, - "chalk>ansi-styles": { + "string.prototype.matchall>call-bind": { "packages": { - "chalk>ansi-styles>color-convert": true + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>call-bind>set-function-length": true } }, - "chalk>ansi-styles>color-convert": { + "@ngraveio/bc-ur>cbor-sync": { + "globals": { + "define": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "browserify>buffer": true + } + }, + "chalk": { + "packages": { + "chalk>ansi-styles": true, + "chalk>supports-color": true } }, "chart.js": { @@ -3505,9 +3437,20 @@ "chart.js>@kurkle/color": true } }, - "chart.js>@kurkle/color": { - "globals": { - "define": true + "@ensdomains/content-hash>cids": { + "packages": { + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>cids>multihashes": true, + "@ensdomains/content-hash>cids>uint8arrays": true + } + }, + "ethereumjs-util>create-hash>cipher-base": { + "packages": { + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true, + "stream-browserify": true, + "browserify>string_decoder": true } }, "classnames": { @@ -3516,6 +3459,11 @@ "define": true } }, + "@metamask/jazzicon>color>clone": { + "packages": { + "browserify>buffer": true + } + }, "cockatiel": { "globals": { "AbortController": true, @@ -3529,6 +3477,37 @@ "process": true } }, + "chalk>ansi-styles>color-convert": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color>color-convert": { + "packages": { + "@metamask/jazzicon>color>color-convert>color-name": true + } + }, + "@metamask/jazzicon>color>color-string": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color": { + "packages": { + "@metamask/jazzicon>color>clone": true, + "@metamask/jazzicon>color>color-convert": true, + "@metamask/jazzicon>color>color-string": true + } + }, + "@metamask/snaps-controllers>concat-stream": { + "packages": { + "terser>source-map-support>buffer-from": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "readable-stream": true, + "browserify>concat-stream>typedarray": true + } + }, "copy-to-clipboard": { "globals": { "clipboardData": true, @@ -3547,10 +3526,47 @@ "copy-to-clipboard>toggle-selection": true } }, - "copy-to-clipboard>toggle-selection": { + "@ethereumjs/tx>@ethereumjs/common>crc-32": { "globals": { - "document.activeElement": true, - "document.getSelection": true + "DO_NOT_EXPORT_CRC": true, + "define": true + } + }, + "@ngraveio/bc-ur>crc": { + "packages": { + "browserify>buffer": true + } + }, + "crypto-browserify>create-ecdh": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "@metamask/ppom-validator>elliptic": true + } + }, + "ethereumjs-util>create-hash": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>md5.js": true, + "ethereumjs-util>create-hash>ripemd160": true, + "addons-linter>sha.js": true + } + }, + "crypto-browserify>create-hmac": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "ethereumjs-util>create-hash": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true + } + }, + "@metamask/snaps-utils>cron-parser": { + "packages": { + "browserify>browser-resolve": true, + "luxon": true } }, "crypto-browserify": { @@ -3558,303 +3574,453 @@ "crypto-browserify>browserify-cipher": true, "crypto-browserify>browserify-sign": true, "crypto-browserify>create-ecdh": true, + "ethereumjs-util>create-hash": true, "crypto-browserify>create-hmac": true, "crypto-browserify>diffie-hellman": true, "crypto-browserify>pbkdf2": true, "crypto-browserify>public-encrypt": true, "crypto-browserify>randombytes": true, - "crypto-browserify>randomfill": true, - "ethereumjs-util>create-hash": true + "crypto-browserify>randomfill": true } }, - "crypto-browserify>browserify-cipher": { + "@metamask/ppom-validator>crypto-js": { + "globals": { + "crypto": true, + "define": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "react-beautiful-dnd>css-box-model": { + "globals": { + "getComputedStyle": true, + "pageXOffset": true, + "pageYOffset": true + }, + "packages": { + "react-router-dom>tiny-invariant": true + } + }, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { + "globals": { + "document.createElement": true, + "document.documentElement": true, + "getComputedStyle": true + }, + "packages": { + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true + } + }, + "currency-formatter": { + "packages": { + "currency-formatter>accounting": true, + "currency-formatter>locale-currency": true, + "react>object-assign": true + } + }, + "debounce-stream": { + "packages": { + "debounce-stream>debounce": true, + "debounce-stream>duplexer": true, + "debounce-stream>through": true + } + }, + "debounce-stream>debounce": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "nock>debug": { + "globals": { + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true + }, + "packages": { + "nock>debug>ms": true, + "process": true + } + }, + "@metamask/eth-token-tracker>deep-equal": { + "packages": { + "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, + "string.prototype.matchall>call-bind": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, + "string.prototype.matchall>get-intrinsic": true, + "browserify>util>is-arguments": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "string.prototype.matchall>es-abstract>is-regex": true, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "@ngraveio/bc-ur>assert>object-is": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true, + "gulp>vinyl-fs>object.assign": true, + "string.prototype.matchall>regexp.prototype.flags": true, + "string.prototype.matchall>side-channel": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, + "@metamask/eth-token-tracker>deep-equal>which-collection": true, + "browserify>util>which-typed-array": true + } + }, + "string.prototype.matchall>define-properties>define-data-property": { + "packages": { + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>gopd": true + } + }, + "string.prototype.matchall>define-properties": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true + } + }, + "crypto-browserify>browserify-cipher>browserify-des>des.js": { "packages": { - "crypto-browserify>browserify-cipher>browserify-des": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true } }, - "crypto-browserify>browserify-cipher>browserify-des": { + "crypto-browserify>diffie-hellman": { "packages": { + "bn.js": true, "browserify>buffer": true, - "crypto-browserify>browserify-cipher>browserify-des>des.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "pumpify>inherits": true + "crypto-browserify>diffie-hellman>miller-rabin": true, + "crypto-browserify>randombytes": true } }, - "crypto-browserify>browserify-cipher>browserify-des>des.js": { + "@material-ui/core>react-transition-group>dom-helpers": { "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "@babel/runtime": true } }, - "crypto-browserify>browserify-cipher>evp_bytestokey": { + "debounce-stream>duplexer": { "packages": { - "ethereumjs-util>create-hash>md5.js": true, - "koa>content-disposition>safe-buffer": true + "stream-browserify": true } }, - "crypto-browserify>browserify-sign": { + "ethers>@ethersproject/signing-key>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "ethereumjs-util>create-hash": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, "pumpify>inherits": true, - "stream-browserify": true + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-ecdh": { + "@metamask/ppom-validator>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-hmac": { + "eth-lattice-keyring>gridplus-sdk>elliptic": { "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>diffie-hellman": { + "string.prototype.matchall>call-bind>es-define-property": { "packages": { - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>diffie-hellman>miller-rabin": true, - "crypto-browserify>randombytes": true + "string.prototype.matchall>get-intrinsic": true } }, - "crypto-browserify>diffie-hellman>miller-rabin": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "bn.js": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>has-symbols": true, + "browserify>util>is-arguments": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "eslint-plugin-react>array-includes>is-string": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "process": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true } }, - "crypto-browserify>pbkdf2": { + "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { "globals": { - "crypto": true, - "process": true, - "queueMicrotask": true, - "setImmediate": true, - "setTimeout": true + "intToBuffer": true }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "bn.js": true, + "buffer": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt": { + "eth-ens-namehash": { + "globals": { + "name": "write" + }, "packages": { - "bn.js": true, "browserify>buffer": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>create-hash": true + "eth-ens-namehash>idna-uts46-hx": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt>browserify-rsa": { + "eth-lattice-keyring": { + "globals": { + "addEventListener": true, + "browser": true, + "clearInterval": true, + "fetch": true, + "open": true, + "setInterval": true + }, "packages": { + "eth-lattice-keyring>@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, - "crypto-browserify>randombytes": true + "crypto-browserify": true, + "webpack>events": true, + "eth-lattice-keyring>gridplus-sdk": true, + "eth-lattice-keyring>rlp": true } }, - "crypto-browserify>public-encrypt>parse-asn1": { + "eth-method-registry": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "crypto-browserify>pbkdf2": true, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true } }, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "@ethereumjs/tx>ethereum-cryptography": { + "globals": { + "TextDecoder": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "bn.js": true, - "browserify>buffer": true, - "browserify>vm-browserify": true, - "pumpify>inherits": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "crypto-browserify>randombytes": { + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "crypto-browserify>randomfill": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "crypto-browserify>randombytes": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "currency-formatter": { + "ethereumjs-util>ethereum-cryptography": { "packages": { - "currency-formatter>accounting": true, - "currency-formatter>locale-currency": true, - "react>object-assign": true - } - }, - "currency-formatter>accounting": { - "globals": { - "define": true - } - }, - "currency-formatter>locale-currency": { - "globals": { - "countryCode": true + "browserify>buffer": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "ganache>secp256k1": true } }, - "debounce-stream": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { "packages": { - "debounce-stream>debounce": true, - "debounce-stream>duplexer": true, - "debounce-stream>through": true + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify>create-hmac": true, + "ethers>@ethersproject/sha2>hash.js": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true } }, - "debounce-stream>debounce": { - "globals": { - "clearTimeout": true, - "setTimeout": true + "ethereumjs-util": { + "packages": { + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "ethereumjs-util>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "ethereumjs-util>rlp": true } }, - "debounce-stream>duplexer": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { "packages": { - "stream-browserify": true + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true } }, - "debounce-stream>through": { + "@metamask/keyring-controller>ethereumjs-wallet": { "packages": { - "process": true, - "stream-browserify": true + "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, + "crypto-browserify>randombytes": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true, + "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, + "uuid": true } }, - "depcheck>@vue/compiler-sfc>postcss>nanoid": { - "globals": { - "crypto.getRandomValues": true + "ethers": { + "packages": { + "@ethersproject/abi": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/contracts": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/providers": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/solidity": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/units": true, + "@ethersproject/wallet": true, + "ethers>@ethersproject/web": true, + "ethers>@ethersproject/wordlists": true } }, - "depcheck>is-core-module>hasown": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": { "packages": { - "browserify>has>function-bind": true + "bn.js": true, + "browserify>buffer": true, + "eth-ens-namehash>js-sha3": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": true } }, - "dependency-tree>precinct>detective-postcss>postcss>nanoid": { + "webpack>events": { "globals": { - "crypto.getRandomValues": true + "console": true } }, - "eslint-plugin-react>array-includes>is-string": { + "crypto-browserify>browserify-cipher>evp_bytestokey": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash>md5.js": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-ens-namehash": { - "globals": { - "name": "write" - }, + "extension-port-stream": { "packages": { - "@metamask/ethjs>js-sha3": true, "browserify>buffer": true, - "eth-ens-namehash>idna-uts46-hx": true + "extension-port-stream>readable-stream": true } }, - "eth-ens-namehash>idna-uts46-hx": { + "fast-json-patch": { "globals": { - "define": true + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, + "@metamask/snaps-utils>fast-xml-parser": { + "globals": { + "entityName": true, + "val": true }, "packages": { - "browserify>punycode": true + "@metamask/snaps-utils>fast-xml-parser>strnum": true } }, - "eth-keyring-controller>@metamask/browser-passworder": { - "globals": { - "crypto": true + "@metamask/notification-services-controller>firebase": { + "packages": { + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/messaging": true } }, - "eth-lattice-keyring": { + "react-focus-lock>focus-lock": { "globals": { - "addEventListener": true, - "browser": true, - "clearInterval": true, - "fetch": true, - "open": true, - "setInterval": true + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify": true, - "eth-lattice-keyring>@ethereumjs/tx": true, - "eth-lattice-keyring>gridplus-sdk": true, - "eth-lattice-keyring>rlp": true, - "webpack>events": true + "tslib": true } }, - "eth-lattice-keyring>@ethereumjs/tx": { + "browserify>util>which-typed-array>for-each": { "packages": { - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>es-abstract>is-callable": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { - "packages": { - "browserify": true, - "browserify>buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true + "axios>form-data": { + "globals": { + "FormData": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { + "fuse.js": { "globals": { - "WeakRef": true - }, - "packages": { - "browserify": true + "console": true, + "define": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { + "string.prototype.matchall>get-intrinsic": { "globals": { - "TextDecoder": true, - "crypto": true + "AggregateError": true, + "FinalizationRegistry": true, + "WeakRef": true }, "packages": { - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true + "string.prototype.matchall>es-abstract>gopd": { + "packages": { + "string.prototype.matchall>get-intrinsic": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3872,230 +4038,307 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethersproject/abi": true, - "@metamask/ethjs>js-sha3": true, - "@metamask/keyring-api>bech32": true, - "bn.js": true, - "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": true, + "@ethersproject/abi": true, "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "@metamask/keyring-api>bech32": true, "eth-lattice-keyring>gridplus-sdk>bignumber.js": true, "eth-lattice-keyring>gridplus-sdk>bitwise": true, + "bn.js": true, "eth-lattice-keyring>gridplus-sdk>borc": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, "eth-lattice-keyring>gridplus-sdk>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, - "eth-lattice-keyring>gridplus-sdk>uuid": true, - "eth-lattice-keyring>rlp": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, "ethers>@ethersproject/sha2>hash.js": true, + "eth-ens-namehash>js-sha3": true, + "lodash": true, + "eth-lattice-keyring>rlp": true, "ganache>secp256k1": true, - "lodash": true + "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { + "string.prototype.matchall>es-abstract>has-property-descriptors": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "string.prototype.matchall>call-bind>es-define-property": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { + "koa>is-generator-function>has-tostringtag": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>has-symbols": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { + "ethereumjs-util>create-hash>md5.js>hash-base": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "pumpify>inherits": true, + "readable-stream": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { + "ethers>@ethersproject/sha2>hash.js": { + "packages": { + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true + } + }, + "depcheck>is-core-module>hasown": { + "packages": { + "browserify>has>function-bind": true + } + }, + "@metamask/eth-trezor-keyring>hdkey": { + "packages": { + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "crypto-browserify": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true + } + }, + "he": { "globals": { - "TextDecoder": true, - "crypto": true + "define": true + } + }, + "history": { + "globals": { + "console": true, + "define": true, + "document.defaultView": true, + "document.querySelector": true + } + }, + "react-router-dom>history": { + "globals": { + "addEventListener": true, + "confirm": true, + "document": true, + "history": true, + "location": true, + "navigator.userAgent": true, + "removeEventListener": true }, "packages": { - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "react-router-dom>history>resolve-pathname": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true, + "react-router-dom>history>value-equal": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "@metamask/ppom-validator>elliptic>hmac-drbg": { + "packages": { + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true + } + }, + "react-redux>hoist-non-react-statics": { + "packages": { + "prop-types>react-is": true + } + }, + "https-browserify": { + "packages": { + "stream-http": true, + "browserify>url": true + } + }, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": { "globals": { - "TextEncoder": true, - "crypto": true + "DOMException": true, + "IDBCursor": true, + "IDBDatabase": true, + "IDBIndex": true, + "IDBObjectStore": true, + "IDBRequest": true, + "IDBTransaction": true, + "indexedDB.deleteDatabase": true, + "indexedDB.open": true } }, - "eth-lattice-keyring>gridplus-sdk>aes-js": { + "eth-ens-namehash>idna-uts46-hx": { "globals": { "define": true + }, + "packages": { + "browserify>punycode": true + } + }, + "string.prototype.matchall>internal-slot": { + "packages": { + "string.prototype.matchall>call-bind>es-errors": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>side-channel": true + } + }, + "browserify>util>is-arguments": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true + } + }, + "string.prototype.matchall>es-abstract>is-array-buffer": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "packages": { + "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "string.prototype.matchall>es-abstract>is-callable": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>bitwise": { + "@metamask/eth-token-tracker>deep-equal>is-date-object": { "packages": { - "browserify>buffer": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc": { - "globals": { - "console": true - }, + "koa>is-generator-function": { "packages": { - "browserify>buffer": true, - "buffer>ieee754": true, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "@material-ui/core>@material-ui/styles>jss>is-in-browser": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { - "globals": { - "URL": true, - "URLSearchParams": true, - "location": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>elliptic": { + "string.prototype.matchall>es-abstract>is-regex": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { - "globals": { - "intToBuffer": true - }, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": { "packages": { - "@metamask/ethjs>js-sha3": true, - "bn.js": true, - "buffer": true + "string.prototype.matchall>call-bind": true } }, - "eth-lattice-keyring>gridplus-sdk>uuid": { - "globals": { - "crypto": true + "eslint-plugin-react>array-includes>is-string": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>rlp": { - "globals": { - "TextEncoder": true + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "packages": { + "string.prototype.matchall>has-symbols": true } }, - "eth-method-registry": { + "browserify>util>is-typed-array": { "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true + "browserify>util>which-typed-array": true } }, - "ethereumjs-util": { + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { "packages": { - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography": true, - "ethereumjs-util>rlp": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true } }, - "ethereumjs-util>create-hash": { + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { + "globals": { + "URL": true, + "URLSearchParams": true, + "location": true + } + }, + "@ensdomains/content-hash>js-base64": { + "globals": { + "Base64": "write", + "TextDecoder": true, + "TextEncoder": true, + "atob": true, + "btoa": true, + "define": true + }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>md5.js": true, - "ethereumjs-util>create-hash>ripemd160": true, - "pumpify>inherits": true + "browserify>buffer": true } }, - "ethereumjs-util>create-hash>cipher-base": { + "eth-ens-namehash>js-sha3": { + "globals": { + "define": true + }, "packages": { - "browserify>string_decoder": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "stream-browserify": true + "process": true } }, - "ethereumjs-util>create-hash>md5.js": { + "@ngraveio/bc-ur>jsbi": { + "globals": { + "define": true + } + }, + "@metamask/message-manager>jsonschema": { "packages": { - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "browserify>url": true } }, - "ethereumjs-util>create-hash>md5.js>hash-base": { + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "readable-stream": true + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true } }, - "ethereumjs-util>create-hash>ripemd160": { + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { + "globals": { + "CSS": true + }, "packages": { - "browserify>buffer": true, - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "pumpify>inherits": true + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography": { + "@material-ui/core>@material-ui/styles>jss-plugin-global": { "packages": { - "browserify>buffer": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ganache>secp256k1": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes": { + "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@babel/runtime": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { - "browserify>buffer": true + "@material-ui/core>@material-ui/styles>jss": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check": { + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { "packages": { - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, - "koa>content-disposition>safe-buffer": true + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { + "@material-ui/core>@material-ui/styles>jss": { + "globals": { + "CSS": true, + "document.createElement": true, + "document.querySelector": true + }, "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, + "react-router-dom>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4104,536 +4347,496 @@ "readable-stream": true } }, - "ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "currency-formatter>locale-currency": { + "globals": { + "countryCode": true } }, - "ethereumjs-wallet>randombytes": { + "localforage": { "globals": { - "crypto.getRandomValues": true + "Blob": true, + "BlobBuilder": true, + "FileReader": true, + "IDBKeyRange": true, + "MSBlobBuilder": true, + "MozBlobBuilder": true, + "OIndexedDB": true, + "WebKitBlobBuilder": true, + "atob": true, + "btoa": true, + "console.error": true, + "console.info": true, + "console.warn": true, + "define": true, + "fetch": true, + "indexedDB": true, + "localStorage": true, + "mozIndexedDB": true, + "msIndexedDB": true, + "navigator.platform": true, + "navigator.userAgent": true, + "openDatabase": true, + "setTimeout": true, + "webkitIndexedDB": true } }, - "ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/web": true, - "ethers>@ethersproject/wordlists": true + "lodash": { + "globals": { + "clearTimeout": true, + "define": true, + "setTimeout": true } }, - "ethers>@ethersproject/abstract-provider": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "loglevel": { + "globals": { + "console": true, + "define": true, + "document.cookie": true, + "localStorage": true, + "log": "write", + "navigator": true } }, - "ethers>@ethersproject/abstract-signer": { - "packages": { - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "lottie-web": { + "globals": { + "Blob": true, + "Howl": true, + "OffscreenCanvas": true, + "URL.createObjectURL": true, + "Worker": true, + "XMLHttpRequest": true, + "bodymovin": "write", + "clearInterval": true, + "console": true, + "define": true, + "document.body": true, + "document.createElement": true, + "document.createElementNS": true, + "document.getElementsByClassName": true, + "document.getElementsByTagName": true, + "document.querySelectorAll": true, + "document.readyState": true, + "location.origin": true, + "location.pathname": true, + "navigator": true, + "requestAnimationFrame": true, + "setInterval": true, + "setTimeout": true } }, - "ethers>@ethersproject/address": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/rlp": true + "luxon": { + "globals": { + "Intl": true } }, - "ethers>@ethersproject/base64": { + "@metamask/snaps-utils>marked": { "globals": { - "atob": true, - "btoa": true - }, - "packages": { - "@ethersproject/bytes": true + "console.error": true, + "console.warn": true, + "define": true } }, - "ethers>@ethersproject/basex": { + "ethereumjs-util>create-hash>md5.js": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/properties": true + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "ethers>@ethersproject/constants": { + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { "packages": { - "@ethersproject/bignumber": true + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/json-wallets": { + "react-markdown>remark-parse>mdast-util-from-markdown": { "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets>aes-js": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/pbkdf2": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "ethers>@ethersproject/json-wallets>aes-js": { - "globals": { - "define": true + "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true } }, - "ethers>@ethersproject/json-wallets>scrypt-js": { + "react-markdown>remark-rehype>mdast-util-to-hast": { "globals": { - "define": true, - "setTimeout": true + "console.warn": true }, "packages": { - "browserify>timers-browserify": true - } - }, - "ethers>@ethersproject/keccak256": { - "packages": { - "@ethersproject/bytes": true, - "@metamask/ethjs>js-sha3": true + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, + "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/logger": { + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { "globals": { - "console": true + "Headers": true, + "TextDecoder": true, + "URL": true, + "btoa": true, + "fetch": true + }, + "packages": { + "browserify>browserify-zlib": true, + "browserify>buffer": true, + "https-browserify": true, + "process": true, + "stream-http": true, + "browserify>url": true, + "browserify>util": true } }, - "ethers>@ethersproject/pbkdf2": { + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/sha2": true + "react-syntax-highlighter>refractor>parse-entities": true } }, - "ethers>@ethersproject/properties": { + "crypto-browserify>diffie-hellman>miller-rabin": { "packages": { - "ethers>@ethersproject/logger": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true } }, - "ethers>@ethersproject/providers": { + "@ensdomains/content-hash>cids>multibase": { "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers>@ethersproject/networks": true, - "ethers>@ethersproject/providers>@ethersproject/web": true, - "ethers>@ethersproject/providers>bech32": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true + "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true } }, - "ethers>@ethersproject/providers>@ethersproject/networks": { + "@ensdomains/content-hash>multihashes>multibase": { "packages": { - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true, + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, + "@ensdomains/content-hash>multicodec": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@ensdomains/content-hash>multicodec>uint8arrays": true, + "sass-embedded>varint": true } }, - "ethers>@ethersproject/random": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "console.warn": true, + "crypto.subtle.digest": true } }, - "ethers>@ethersproject/rlp": { + "@ensdomains/content-hash>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>multibase": true, + "@ensdomains/content-hash>multihashes>varint": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/sha2": { + "@ensdomains/content-hash>cids>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2>hash.js": true + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>cids>uint8arrays": true, + "@ensdomains/content-hash>cids>multihashes>varint": true } }, - "ethers>@ethersproject/sha2>hash.js": { - "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/signing-key>elliptic": true + "@metamask/approval-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/solidity": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true + "@metamask/notification-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/strings": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true + "@metamask/permission-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/transactions": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/signing-key": true + "@metamask/rpc-methods>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/units": { - "packages": { - "@ethersproject/bignumber": true, - "ethers>@ethersproject/logger": true + "@metamask/rpc-methods-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/web": { + "@metamask/snaps-controllers>nanoid": { "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/wordlists": { - "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@metamask/snaps-controllers-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream": { - "packages": { - "browserify>buffer": true, - "extension-port-stream>readable-stream": true + "depcheck>@vue/compiler-sfc>postcss>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream": { + "dependency-tree>precinct>detective-postcss>postcss>nanoid": { "globals": { - "AbortController": true, - "AggregateError": true, - "Blob": true - }, - "packages": { - "browserify>buffer": true, - "browserify>string_decoder": true, - "extension-port-stream>readable-stream>abort-controller": true, - "process": true, - "webpack>events": true + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream>abort-controller": { + "node-fetch": { "globals": { - "AbortController": true + "Headers": true, + "Request": true, + "Response": true, + "fetch": true } }, - "fast-json-patch": { + "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true + "fetch": true } }, - "fuse.js": { + "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { "globals": { - "console": true, - "define": true + "fetch": true } }, - "ganache>secp256k1": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": { "packages": { - "@metamask/ppom-validator>elliptic": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true + } + }, + "string.prototype.matchall>es-abstract>object-inspect": { + "globals": { + "HTMLElement": true, + "WeakRef": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "@ngraveio/bc-ur>assert>object-is": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true } }, "gulp>vinyl-fs>object.assign": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>has-symbols": true + "string.prototype.matchall>has-symbols": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "he": { - "globals": { - "define": true + "@metamask/object-multiplex>once": { + "packages": { + "@metamask/object-multiplex>once>wrappy": true } }, - "history": { + "crypto-browserify>public-encrypt>parse-asn1": { + "packages": { + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "browserify>buffer": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "crypto-browserify>pbkdf2": true + } + }, + "react-syntax-highlighter>refractor>parse-entities": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true + "document.createElement": true } }, - "https-browserify": { + "path-browserify": { "packages": { - "browserify>url": true, - "stream-http": true + "process": true } }, - "koa>content-disposition>safe-buffer": { + "serve-handler>path-to-regexp": { "packages": { - "browserify>buffer": true + "serve-handler>path-to-regexp>isarray": true } }, - "koa>is-generator-function": { + "crypto-browserify>pbkdf2": { + "globals": { + "crypto": true, + "process": true, + "queueMicrotask": true, + "setImmediate": true, + "setTimeout": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash": true, + "process": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true } }, - "koa>is-generator-function>has-tostringtag": { - "packages": { - "string.prototype.matchall>has-symbols": true + "@material-ui/core>popper.js": { + "globals": { + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, + "console.warn": true, + "define": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator": true, + "requestAnimationFrame": true, + "setTimeout": true } }, - "localforage": { + "react-tippy>popper.js": { "globals": { - "Blob": true, - "BlobBuilder": true, - "FileReader": true, - "IDBKeyRange": true, - "MSBlobBuilder": true, - "MozBlobBuilder": true, - "OIndexedDB": true, - "WebKitBlobBuilder": true, - "atob": true, - "btoa": true, - "console.error": true, - "console.info": true, + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, "console.warn": true, "define": true, - "fetch": true, - "indexedDB": true, - "localStorage": true, - "mozIndexedDB": true, - "msIndexedDB": true, - "navigator.platform": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, "navigator.userAgent": true, - "openDatabase": true, - "setTimeout": true, - "webkitIndexedDB": true + "requestAnimationFrame": true, + "setTimeout": true } }, - "lodash": { + "process": { "globals": { "clearTimeout": true, - "define": true, "setTimeout": true } }, - "loglevel": { + "promise-to-callback": { + "packages": { + "promise-to-callback>is-fn": true, + "promise-to-callback>set-immediate-shim": true + } + }, + "prop-types": { "globals": { - "console": true, - "define": true, - "document.cookie": true, - "localStorage": true, - "log": "write", - "navigator": true + "console": true + }, + "packages": { + "react>object-assign": true, + "prop-types>react-is": true } }, - "lottie-web": { + "react-markdown>property-information": { + "packages": { + "watchify>xtend": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { "globals": { - "Blob": true, - "Howl": true, - "OffscreenCanvas": true, - "URL.createObjectURL": true, - "Worker": true, - "XMLHttpRequest": true, - "bodymovin": "write", - "clearInterval": true, - "console": true, - "define": true, - "document.body": true, - "document.createElement": true, - "document.createElementNS": true, - "document.getElementsByClassName": true, - "document.getElementsByTagName": true, - "document.querySelectorAll": true, - "document.readyState": true, - "location.origin": true, - "location.pathname": true, - "navigator": true, - "requestAnimationFrame": true, - "setInterval": true, + "process": true, "setTimeout": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true } }, - "luxon": { + "crypto-browserify>public-encrypt": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "crypto-browserify>randombytes": true + } + }, + "browserify>punycode": { "globals": { - "Intl": true + "define": true } }, - "nanoid": { + "qrcode-generator": { "globals": { - "crypto.getRandomValues": true + "define": true } }, - "nock>debug": { + "qrcode.react": { "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "Path2D": true, + "devicePixelRatio": true }, "packages": { - "nock>debug>ms": true, - "process": true - } - }, - "node-fetch": { - "globals": { - "Headers": true, - "Request": true, - "Response": true, - "fetch": true + "react": true } }, - "path-browserify": { + "@storybook/addon-knobs>qs": { "packages": { - "process": true + "string.prototype.matchall>side-channel": true } }, - "process": { + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { "globals": { - "clearTimeout": true, - "setTimeout": true - } - }, - "promise-to-callback": { - "packages": { - "promise-to-callback>is-fn": true, - "promise-to-callback>set-immediate-shim": true + "queueMicrotask": true } }, - "promise-to-callback>set-immediate-shim": { + "react-beautiful-dnd>raf-schd": { "globals": { - "setTimeout.apply": true - }, - "packages": { - "browserify>timers-browserify": true + "cancelAnimationFrame": true, + "requestAnimationFrame": true } }, - "prop-types": { + "crypto-browserify>randombytes": { "globals": { - "console": true + "crypto": true, + "msCrypto": true }, "packages": { - "prop-types>react-is": true, - "react>object-assign": true - } - }, - "prop-types>react-is": { - "globals": { - "console": true + "process": true, + "koa>content-disposition>safe-buffer": true } }, - "qrcode-generator": { + "ethereumjs-wallet>randombytes": { "globals": { - "define": true + "crypto.getRandomValues": true } }, - "qrcode.react": { + "crypto-browserify>randomfill": { "globals": { - "Path2D": true, - "devicePixelRatio": true + "crypto": true, + "msCrypto": true }, "packages": { - "react": true + "process": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true } }, "react": { @@ -4641,8 +4844,8 @@ "console": true }, "packages": { - "prop-types": true, - "react>object-assign": true + "react>object-assign": true, + "prop-types": true } }, "react-beautiful-dnd": { @@ -4664,43 +4867,28 @@ }, "packages": { "@babel/runtime": true, - "react": true, "react-beautiful-dnd>css-box-model": true, "react-beautiful-dnd>memoize-one": true, "react-beautiful-dnd>raf-schd": true, - "react-beautiful-dnd>use-memo-one": true, + "react": true, "react-dom": true, "react-redux": true, - "redux": true + "redux": true, + "react-beautiful-dnd>use-memo-one": true } }, - "react-beautiful-dnd>css-box-model": { + "react-chartjs-2": { "globals": { - "getComputedStyle": true, - "pageXOffset": true, - "pageYOffset": true + "setTimeout": true }, "packages": { - "react-router-dom>tiny-invariant": true - } - }, - "react-beautiful-dnd>raf-schd": { - "globals": { - "cancelAnimationFrame": true, - "requestAnimationFrame": true - } - }, - "react-beautiful-dnd>use-memo-one": { - "packages": { + "chart.js": true, "react": true } }, - "react-chartjs-2": { - "globals": { - "setTimeout": true - }, + "react-focus-lock>react-clientside-effect": { "packages": { - "chart.js": true, + "@babel/runtime": true, "react": true } }, @@ -4745,22 +4933,28 @@ "trustedTypes": true }, "packages": { + "react>object-assign": true, "prop-types": true, "react": true, - "react-dom>scheduler": true, - "react>object-assign": true + "react-dom>scheduler": true } }, - "react-dom>scheduler": { + "react-responsive-carousel>react-easy-swipe": { "globals": { - "MessageChannel": true, - "cancelAnimationFrame": true, - "clearTimeout": true, - "console": true, - "navigator": true, - "performance": true, - "requestAnimationFrame": true, - "setTimeout": true + "addEventListener": true, + "define": true, + "document.addEventListener": true, + "document.removeEventListener": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-popper>react-fast-compare": { + "globals": { + "Element": true, + "console.warn": true } }, "react-focus-lock": { @@ -4774,667 +4968,726 @@ }, "packages": { "@babel/runtime": true, + "react-focus-lock>focus-lock": true, "prop-types": true, "react": true, - "react-focus-lock>focus-lock": true, "react-focus-lock>react-clientside-effect": true, "react-focus-lock>use-callback-ref": true, "react-focus-lock>use-sidecar": true } }, - "react-focus-lock>focus-lock": { + "react-idle-timer": { "globals": { - "HTMLIFrameElement": true, - "Node.DOCUMENT_FRAGMENT_NODE": true, - "Node.DOCUMENT_NODE": true, - "Node.DOCUMENT_POSITION_CONTAINED_BY": true, - "Node.DOCUMENT_POSITION_CONTAINS": true, - "Node.ELEMENT_NODE": true, - "console.error": true, + "clearTimeout": true, + "document": true, + "setTimeout": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-inspector": { + "globals": { + "Node": true, + "chromeDark": true, + "chromeLight": true + }, + "packages": { + "react": true + } + }, + "prop-types>react-is": { + "globals": { + "console": true + } + }, + "react-markdown>react-is": { + "globals": { + "console": true + } + }, + "react-redux>react-is": { + "globals": { + "console": true + } + }, + "react-markdown": { + "globals": { + "console.warn": true + }, + "packages": { + "react-markdown>comma-separated-tokens": true, + "prop-types": true, + "react-markdown>property-information": true, + "react": true, + "react-markdown>react-is": true, + "react-markdown>remark-parse": true, + "react-markdown>remark-rehype": true, + "react-markdown>space-separated-tokens": true, + "react-markdown>style-to-object": true, + "react-markdown>unified": true, + "react-markdown>unist-util-visit": true, + "react-markdown>vfile": true + } + }, + "react-popper": { + "globals": { + "document": true + }, + "packages": { + "@popperjs/core": true, + "react": true, + "react-popper>react-fast-compare": true, + "react-popper>warning": true + } + }, + "react-redux": { + "globals": { + "console": true, + "document": true + }, + "packages": { + "@babel/runtime": true, + "react-redux>hoist-non-react-statics": true, + "prop-types": true, + "react": true, + "react-dom": true, + "react-redux>react-is": true + } + }, + "react-responsive-carousel": { + "globals": { + "HTMLElement": true, + "addEventListener": true, + "clearTimeout": true, "console.warn": true, "document": true, - "getComputedStyle": true, + "getComputedStyle": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "classnames": true, + "react": true, + "react-dom": true, + "react-responsive-carousel>react-easy-swipe": true + } + }, + "react-router-dom": { + "packages": { + "react-router-dom>history": true, + "prop-types": true, + "react": true, + "react-router-dom>react-router": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true + } + }, + "react-router-dom-v5-compat": { + "globals": { + "FormData": true, + "URL": true, + "URLSearchParams": true, + "__reactRouterVersion": "write", + "addEventListener": true, + "confirm": true, + "define": true, + "document": true, + "history.scrollRestoration": true, + "location.href": true, + "removeEventListener": true, + "scrollTo": true, + "scrollY": true, + "sessionStorage.getItem": true, + "sessionStorage.setItem": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true + "react-router-dom-v5-compat>@remix-run/router": true, + "history": true, + "react": true, + "react-dom": true, + "react-router-dom": true, + "react-router-dom-v5-compat>react-router": true } }, - "react-focus-lock>react-clientside-effect": { + "react-router-dom>react-router": { "packages": { - "@babel/runtime": true, - "react": true + "react-router-dom>history": true, + "react-redux>hoist-non-react-statics": true, + "serve-handler>path-to-regexp": true, + "prop-types": true, + "react": true, + "prop-types>react-is": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true } }, - "react-focus-lock>use-callback-ref": { + "react-router-dom-v5-compat>react-router": { + "globals": { + "console.error": true, + "define": true + }, "packages": { + "react-router-dom-v5-compat>@remix-run/router": true, "react": true } }, - "react-focus-lock>use-sidecar": { + "react-simple-file-input": { "globals": { - "console.error": true + "File": true, + "FileReader": true, + "console.warn": true }, "packages": { - "@swc/helpers>tslib": true, - "react": true, - "react-focus-lock>use-sidecar>detect-node-es": true + "prop-types": true, + "react": true } }, - "react-idle-timer": { + "react-tippy": { "globals": { + "Element": true, + "MSStream": true, + "MutationObserver": true, + "addEventListener": true, "clearTimeout": true, + "console.error": true, + "console.warn": true, + "define": true, "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator.maxTouchPoints": true, + "navigator.msMaxTouchPoints": true, + "navigator.userAgent": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "react-tippy>popper.js": true, + "react": true, + "react-dom": true } }, - "react-inspector": { + "react-toggle-button": { "globals": { - "Node": true, - "chromeDark": true, - "chromeLight": true + "clearTimeout": true, + "console.warn": true, + "define": true, + "performance": true, + "setTimeout": true }, "packages": { "react": true } }, - "react-markdown": { + "@material-ui/core>react-transition-group": { "globals": { - "console.warn": true + "Element": true, + "setTimeout": true }, "packages": { + "@material-ui/core>react-transition-group>dom-helpers": true, "prop-types": true, "react": true, - "react-markdown>comma-separated-tokens": true, - "react-markdown>property-information": true, - "react-markdown>react-is": true, - "react-markdown>remark-parse": true, - "react-markdown>remark-rehype": true, - "react-markdown>space-separated-tokens": true, - "react-markdown>style-to-object": true, - "react-markdown>unified": true, - "react-markdown>unist-util-visit": true, - "react-markdown>vfile": true + "react-dom": true } }, - "react-markdown>property-information": { + "readable-stream": { "packages": { - "watchify>xtend": true + "browserify>browser-resolve": true, + "browserify>buffer": true, + "webpack>events": true, + "pumpify>inherits": true, + "process": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true } }, - "react-markdown>react-is": { + "extension-port-stream>readable-stream": { "globals": { - "console": true - } - }, - "react-markdown>remark-parse": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, - "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true, - "react-syntax-highlighter>refractor>parse-entities": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "queueMicrotask": true + }, "packages": { - "react-syntax-highlighter>refractor>parse-entities": true + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "browserify>buffer": true, + "webpack>events": true, + "process": true, + "browserify>string_decoder": true } }, - "react-markdown>remark-rehype": { + "@metamask/snaps-controllers>readable-web-to-node-stream": { "packages": { - "react-markdown>remark-rehype>mdast-util-to-hast": true + "readable-stream": true } }, - "react-markdown>remark-rehype>mdast-util-to-hast": { + "redux": { "globals": { - "console.warn": true + "console": true }, "packages": { - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, - "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, - "react-markdown>unist-util-visit": true + "@babel/runtime": true } }, - "react-markdown>style-to-object": { + "string.prototype.matchall>regexp.prototype.flags": { "packages": { - "react-markdown>style-to-object>inline-style-parser": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": true } }, - "react-markdown>unified": { + "react-markdown>remark-parse": { "packages": { - "mocha>yargs-unparser>is-plain-obj": true, - "react-markdown>unified>bail": true, - "react-markdown>unified>extend": true, - "react-markdown>unified>is-buffer": true, - "react-markdown>unified>trough": true, - "react-markdown>vfile": true + "react-markdown>remark-parse>mdast-util-from-markdown": true } }, - "react-markdown>unist-util-visit": { + "react-markdown>remark-rehype": { "packages": { - "react-markdown>unist-util-visit>unist-util-visit-parents": true + "react-markdown>remark-rehype>mdast-util-to-hast": true } }, - "react-markdown>unist-util-visit>unist-util-visit-parents": { + "react-markdown>vfile>replace-ext": { "packages": { - "react-markdown>unist-util-visit>unist-util-is": true + "path-browserify": true } }, - "react-markdown>vfile": { - "packages": { - "path-browserify": true, - "process": true, - "react-markdown>vfile>is-buffer": true, - "react-markdown>vfile>replace-ext": true, - "react-markdown>vfile>vfile-message": true + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true } }, - "react-markdown>vfile>replace-ext": { + "@metamask/snaps-utils>rfdc": { "packages": { - "path-browserify": true + "browserify>buffer": true } }, - "react-markdown>vfile>vfile-message": { + "ethereumjs-util>create-hash>ripemd160": { "packages": { - "react-markdown>vfile>unist-util-stringify-position": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true } }, - "react-popper": { - "globals": { - "document": true - }, + "@keystonehq/metamask-airgapped-keyring>rlp": { "packages": { - "@popperjs/core": true, - "react": true, - "react-popper>react-fast-compare": true, - "react-popper>warning": true - } - }, - "react-popper>react-fast-compare": { - "globals": { - "Element": true, - "console.warn": true + "bn.js": true, + "browserify>buffer": true } }, - "react-popper>warning": { + "eth-lattice-keyring>rlp": { "globals": { - "console": true + "TextEncoder": true } }, - "react-redux": { - "globals": { - "console": true, - "document": true - }, + "ethereumjs-util>rlp": { "packages": { - "@babel/runtime": true, - "prop-types": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true, - "react-redux>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>hoist-non-react-statics": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { "packages": { - "prop-types>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>react-is": { + "wait-on>rxjs": { "globals": { - "console": true + "cancelAnimationFrame": true, + "clearInterval": true, + "clearTimeout": true, + "performance": true, + "requestAnimationFrame": true, + "setInterval.apply": true, + "setTimeout.apply": true } }, - "react-responsive-carousel": { + "koa>content-disposition>safe-buffer": { + "packages": { + "browserify>buffer": true + } + }, + "react-dom>scheduler": { "globals": { - "HTMLElement": true, - "addEventListener": true, + "MessageChannel": true, + "cancelAnimationFrame": true, "clearTimeout": true, - "console.warn": true, - "document": true, - "getComputedStyle": true, - "removeEventListener": true, + "console": true, + "navigator": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true - }, - "packages": { - "classnames": true, - "react": true, - "react-dom": true, - "react-responsive-carousel>react-easy-swipe": true } }, - "react-responsive-carousel>react-easy-swipe": { + "ethers>@ethersproject/json-wallets>scrypt-js": { "globals": { - "addEventListener": true, "define": true, - "document.addEventListener": true, - "document.removeEventListener": true + "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "browserify>timers-browserify": true } }, - "react-router-dom": { + "ganache>secp256k1": { "packages": { - "prop-types": true, - "react": true, - "react-router-dom>history": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "@metamask/ppom-validator>elliptic": true } }, - "react-router-dom-v5-compat": { + "semver": { "globals": { - "FormData": true, - "URL": true, - "URLSearchParams": true, - "__reactRouterVersion": "write", - "addEventListener": true, - "confirm": true, - "define": true, - "document": true, - "history.scrollRestoration": true, - "location.href": true, - "removeEventListener": true, - "scrollTo": true, - "scrollY": true, - "sessionStorage.getItem": true, - "sessionStorage.setItem": true, - "setTimeout": true + "console.error": true }, "packages": { - "history": true, - "react": true, - "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>@remix-run/router": true, - "react-router-dom-v5-compat>react-router": true + "process": true } }, - "react-router-dom-v5-compat>@remix-run/router": { - "globals": { - "AbortController": true, - "DOMException": true, - "FormData": true, - "Headers": true, - "Request": true, - "Response": true, - "URL": true, - "URLSearchParams": true, - "console": true, - "document.defaultView": true + "string.prototype.matchall>call-bind>set-function-length": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom-v5-compat>react-router": { - "globals": { - "console.error": true, - "define": true - }, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": { "packages": { - "react": true, - "react-router-dom-v5-compat>@remix-run/router": true + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom>history": { + "promise-to-callback>set-immediate-shim": { "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true + "setTimeout.apply": true }, "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>history>value-equal": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "browserify>timers-browserify": true } }, - "react-router-dom>react-router": { + "addons-linter>sha.js": { "packages": { - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-redux>hoist-non-react-statics": true, - "react-router-dom>history": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "serve-handler>path-to-regexp": true + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "react-router-dom>tiny-warning": { - "globals": { - "console": true + "string.prototype.matchall>side-channel": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>object-inspect": true } }, - "react-simple-file-input": { + "@metamask/profile-sync-controller>siwe": { "globals": { - "File": true, - "FileReader": true, + "console.error": true, "console.warn": true }, "packages": { - "prop-types": true, - "react": true + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random": true, + "ethers": true, + "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true } }, - "react-syntax-highlighter>refractor>parse-entities": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { "globals": { - "document.createElement": true + "StopIteration": true + }, + "packages": { + "string.prototype.matchall>internal-slot": true } }, - "react-tippy": { + "stream-browserify": { + "packages": { + "webpack>events": true, + "pumpify>inherits": true, + "readable-stream": true + } + }, + "stream-http": { "globals": { - "Element": true, - "MSStream": true, - "MutationObserver": true, - "addEventListener": true, + "AbortController": true, + "Blob": true, + "MSStreamReader": true, + "ReadableStream": true, + "WritableStream": true, + "XDomainRequest": true, + "XMLHttpRequest": true, "clearTimeout": true, - "console.error": true, - "console.warn": true, - "define": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.maxTouchPoints": true, - "navigator.msMaxTouchPoints": true, - "navigator.userAgent": true, - "performance": true, - "requestAnimationFrame": true, + "fetch": true, + "location.protocol.search": true, "setTimeout": true }, "packages": { - "react": true, - "react-dom": true, - "react-tippy>popper.js": true + "browserify>buffer": true, + "stream-http>builtin-status-codes": true, + "pumpify>inherits": true, + "process": true, + "readable-stream": true, + "browserify>url": true, + "watchify>xtend": true } }, - "react-tippy>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.userAgent": true, - "requestAnimationFrame": true, - "setTimeout": true + "@metamask/snaps-controllers>tar-stream>streamx": { + "packages": { + "webpack>events": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true } }, - "react-toggle-button": { - "globals": { - "clearTimeout": true, - "console.warn": true, - "define": true, - "performance": true, - "setTimeout": true - }, + "browserify>string_decoder": { "packages": { - "react": true + "koa>content-disposition>safe-buffer": true } }, - "readable-stream": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": { "packages": { - "browserify>browser-resolve": true, - "browserify>buffer": true, - "browserify>string_decoder": true, - "process": true, - "pumpify>inherits": true, - "readable-stream>util-deprecate": true, - "webpack>events": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true } }, - "readable-stream>util-deprecate": { - "globals": { - "console.trace": true, - "console.warn": true, - "localStorage": true + "react-markdown>style-to-object": { + "packages": { + "react-markdown>style-to-object>inline-style-parser": true } }, - "redux": { - "globals": { - "console": true - }, + "@metamask/snaps-controllers>tar-stream": { "packages": { - "@babel/runtime": true + "@metamask/snaps-controllers>tar-stream>b4a": true, + "browserify>browser-resolve": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx": true } }, - "reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true + "debounce-stream>through": { + "packages": { + "process": true, + "stream-browserify": true } }, - "semver": { + "browserify>timers-browserify": { "globals": { - "console.error": true + "clearInterval": true, + "clearTimeout": true, + "setInterval": true, + "setTimeout": true }, "packages": { "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true + "react-router-dom>tiny-warning": { + "globals": { + "console": true } }, - "stream-browserify": { - "packages": { - "pumpify>inherits": true, - "readable-stream": true, - "webpack>events": true + "copy-to-clipboard>toggle-selection": { + "globals": { + "document.activeElement": true, + "document.getSelection": true + } + }, + "tslib": { + "globals": { + "SuppressedError": true, + "define": true } }, - "stream-http": { + "@metamask/eth-sig-util>tweetnacl": { "globals": { - "AbortController": true, - "Blob": true, - "MSStreamReader": true, - "ReadableStream": true, - "WritableStream": true, - "XDomainRequest": true, - "XMLHttpRequest": true, - "clearTimeout": true, - "fetch": true, - "location.protocol.search": true, - "setTimeout": true + "crypto": true, + "msCrypto": true, + "nacl": "write" }, "packages": { - "browserify>buffer": true, - "browserify>url": true, - "process": true, - "pumpify>inherits": true, - "readable-stream": true, - "stream-http>builtin-status-codes": true, - "watchify>xtend": true + "browserify>browser-resolve": true } }, - "string.prototype.matchall>call-bind": { - "packages": { - "browserify>has>function-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>call-bind>set-function-length": true, - "string.prototype.matchall>get-intrinsic": true + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>call-bind>es-define-property": { + "@ensdomains/content-hash>cids>uint8arrays": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>cids>multibase": true } }, - "string.prototype.matchall>call-bind>set-function-length": { + "@ensdomains/content-hash>multicodec>uint8arrays": { + "globals": { + "Buffer": true, + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "string.prototype.matchall>define-properties": { + "react-markdown>unified": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "react-markdown>unified>bail": true, + "react-markdown>unified>extend": true, + "react-markdown>unified>is-buffer": true, + "mocha>yargs-unparser>is-plain-obj": true, + "react-markdown>unified>trough": true, + "react-markdown>vfile": true } }, - "string.prototype.matchall>define-properties>define-data-property": { + "react-markdown>unist-util-visit>unist-util-visit-parents": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "react-markdown>unist-util-visit>unist-util-is": true } }, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "react-markdown>unist-util-visit": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true + "react-markdown>unist-util-visit>unist-util-visit-parents": true } }, - "string.prototype.matchall>es-abstract>available-typed-arrays": { - "packages": { - "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true + "uri-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "browserify>url": { "packages": { - "string.prototype.matchall>has-symbols": true + "browserify>punycode": true, + "@storybook/addon-knobs>qs": true } }, - "string.prototype.matchall>es-abstract>gopd": { + "react-focus-lock>use-callback-ref": { "packages": { - "string.prototype.matchall>get-intrinsic": true + "react": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "react-beautiful-dnd>use-memo-one": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true + "react": true } }, - "string.prototype.matchall>es-abstract>is-array-buffer": { + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "react-focus-lock>use-sidecar>detect-node-es": true, + "react": true, + "tslib": true } }, - "string.prototype.matchall>es-abstract>is-callable": { + "readable-stream>util-deprecate": { "globals": { - "document": true + "console.trace": true, + "console.warn": true, + "localStorage": true } }, - "string.prototype.matchall>es-abstract>is-regex": { + "browserify>assert>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true, + "process": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "browserify>assert>util>inherits": true, + "process": true } }, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": { + "browserify>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true + }, "packages": { - "string.prototype.matchall>call-bind": true + "pumpify>inherits": true, + "browserify>util>is-arguments": true, + "koa>is-generator-function": true, + "browserify>util>is-typed-array": true, + "process": true, + "browserify>util>which-typed-array": true } }, - "string.prototype.matchall>es-abstract>object-inspect": { + "uuid": { "globals": { - "HTMLElement": true, - "WeakRef": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "msCrypto": true } }, - "string.prototype.matchall>get-intrinsic": { + "@metamask/eth-snap-keyring>uuid": { "globals": { - "AggregateError": true, - "FinalizationRegistry": true, - "WeakRef": true - }, - "packages": { - "browserify>has>function-bind": true, - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true + "crypto": true } }, - "string.prototype.matchall>internal-slot": { - "packages": { - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>side-channel": true + "@metamask/keyring-snap-client>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eth-lattice-keyring>gridplus-sdk>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "web3-stream-provider>uuid": { + "globals": { + "crypto": true + } + }, + "@metamask/snaps-utils>validate-npm-package-name": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "@metamask/snaps-utils>validate-npm-package-name>builtins": true } }, - "string.prototype.matchall>side-channel": { + "react-markdown>vfile>vfile-message": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>get-intrinsic": true + "react-markdown>vfile>unist-util-stringify-position": true } }, - "terser>source-map-support>buffer-from": { + "react-markdown>vfile": { "packages": { - "browserify>buffer": true + "react-markdown>vfile>is-buffer": true, + "path-browserify": true, + "process": true, + "react-markdown>vfile>replace-ext": true, + "react-markdown>vfile>vfile-message": true } }, - "uri-js": { + "browserify>vm-browserify": { "globals": { - "define": true + "document.body.appendChild": true, + "document.body.removeChild": true, + "document.createElement": true } }, - "uuid": { + "react-popper>warning": { "globals": { - "crypto": true, - "msCrypto": true + "console": true } }, - "wait-on>rxjs": { + "@ensdomains/content-hash>multihashes>web-encoding": { "globals": { - "cancelAnimationFrame": true, - "clearInterval": true, - "clearTimeout": true, - "performance": true, - "requestAnimationFrame": true, - "setInterval.apply": true, - "setTimeout.apply": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>util": true } }, "web3": { @@ -5447,14 +5700,14 @@ "setTimeout": true }, "packages": { - "browserify>util": true, "readable-stream": true, + "browserify>util": true, "web3-stream-provider>uuid": true } }, - "web3-stream-provider>uuid": { + "@metamask/controllers>web3": { "globals": { - "crypto": true + "XMLHttpRequest": true } }, "webextension-polyfill": { @@ -5466,9 +5719,30 @@ "define": true } }, - "webpack>events": { - "globals": { - "console": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, + "eslint-plugin-react>array-includes>is-string": true, + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-collection": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + } + }, + "browserify>util>which-typed-array": { + "packages": { + "string.prototype.matchall>es-abstract>available-typed-arrays": true, + "string.prototype.matchall>call-bind": true, + "browserify>util>which-typed-array>for-each": true, + "string.prototype.matchall>es-abstract>gopd": true, + "koa>is-generator-function>has-tostringtag": true } } } diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index ddd92183c786..7a6974a03193 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -5,144 +5,124 @@ "regeneratorRuntime": "write" } }, - "@ensdomains/content-hash": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { "globals": { - "console.warn": true + "WeakRef": true }, "packages": { - "@ensdomains/content-hash>cids": true, - "@ensdomains/content-hash>js-base64": true, - "@ensdomains/content-hash>multicodec": true, - "@ensdomains/content-hash>multihashes": true, - "browserify>buffer": true + "browserify": true } }, - "@ensdomains/content-hash>cids": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes": true, - "@ensdomains/content-hash>cids>uint8arrays": true, - "@ensdomains/content-hash>multicodec": true + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, + "browserify": true, + "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true } }, - "@ensdomains/content-hash>cids>multibase": { + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "SuppressedError": true + } + }, + "@ensdomains/content-hash": { + "globals": { + "console.warn": true }, "packages": { - "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true + "browserify>buffer": true, + "@ensdomains/content-hash>cids": true, + "@ensdomains/content-hash>js-base64": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>multihashes": true } }, - "@ensdomains/content-hash>cids>multihashes": { + "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes>varint": true, - "@ensdomains/content-hash>cids>uint8arrays": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>cids>uint8arrays": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "webpack>events": true } }, - "@ensdomains/content-hash>js-base64": { - "globals": { - "Base64": "write", - "TextDecoder": true, - "TextEncoder": true, - "atob": true, - "btoa": true, - "define": true - }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "browserify>buffer": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays": true, - "sass-embedded>varint": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays": { + "@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "Buffer": true, - "TextDecoder": true, "TextEncoder": true - }, - "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "console.warn": true, - "crypto.subtle.digest": true - } - }, - "@ensdomains/content-hash>multihashes": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase": true, - "@ensdomains/content-hash>multihashes>varint": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase>base-x": { + "@ethereumjs/tx": { "packages": { - "koa>content-disposition>safe-buffer": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, - "@ensdomains/content-hash>multihashes>web-encoding": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx": { "packages": { - "browserify>util": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@ethereumjs/tx": { + "eth-lattice-keyring>@ethereumjs/tx": { "packages": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, + "@ethersproject/providers": true, "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@ethereumjs/tx>@ethereumjs/common": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/providers": true, "browserify>buffer": true, - "webpack>events": true - } - }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { - "globals": { - "DO_NOT_EXPORT_CRC": true, - "define": true - } - }, - "@ethereumjs/tx>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "@ethereumjs/tx>@ethereumjs/util": { @@ -151,78 +131,83 @@ }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true, - "@ethereumjs/tx>ethereum-cryptography": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "webpack>events": true + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "@metamask/smart-transactions-controller>@ethereumjs/util": { "globals": { - "Headers": true, - "TextDecoder": true, - "URL": true, - "btoa": true, + "console.warn": true, "fetch": true }, "packages": { - "browserify>browserify-zlib": true, - "browserify>buffer": true, - "browserify>url": true, - "browserify>util": true, - "https-browserify": true, - "process": true, - "stream-http": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, - "@ethereumjs/tx>ethereum-cryptography": { + "@ethersproject/abi": { "globals": { - "TextDecoder": true, - "crypto": true + "console.log": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true, - "@noble/hashes": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { - "globals": { - "TextEncoder": true - }, + "ethers>@ethersproject/abstract-provider": { "packages": { - "@noble/hashes": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "ethers>@ethersproject/abstract-signer": { "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethersproject/abi": { - "globals": { - "console.log": true - }, + "ethers>@ethersproject/address": { "packages": { "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/rlp": true + } + }, + "ethers>@ethersproject/base64": { + "globals": { + "atob": true, + "btoa": true + }, + "packages": { + "@ethersproject/bytes": true + } + }, + "ethers>@ethersproject/basex": { + "packages": { + "@ethersproject/bytes": true, + "ethers>@ethersproject/properties": true } }, "@ethersproject/bignumber": { "packages": { "@ethersproject/bytes": true, - "bn.js": true, - "ethers>@ethersproject/logger": true + "ethers>@ethersproject/logger": true, + "bn.js": true } }, "@ethersproject/bytes": { @@ -230,17 +215,22 @@ "ethers>@ethersproject/logger": true } }, + "ethers>@ethersproject/constants": { + "packages": { + "@ethersproject/bignumber": true + } + }, "@ethersproject/contracts": { "globals": { "setTimeout": true }, "packages": { "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/abstract-provider": true, "ethers>@ethersproject/abstract-signer": true, "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/transactions": true @@ -248,10 +238,10 @@ }, "@ethersproject/hash": { "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/address": true, "ethers>@ethersproject/base64": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, @@ -260,9 +250,9 @@ }, "@ethersproject/hdnode": { "packages": { + "ethers>@ethersproject/basex": true, "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "ethers>@ethersproject/basex": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, @@ -273,1692 +263,1236 @@ "ethers>@ethersproject/wordlists": true } }, - "@ethersproject/providers": { - "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/json-wallets": { "packages": { - "@ethersproject/bignumber": true, + "ethers>@ethersproject/address": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/providers>bech32": true, - "@metamask/test-bundler>@ethersproject/networks": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "@ethersproject/providers>@ethersproject/random": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/json-wallets>aes-js": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true } }, - "@ethersproject/wallet": { + "ethers>@ethersproject/keccak256": { "packages": { "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/transactions": true + "eth-ens-namehash>js-sha3": true } }, - "@keystonehq/bc-ur-registry-eth": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "uuid": true + "ethers>@ethersproject/logger": { + "globals": { + "console": true } }, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { - "globals": { - "define": true - }, + "ethers>@ethersproject/providers>@ethersproject/networks": { "packages": { - "@ngraveio/bc-ur": true, - "@swc/helpers>tslib": true, - "browserify>buffer": true, - "buffer": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring": { + "@metamask/test-bundler>@ethersproject/networks": { "packages": { - "@ethereumjs/tx": true, - "@keystonehq/bc-ur-registry-eth": true, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, - "@keystonehq/metamask-airgapped-keyring>rlp": true, - "@metamask/obs-store": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { + "ethers>@ethersproject/pbkdf2": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "eth-lattice-keyring>rlp": true, - "uuid": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/sha2": true } }, - "@keystonehq/metamask-airgapped-keyring>rlp": { + "ethers>@ethersproject/properties": { "packages": { - "bn.js": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@lavamoat/lavadome-react": { + "@ethersproject/providers": { "globals": { - "Document.prototype": true, - "DocumentFragment.prototype": true, - "Element.prototype": true, - "Node.prototype": true, + "WebSocket": true, + "clearInterval": true, + "clearTimeout": true, + "console.log": true, "console.warn": true, - "document": true + "setInterval": true, + "setTimeout": true }, "packages": { - "react": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "@metamask/test-bundler>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "@ethersproject/providers>@ethersproject/web": true, + "@ethersproject/providers>bech32": true } }, - "@material-ui/core": { + "ethers>@ethersproject/providers": { "globals": { - "Image": true, - "_formatMuiErrorMessage": true, - "addEventListener": true, + "WebSocket": true, "clearInterval": true, "clearTimeout": true, - "console.error": true, + "console.log": true, "console.warn": true, - "document": true, - "getComputedStyle": true, - "getSelection": true, - "innerHeight": true, - "innerWidth": true, - "matchMedia": true, - "navigator": true, - "performance.now": true, - "removeEventListener": true, - "requestAnimationFrame": true, "setInterval": true, "setTimeout": true }, "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles": true, - "@material-ui/core>@material-ui/system": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "@material-ui/core>popper.js": true, - "@material-ui/core>react-transition-group": true, - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/providers>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/providers>@ethersproject/web": true, + "ethers>@ethersproject/providers>bech32": true } }, - "@material-ui/core>@material-ui/styles": { + "@ethersproject/providers>@ethersproject/random": { "globals": { - "console.error": true, - "console.warn": true, - "document.createComment": true, - "document.head": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, - "@material-ui/core>@material-ui/styles>jss-plugin-global": true, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, - "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "prop-types": true, - "react": true, - "react-redux>hoist-non-react-statics": true + "crypto.getRandomValues": true } }, - "@material-ui/core>@material-ui/styles>jss": { - "globals": { - "CSS": true, - "document.createElement": true, - "document.querySelector": true - }, + "ethers>@ethersproject/random": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { + "ethers>@ethersproject/rlp": { "packages": { - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { - "globals": { - "CSS": true - }, + "ethers>@ethersproject/sha2": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2>hash.js": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-global": { + "ethers>@ethersproject/signing-key": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/signing-key>elliptic": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": { + "ethers>@ethersproject/solidity": { "packages": { - "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { + "ethers>@ethersproject/strings": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { + "ethers>@ethersproject/transactions": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/signing-key": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { - "globals": { - "document.createElement": true, - "document.documentElement": true, - "getComputedStyle": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true - } - }, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": { - "globals": { - "document": true - } - }, - "@material-ui/core>@material-ui/system": { - "globals": { - "console.error": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/utils": true, - "prop-types": true - } - }, - "@material-ui/core>@material-ui/utils": { - "packages": { - "@babel/runtime": true, - "prop-types": true, - "prop-types>react-is": true - } - }, - "@material-ui/core>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator": true, - "requestAnimationFrame": true, - "setTimeout": true - } - }, - "@material-ui/core>react-transition-group": { - "globals": { - "Element": true, - "setTimeout": true - }, - "packages": { - "@material-ui/core>react-transition-group>dom-helpers": true, - "prop-types": true, - "react": true, - "react-dom": true - } - }, - "@material-ui/core>react-transition-group>dom-helpers": { - "packages": { - "@babel/runtime": true - } - }, - "@metamask/abi-utils": { - "packages": { - "@metamask/abi-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true - } - }, - "@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/accounts-controller": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/base-controller": true, - "@metamask/eth-snap-keyring": true, - "@metamask/keyring-api": true, - "@metamask/keyring-controller": true, - "@metamask/utils": true, - "uuid": true - } - }, - "@metamask/address-book-controller": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true - } - }, - "@metamask/announcement-controller": { - "packages": { - "@metamask/announcement-controller>@metamask/base-controller": true - } - }, - "@metamask/announcement-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/approval-controller": { - "globals": { - "console.info": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/rpc-errors": true, - "nanoid": true - } - }, - "@metamask/approval-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/assets-controllers": { - "globals": { - "AbortController": true, - "Headers": true, - "URL": true, - "URLSearchParams": true, - "clearInterval": true, - "clearTimeout": true, - "console.error": true, - "console.log": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/units": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/bignumber": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/abi-utils": true, - "@metamask/base-controller": true, - "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "bn.js": true, - "cockatiel": true, - "ethers>@ethersproject/address": true, - "lodash": true, - "single-call-balance-checker-abi": true, - "uuid": true - } - }, - "@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/browser-passworder": { - "globals": { - "CryptoKey": true, - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "@metamask/browser-passworder>@metamask/utils": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@metamask/browser-passworder>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@ethersproject/wallet": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/transactions": true } }, - "@metamask/controller-utils": { + "@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, "fetch": true, "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/controller-utils>@spruceid/siwe-parser": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/utils": true, - "bn.js": true, - "browserify>buffer": true, - "eslint>fast-deep-equal": true, - "eth-ens-namehash": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser": { - "globals": { - "console.error": true, - "console.log": true - }, - "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/controllers>web3": { - "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/ens-controller": { - "packages": { - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "punycode": true - } - }, - "@metamask/eth-json-rpc-filters": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/safe-event-emitter": true, - "pify": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-json-rpc-middleware": { + "ethers>@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, - "@metamask/eth-json-rpc-middleware>klona": true, - "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-sig-util": true, - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true - } - }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-json-rpc-provider": { - "packages": { - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true, - "uuid": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring": { + "ethers>@ethersproject/web": { "globals": { - "addEventListener": true, - "console.error": true, - "document.createElement": true, - "document.head.appendChild": true, + "clearTimeout": true, "fetch": true, - "removeEventListener": true + "setTimeout": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, - "@metamask/eth-sig-util": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "webpack>events": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "ethers>@ethersproject/wordlists": { + "packages": { + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { + "@metamask/notification-services-controller>firebase>@firebase/app": { "globals": { + "FinalizationRegistry": true, "console.warn": true }, "packages": { - "@ethersproject/abi": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, - "browserify>buffer": true, - "ethers>@ethersproject/rlp": true, - "semver": true + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true + "@metamask/notification-services-controller>firebase>@firebase/util": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { + "@metamask/notification-services-controller>firebase>@firebase/installations": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "BroadcastChannel": true, + "Headers": true, "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, + "console.error": true, + "crypto": true, + "fetch": true, + "msCrypto": true, + "navigator.onLine": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { - "globals": { - "console.warn": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { - "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": true, - "@metamask/ppom-validator>crypto-js": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { "globals": { - "console.warn": true + "console": true }, "packages": { - "wait-on>rxjs": true + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { + "@metamask/notification-services-controller>firebase>@firebase/messaging": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "Headers": true, + "Notification.maxActions": true, + "Notification.permission": true, + "Notification.requestPermission": true, + "PushSubscription.prototype.hasOwnProperty": true, + "ServiceWorkerRegistration": true, + "URL": true, + "addEventListener": true, + "atob": true, "btoa": true, + "clients.matchAll": true, + "clients.openWindow": true, "console.warn": true, "document": true, + "fetch": true, + "indexedDB": true, "location.href": true, + "location.origin": true, "navigator": true, + "origin.replace": true, + "registration.showNotification": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/providers": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/wordlists": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { - "globals": { - "__ledgerLogsListen": "write", - "console.error": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/installations": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { + "@metamask/notification-services-controller>firebase>@firebase/util": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "atob": true, + "browser": true, "btoa": true, - "console.warn": true, + "chrome": true, + "console": true, "document": true, - "location.href": true, + "indexedDB": true, "navigator": true, + "process": true, + "self": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, "process": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { - "globals": { - "crypto": true, - "define": true - } - }, - "@metamask/eth-query": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "watchify>xtend": true + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/bc-ur-registry-eth": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "eth-lattice-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-sig-util": { + "@keystonehq/bc-ur-registry-eth": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>@metamask/utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "uuid": true } }, - "@metamask/eth-sig-util>@metamask/utils": { + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "define": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ngraveio/bc-ur": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "buffer": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "tslib": true } }, - "@metamask/eth-sig-util>tweetnacl": { - "globals": { - "crypto": true, - "msCrypto": true, - "nacl": "write" - }, + "@keystonehq/metamask-airgapped-keyring": { "packages": { - "browserify>browser-resolve": true + "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, + "@keystonehq/bc-ur-registry-eth": true, + "@metamask/obs-store": true, + "browserify>buffer": true, + "webpack>events": true, + "@keystonehq/metamask-airgapped-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-snap-keyring": { + "chart.js>@kurkle/color": { "globals": { - "URL": true, - "console.error": true + "define": true + } + }, + "@lavamoat/lavadome-react": { + "globals": { + "Document.prototype": true, + "DocumentFragment.prototype": true, + "Element.prototype": true, + "Node.prototype": true, + "console.warn": true, + "document": true }, "packages": { - "@ethereumjs/tx": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/eth-snap-keyring>uuid": true, - "@metamask/keyring-api": true, - "@metamask/utils>@metamask/superstruct": true, - "webpack>events": true + "react": true } }, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { + "globals": { + "console.warn": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { + "packages": { + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, + "@metamask/ppom-validator>crypto-js": true } }, - "@metamask/eth-snap-keyring>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.warn": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ethersproject/abi": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/transactions": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, "browserify>buffer": true, - "nock>debug": true, "semver": true } }, - "@metamask/eth-snap-keyring>uuid": { - "globals": { - "crypto": true - } - }, - "@metamask/eth-token-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { "globals": { "console.warn": true }, "packages": { - "@babel/runtime": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, - "@metamask/eth-token-tracker>deep-equal": true, - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/safe-event-emitter": true, - "bn.js": true, - "human-standard-token-abi": true + "wait-on>rxjs": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { + "globals": { + "__ledgerLogsListen": "write", + "console.error": true + } + }, + "@material-ui/core": { "globals": { + "Image": true, + "_formatMuiErrorMessage": true, + "addEventListener": true, + "clearInterval": true, "clearTimeout": true, "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "getSelection": true, + "innerHeight": true, + "innerWidth": true, + "matchMedia": true, + "navigator": true, + "performance.now": true, + "removeEventListener": true, + "requestAnimationFrame": true, + "setInterval": true, "setTimeout": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true, - "pify": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles": true, + "@material-ui/core>@material-ui/system": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>popper.js": true, + "prop-types": true, + "react": true, + "react-dom": true, + "prop-types>react-is": true, + "@material-ui/core>react-transition-group": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { + "@material-ui/core>@material-ui/styles": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.error": true, + "console.warn": true, + "document.createComment": true, + "document.head": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-token-tracker>deep-equal": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, - "@metamask/eth-token-tracker>deep-equal>is-date-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, - "@metamask/eth-token-tracker>deep-equal>which-collection": true, - "@ngraveio/bc-ur>assert>object-is": true, - "browserify>util>is-arguments": true, - "browserify>util>which-typed-array": true, - "gulp>vinyl-fs>object.assign": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>regexp.prototype.flags": true, - "string.prototype.matchall>side-channel": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, + "@material-ui/core>@material-ui/styles>jss-plugin-global": true, + "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, + "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, + "@material-ui/core>@material-ui/styles>jss": true, + "prop-types": true, + "react": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { + "@material-ui/core>@material-ui/system": { + "globals": { + "console.error": true + }, "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true, - "browserify>util>is-arguments": true, - "eslint-plugin-react>array-includes>is-string": true, - "process": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>has-symbols": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "prop-types": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { - "globals": { - "StopIteration": true - }, + "@material-ui/core>@material-ui/utils": { "packages": { - "string.prototype.matchall>internal-slot": true + "@babel/runtime": true, + "prop-types": true, + "prop-types>react-is": true } }, - "@metamask/eth-token-tracker>deep-equal>is-date-object": { + "@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection": { + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-controller>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-trezor-keyring": { - "globals": { - "setTimeout": true - }, + "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "@trezor/connect-web": true, - "browserify>buffer": true, - "webpack>events": true + "@metamask/base-controller": true, + "@metamask/eth-snap-keyring": true, + "@metamask/keyring-api": true, + "@metamask/keyring-controller": true, + "@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "uuid": true } }, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "@metamask/address-book-controller": { "packages": { - "@metamask/eth-sig-util": true, - "@swc/helpers>tslib": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true } }, - "@metamask/eth-trezor-keyring>hdkey": { + "@metamask/announcement-controller": { "packages": { - "browserify>assert": true, - "crypto-browserify": true, - "ethereumjs-util>create-hash>ripemd160": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true + "@metamask/announcement-controller>@metamask/base-controller": true } }, - "@metamask/etherscan-link": { + "@metamask/approval-controller": { "globals": { - "URL": true + "console.info": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/rpc-errors": true, + "nanoid": true } }, - "@metamask/ethjs": { + "@metamask/assets-controllers": { "globals": { + "AbortController": true, + "Headers": true, + "URL": true, + "URLSearchParams": true, "clearInterval": true, - "setInterval": true + "clearTimeout": true, + "console.error": true, + "console.log": true, + "setInterval": true, + "setTimeout": true }, "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-provider-http": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/number-to-bn": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/abi-utils": true, + "@metamask/base-controller": true, + "@metamask/contract-metadata": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/metamask-eth-abis": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, "bn.js": true, - "browserify>buffer": true - } - }, - "@metamask/ethjs-contract": { - "packages": { - "@babel/runtime": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, - "promise-to-callback": true + "cockatiel": true, + "lodash": true, + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, + "single-call-balance-checker-abi": true, + "uuid": true } }, - "@metamask/ethjs-query": { + "@metamask/base-controller": { "globals": { - "console": true + "setTimeout": true }, "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format": true, - "@metamask/ethjs-query>@metamask/ethjs-rpc": true, - "promise-to-callback": true - } - }, - "@metamask/ethjs-query>@metamask/ethjs-format": { - "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "@metamask/ethjs>@metamask/number-to-bn": true + "immer": true } }, - "@metamask/ethjs-query>@metamask/ethjs-rpc": { + "@metamask/announcement-controller>@metamask/base-controller": { + "globals": { + "setTimeout": true + }, "packages": { - "promise-to-callback": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-filter": { + "@metamask/name-controller>@metamask/base-controller": { "globals": { - "clearInterval": true, - "setInterval": true - } - }, - "@metamask/ethjs>@metamask/ethjs-provider-http": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": { + "@metamask/rate-limit-controller>@metamask/base-controller": { "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/ethjs>@metamask/ethjs-unit": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/number-to-bn": true, - "bn.js": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-util": { + "@metamask/browser-passworder": { + "globals": { + "CryptoKey": true, + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, + "@metamask/browser-passworder>@metamask/utils": true, "browserify>buffer": true } }, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true - } - }, - "@metamask/ethjs>@metamask/number-to-bn": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "eth-keyring-controller>@metamask/browser-passworder": { + "globals": { + "crypto": true } }, - "@metamask/ethjs>ethjs-abi": { + "@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/ethjs>ethjs-abi>number-to-bn": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@metamask/ethjs-unit": true, + "@metamask/controller-utils>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, "bn.js": true, - "browserify>buffer": true + "browserify>buffer": true, + "eth-ens-namehash": true, + "eslint>fast-deep-equal": true } }, - "@metamask/ethjs>ethjs-abi>number-to-bn": { + "@metamask/ens-controller": { "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "punycode": true } }, - "@metamask/ethjs>js-sha3": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { "globals": { - "define": true + "clearTimeout": true, + "console.error": true, + "setTimeout": true }, "packages": { - "process": true + "@metamask/safe-event-emitter": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true, + "pify": true } }, - "@metamask/gas-fee-controller": { + "@metamask/network-controller>@metamask/eth-block-tracker": { "globals": { - "clearInterval": true, + "clearTimeout": true, "console.error": true, - "setInterval": true + "setTimeout": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "bn.js": true, - "uuid": true + "@metamask/safe-event-emitter": true, + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, - "@metamask/jazzicon": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring": { "globals": { - "document.createElement": true, - "document.createElementNS": true + "TextEncoder": true }, "packages": { - "@metamask/jazzicon>color": true, - "@metamask/jazzicon>mersenne-twister": true - } - }, - "@metamask/jazzicon>color": { - "packages": { - "@metamask/jazzicon>color>clone": true, - "@metamask/jazzicon>color>color-convert": true, - "@metamask/jazzicon>color>color-string": true - } - }, - "@metamask/jazzicon>color>clone": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/jazzicon>color>color-convert": { - "packages": { - "@metamask/jazzicon>color>color-convert>color-name": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-sig-util": true, + "@metamask/scure-bip39": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@metamask/jazzicon>color>color-string": { + "@metamask/eth-json-rpc-filters": { + "globals": { + "console.error": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/safe-event-emitter": true, + "@metamask/name-controller>async-mutex": true, + "pify": true } }, - "@metamask/json-rpc-engine": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "globals": { + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/json-rpc-engine>@metamask/utils": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true } }, - "@metamask/json-rpc-engine>@metamask/utils": { + "@metamask/eth-json-rpc-middleware": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true, + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>klona": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true } }, - "@metamask/json-rpc-middleware-stream": { - "globals": { - "console.warn": true, - "setTimeout": true - }, + "@metamask/eth-json-rpc-provider": { "packages": { - "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, "@metamask/safe-event-emitter": true, - "readable-stream": true + "uuid": true } }, - "@metamask/json-rpc-middleware-stream>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "addEventListener": true, + "console.error": true, + "document.createElement": true, + "document.head.appendChild": true, + "fetch": true, + "removeEventListener": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-api": { - "globals": { - "URL": true - }, + "@metamask/controller-utils>@metamask/eth-query": { "packages": { - "@metamask/keyring-api>@metamask/utils": true, - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-api>uuid": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/ppom-validator>json-rpc-random-id": true, + "watchify>xtend": true } }, - "@metamask/keyring-api>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/abi-utils": true, + "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-api>uuid": { - "globals": { - "crypto": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/base-controller": true, - "@metamask/browser-passworder": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>ethereumjs-wallet": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/utils": true + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": { - "globals": { - "TextEncoder": true - }, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, - "@metamask/scure-bip39": true, - "browserify>buffer": true + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/keyring-controller>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/eth-sig-util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, "crypto-browserify>randombytes": true } }, - "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "@metamask/eth-snap-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true }, "packages": { + "@ethereumjs/tx": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/keyring-api": true, + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-snap-keyring>@metamask/utils": true, + "webpack>events": true, + "@metamask/eth-snap-keyring>uuid": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": { + "@metamask/eth-token-tracker": { "globals": { - "URL": true + "console.warn": true }, "packages": { - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@babel/runtime": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true, + "@metamask/safe-event-emitter": true, + "bn.js": true, + "@metamask/eth-token-tracker>deep-equal": true, + "human-standard-token-abi": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { + "@metamask/eth-trezor-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, - "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, - "browserify>buffer": true, - "crypto-browserify": true, - "crypto-browserify>randombytes": true, - "eth-lattice-keyring>gridplus-sdk>aes-js": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "uuid": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { - "packages": { - "browserify>assert": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethers>@ethersproject/sha2>hash.js": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true, - "bn.js": true, - "browserify>assert": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, + "@trezor/connect-web": true, "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "@metamask/etherscan-link": { + "globals": { + "URL": true } }, - "@metamask/logging-controller": { + "eth-method-registry>@metamask/ethjs-contract": { "packages": { - "@metamask/base-controller": true, - "uuid": true + "@babel/runtime": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": true, + "eth-ens-namehash>js-sha3": true, + "promise-to-callback": true } }, - "@metamask/logo": { + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": { "globals": { - "addEventListener": true, - "document.body.appendChild": true, - "document.createElementNS": true, - "innerHeight": true, - "innerWidth": true, - "requestAnimationFrame": true - }, - "packages": { - "@metamask/logo>gl-mat4": true, - "@metamask/logo>gl-vec3": true - } - }, - "@metamask/message-manager": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "clearInterval": true, + "setInterval": true } }, - "@metamask/message-manager>jsonschema": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": { "packages": { - "browserify>url": true + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/name-controller": { + "eth-method-registry>@metamask/ethjs-query": { "globals": { - "fetch": true + "console": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/name-controller>@metamask/base-controller": true, - "@metamask/name-controller>@metamask/utils": true, - "@metamask/name-controller>async-mutex": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": true, + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": { "packages": { - "immer": true + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "bn.js": true } }, - "@metamask/name-controller>async-mutex": { - "globals": { - "clearTimeout": true, - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": { "packages": { - "@swc/helpers>tslib": true + "browserify>buffer": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/network-controller": { + "@metamask/gas-fee-controller": { "globals": { - "btoa": true, - "fetch": true, - "setTimeout": true + "clearInterval": true, + "console.error": true, + "setInterval": true }, "packages": { - "@metamask/base-controller": true, "@metamask/controller-utils": true, - "@metamask/eth-json-rpc-middleware": true, - "@metamask/eth-json-rpc-provider": true, - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-block-tracker": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "eslint>fast-deep-equal": true, - "reselect": true, - "uri-js": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "bn.js": true, "uuid": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker": { + "@metamask/jazzicon": { "globals": { - "clearTimeout": true, - "console.error": true, - "setTimeout": true + "document.createElement": true, + "document.createElementNS": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true + "@metamask/jazzicon>color": true, + "@metamask/jazzicon>mersenne-twister": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/json-rpc-engine": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/rpc-errors": true, + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-engine>@metamask/utils": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "@metamask/json-rpc-middleware-stream": { "globals": { - "fetch": true, + "console.warn": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-provider": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true, - "@metamask/rpc-errors": true + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { + "@metamask/snaps-sdk>@metamask/key-tree": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "crypto.subtle": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, + "@metamask/scure-bip39": true, + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/utils>@scure/base": true } }, - "@metamask/notification-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/keyring-api": { + "packages": { + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller": { - "globals": { - "Intl.NumberFormat": true, - "addEventListener": true, - "fetch": true, - "registration": true, - "removeEventListener": true - }, + "@metamask/profile-sync-controller>@metamask/keyring-api": { "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, - "@metamask/notification-services-controller>bignumber.js": true, - "@metamask/notification-services-controller>firebase": true, - "@metamask/profile-sync-controller": true, - "@metamask/utils": true, - "loglevel": true, - "uuid": true + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { - "globals": { - "SuppressedError": true + "@metamask/keyring-controller": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/base-controller": true, + "@metamask/browser-passworder": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, + "@metamask/keyring-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, + "@metamask/keyring-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "@metamask/keyring-controller>ethereumjs-wallet": true } }, - "@metamask/notification-services-controller>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { + "packages": { + "@metamask/keyring-snap-client": true } }, - "@metamask/notification-services-controller>firebase": { + "@metamask/keyring-snap-client": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/messaging": true + "@metamask/keyring-api": true, + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-snap-client>uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app": { + "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { - "FinalizationRegistry": true, - "console.warn": true + "URL": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { + "@metamask/logging-controller": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { + "@metamask/logo": { "globals": { - "console": true + "addEventListener": true, + "document.body.appendChild": true, + "document.createElementNS": true, + "innerHeight": true, + "innerWidth": true, + "requestAnimationFrame": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/logo>gl-mat4": true, + "@metamask/logo>gl-vec3": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": { + "@metamask/message-manager": { + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "uuid": true + } + }, + "@metamask/name-controller": { "globals": { - "DOMException": true, - "IDBCursor": true, - "IDBDatabase": true, - "IDBIndex": true, - "IDBObjectStore": true, - "IDBRequest": true, - "IDBTransaction": true, - "indexedDB.deleteDatabase": true, - "indexedDB.open": true + "fetch": true + }, + "packages": { + "@metamask/name-controller>@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/name-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true } }, - "@metamask/notification-services-controller>firebase>@firebase/installations": { + "@metamask/network-controller": { "globals": { - "BroadcastChannel": true, - "Headers": true, "btoa": true, - "console.error": true, - "crypto": true, "fetch": true, - "msCrypto": true, - "navigator.onLine": true, "setTimeout": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/network-controller>@metamask/eth-block-tracker": true, + "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, + "@metamask/eth-json-rpc-middleware": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true, + "@metamask/utils": true, + "eslint>fast-deep-equal": true, + "reselect": true, + "uri-js": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/messaging": { + "@metamask/transaction-controller>@metamask/nonce-tracker": { + "packages": { + "@ethersproject/providers": true, + "browserify>assert": true, + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true + } + }, + "@metamask/notification-services-controller": { "globals": { - "Headers": true, - "Notification.maxActions": true, - "Notification.permission": true, - "Notification.requestPermission": true, - "PushSubscription.prototype.hasOwnProperty": true, - "ServiceWorkerRegistration": true, - "URL": true, + "Intl.NumberFormat": true, "addEventListener": true, - "atob": true, - "btoa": true, - "clients.matchAll": true, - "clients.openWindow": true, - "console.warn": true, - "document": true, "fetch": true, - "indexedDB": true, - "location.href": true, - "location.origin": true, - "navigator": true, - "origin.replace": true, - "registration.showNotification": true, - "setTimeout": true + "registration": true, + "removeEventListener": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/installations": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true, - "@swc/helpers>tslib": true + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/profile-sync-controller": true, + "@metamask/utils": true, + "@metamask/notification-services-controller>bignumber.js": true, + "@metamask/notification-services-controller>firebase": true, + "loglevel": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/util": { - "globals": { - "atob": true, - "browser": true, - "btoa": true, - "chrome": true, - "console": true, - "document": true, - "indexedDB": true, - "navigator": true, - "process": true, - "self": true, - "setTimeout": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": { "packages": { - "process": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, "@metamask/object-multiplex": { @@ -1970,11 +1504,6 @@ "readable-stream": true } }, - "@metamask/object-multiplex>once": { - "packages": { - "@metamask/object-multiplex>once>wrappy": true - } - }, "@metamask/obs-store": { "packages": { "@metamask/safe-event-emitter": true, @@ -1990,38 +1519,18 @@ "@metamask/controller-utils": true, "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, + "@metamask/permission-controller>@metamask/utils": true, "deep-freeze-strict": true, "immer": true, "nanoid": true } }, - "@metamask/permission-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, "@metamask/permission-log-controller": { "packages": { "@metamask/base-controller": true, "@metamask/permission-log-controller>@metamask/utils": true } }, - "@metamask/permission-log-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, "@metamask/phishing-controller": { "globals": { "TextEncoder": true, @@ -2030,12 +1539,12 @@ "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/base-controller": true, "@metamask/controller-utils": true, "@noble/hashes": true, - "punycode": true, - "webpack-cli>fastest-levenshtein": true + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack-cli>fastest-levenshtein": true, + "punycode": true } }, "@metamask/polling-controller": { @@ -2054,84 +1563,32 @@ "globals": { "MessageEvent.prototype": true, "WorkerGlobalScope": true, - "addEventListener": true, - "browser": true, - "chrome": true, - "location.origin": true, - "postMessage": true, - "removeEventListener": true - }, - "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/ppom-validator": { - "globals": { - "URL": true, - "console.error": true, - "crypto": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/ppom-validator>crypto-js": true, - "@metamask/ppom-validator>elliptic": true, - "await-semaphore": true, - "browserify>buffer": true - } - }, - "@metamask/ppom-validator>crypto-js": { - "globals": { - "crypto": true, - "define": true, - "msCrypto": true - }, - "packages": { - "browserify>browser-resolve": true - } - }, - "@metamask/ppom-validator>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true - } - }, - "@metamask/ppom-validator>elliptic>brorand": { - "globals": { - "crypto": true, - "msCrypto": true + "addEventListener": true, + "browser": true, + "chrome": true, + "location.origin": true, + "postMessage": true, + "removeEventListener": true }, "packages": { - "browserify>browser-resolve": true + "@metamask/post-message-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/ppom-validator>elliptic>hmac-drbg": { + "@metamask/ppom-validator": { + "globals": { + "URL": true, + "console.error": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "ethers>@ethersproject/sha2>hash.js": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "await-semaphore": true, + "browserify>buffer": true, + "@metamask/ppom-validator>crypto-js": true, + "@metamask/ppom-validator>elliptic": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, "@metamask/preferences-controller": { @@ -2157,668 +1614,933 @@ }, "packages": { "@metamask/base-controller": true, + "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/keyring-controller": true, "@metamask/network-controller": true, - "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/profile-sync-controller>@noble/ciphers": true, - "@metamask/profile-sync-controller>siwe": true, "@noble/hashes": true, "browserify>buffer": true, - "loglevel": true + "loglevel": true, + "@metamask/profile-sync-controller>siwe": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api": { + "@metamask/queued-request-controller": { "packages": { - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": true, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/selected-network-controller": true, + "@metamask/utils": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { + "@metamask/rate-limit-controller": { + "globals": { + "setTimeout": true + }, + "packages": { + "@metamask/rate-limit-controller>@metamask/base-controller": true, + "@metamask/rate-limit-controller>@metamask/rpc-errors": true, + "@metamask/rate-limit-controller>@metamask/utils": true + } + }, + "@metamask/remote-feature-flag-controller": { + "packages": { + "@metamask/base-controller": true, + "cockatiel": true, + "uuid": true + } + }, + "@metamask/rpc-errors": { + "packages": { + "@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/rate-limit-controller>@metamask/rpc-errors": { + "packages": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "webpack>events": true + } + }, + "@metamask/scure-bip39": { "globals": { - "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/scure-bip39>@noble/hashes": true, + "@metamask/utils>@scure/base": true } }, - "@metamask/profile-sync-controller>@noble/ciphers": { + "@metamask/selected-network-controller": { + "packages": { + "@metamask/base-controller": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true + } + }, + "@metamask/signature-controller": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "crypto": true + "fetch": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller": true, + "@metamask/logging-controller": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "@metamask/message-manager>jsonschema": true, + "uuid": true } }, - "@metamask/profile-sync-controller>siwe": { + "@metamask/smart-transactions-controller": { "globals": { + "URLSearchParams": true, + "clearInterval": true, "console.error": true, - "console.warn": true + "console.log": true, + "fetch": true, + "setInterval": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random": true, - "ethers": true + "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethersproject/bytes": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "@metamask/transaction-controller": true, + "@metamask/smart-transactions-controller>bignumber.js": true, + "browserify>buffer": true, + "fast-json-patch": true, + "lodash": true } }, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "@metamask/snaps-controllers": { "globals": { - "console.error": true, - "console.log": true + "DecompressionStream": true, + "URL": true, + "clearTimeout": true, + "document.getElementById": true, + "fetch.bind": true, + "setTimeout": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/json-rpc-middleware-stream": true, + "@metamask/object-multiplex": true, + "@metamask/permission-controller": true, + "@metamask/post-message-stream": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/snaps-registry": true, + "@metamask/snaps-rpc-methods": true, + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/snaps-controllers>@metamask/utils": true, + "@metamask/snaps-controllers>@xstate/fsm": true, + "@metamask/name-controller>async-mutex": true, + "browserify>browserify-zlib": true, + "@metamask/snaps-controllers>concat-stream": true, + "eslint>fast-deep-equal": true, + "@metamask/snaps-controllers>get-npm-tarball-url": true, + "immer": true, + "luxon": true, + "nanoid": true, + "readable-stream": true, + "@metamask/snaps-controllers>readable-web-to-node-stream": true, + "semver": true, + "@metamask/snaps-controllers>tar-stream": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random": { + "@metamask/snaps-execution-environments": { "globals": { - "crypto": true, - "msCrypto": true + "document.getElementById": true }, "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, - "browserify>browser-resolve": true + "@metamask/post-message-stream": true, + "@metamask/snaps-utils": true, + "@metamask/utils": true, + "@metamask/snaps-execution-environments>@metamask/utils": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "@metamask/snaps-utils>@metamask/snaps-registry": { "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@noble/hashes": true } }, - "@metamask/queued-request-controller": { + "@metamask/snaps-rpc-methods": { "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, "@metamask/rpc-errors": true, - "@metamask/selected-network-controller": true, - "@metamask/utils": true + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-rpc-methods>@metamask/utils": true, + "@noble/hashes": true, + "luxon": true } }, - "@metamask/rate-limit-controller": { + "@metamask/snaps-sdk": { "globals": { + "fetch": true + }, + "packages": { + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-sdk>@metamask/utils": true + } + }, + "@metamask/snaps-utils": { + "globals": { + "File": true, + "FileReader": true, + "TextDecoder": true, + "TextEncoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "crypto": true, + "document.body.appendChild": true, + "document.createElement": true, + "fetch": true + }, + "packages": { + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/slip44": true, + "@metamask/snaps-sdk": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/utils": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "chalk": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>fast-xml-parser": true, + "@metamask/snaps-utils>marked": true, + "@metamask/snaps-utils>rfdc": true, + "semver": true, + "@metamask/snaps-utils>validate-npm-package-name": true + } + }, + "@metamask/transaction-controller": { + "globals": { + "clearTimeout": true, + "console.error": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/rate-limit-controller>@metamask/base-controller": true, - "@metamask/rate-limit-controller>@metamask/rpc-errors": true, - "@metamask/rate-limit-controller>@metamask/utils": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/abi": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/metamask-eth-abis": true, + "@metamask/network-controller": true, + "@metamask/transaction-controller>@metamask/nonce-tracker": true, + "@metamask/rpc-errors": true, + "@metamask/transaction-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "bn.js": true, + "browserify>buffer": true, + "eth-method-registry": true, + "webpack>events": true, + "fast-json-patch": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/base-controller": { + "@metamask/user-operation-controller": { "globals": { - "setTimeout": true + "fetch": true }, "packages": { - "immer": true - } - }, - "@metamask/rate-limit-controller>@metamask/rpc-errors": { - "packages": { - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/transaction-controller": true, + "@metamask/utils": true, + "bn.js": true, + "webpack>events": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rate-limit-controller>@metamask/utils": { + "@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/remote-feature-flag-controller": { - "packages": { - "@metamask/base-controller": true, - "cockatiel": true - } - }, - "@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true - } - }, - "@metamask/rpc-errors>@metamask/utils": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rpc-methods-flask>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/rpc-methods>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/safe-event-emitter": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39": { + "@metamask/browser-passworder>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/scure-bip39>@noble/hashes": true, - "@metamask/utils>@scure/base": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39>@noble/hashes": { + "@metamask/controller-utils>@metamask/utils": { "globals": { - "TextEncoder": true, - "crypto": true - } - }, - "@metamask/selected-network-controller": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/base-controller": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/keyring-controller": true, - "@metamask/logging-controller": true, - "@metamask/message-manager>jsonschema": true, - "@metamask/signature-controller>@metamask/eth-sig-util": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util": { + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/smart-transactions-controller": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { "globals": { - "URLSearchParams": true, - "clearInterval": true, - "console.error": true, - "console.log": true, - "fetch": true, - "setInterval": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bytes": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/transaction-controller": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "fast-json-patch": true, - "lodash": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { - "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { - "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/eth-json-rpc-middleware>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/util": { - "globals": { - "console.warn": true, - "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "webpack>events": true - } - }, - "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>bignumber.js": { + "@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "DecompressionStream": true, - "URL": true, - "clearTimeout": true, - "document.getElementById": true, - "fetch.bind": true, - "setTimeout": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, - "@metamask/json-rpc-middleware-stream": true, - "@metamask/object-multiplex": true, - "@metamask/permission-controller": true, - "@metamask/post-message-stream": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-controllers>@xstate/fsm": true, - "@metamask/snaps-controllers>concat-stream": true, - "@metamask/snaps-controllers>get-npm-tarball-url": true, - "@metamask/snaps-controllers>readable-web-to-node-stream": true, - "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-rpc-methods": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-utils": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/utils": true, - "browserify>browserify-zlib": true, - "eslint>fast-deep-equal": true, - "immer": true, - "nanoid": true, - "readable-stream": true, + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-controllers-flask>nanoid": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/snaps-controllers>concat-stream": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "readable-stream": true, - "terser>source-map-support>buffer-from": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>nanoid": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>readable-web-to-node-stream": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "readable-stream": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>b4a": true, - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx": true, - "browserify>browser-resolve": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>b4a": { + "@metamask/eth-snap-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx": { + "@metamask/json-rpc-engine>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true, - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { + "@metamask/json-rpc-middleware-stream>@metamask/utils": { "globals": { - "queueMicrotask": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-execution-environments": { + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": { "globals": { - "document.getElementById": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/post-message-stream": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-rpc-methods": { + "@metamask/keyring-api>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk": { + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk>@metamask/key-tree": { + "@metamask/keyring-controller>@metamask/utils": { "globals": { - "crypto.subtle": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/scure-bip39": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils": { + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { "globals": { - "File": true, - "FileReader": true, "TextDecoder": true, - "TextEncoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "crypto": true, - "document.body.appendChild": true, - "document.createElement": true, - "fetch": true + "TextEncoder": true }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils>@metamask/slip44": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>fast-xml-parser": true, - "@metamask/snaps-utils>marked": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, "@noble/hashes": true, - "chalk": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>cron-parser": { + "@metamask/permission-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>browser-resolve": true, - "luxon": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>fast-xml-parser": { + "@metamask/permission-log-controller>@metamask/utils": { "globals": { - "entityName": true, - "val": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/snaps-utils>fast-xml-parser>strnum": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>marked": { + "@metamask/post-message-stream>@metamask/utils": { "globals": { - "console.error": true, - "console.warn": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>rfdc": { + "@metamask/rate-limit-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>buffer": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name": { + "@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-utils>validate-npm-package-name>builtins": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name>builtins": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "process": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/test-bundler>@ethersproject/networks": { + "@metamask/snaps-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "ethers>@ethersproject/logger": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller": { + "@metamask/snaps-execution-environments>@metamask/utils": { "globals": { - "clearTimeout": true, - "console.error": true, - "fetch": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/abi": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/network-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller>@metamask/nonce-tracker": true, - "@metamask/utils": true, - "bn.js": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "eth-method-registry": true, - "fast-json-patch": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker": { + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true, - "browserify>assert": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { + "@metamask/snaps-rpc-methods>@metamask/utils": { "globals": { - "clearTimeout": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/user-operation-controller": { + "@metamask/snaps-sdk>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "bn.js": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/utils": { + "@metamask/snaps-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/utils>@scure/base": { + "@metamask/transaction-controller>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, "@ngraveio/bc-ur": { "packages": { "@ngraveio/bc-ur>@keystonehq/alias-sampling": true, + "browserify>assert": true, "@ngraveio/bc-ur>bignumber.js": true, + "browserify>buffer": true, "@ngraveio/bc-ur>cbor-sync": true, "@ngraveio/bc-ur>crc": true, "@ngraveio/bc-ur>jsbi": true, - "addons-linter>sha.js": true, - "browserify>assert": true, - "browserify>buffer": true + "addons-linter>sha.js": true } }, - "@ngraveio/bc-ur>assert>object-is": { + "@metamask/profile-sync-controller>@noble/ciphers": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "crypto": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { + "globals": { + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true } }, - "@ngraveio/bc-ur>bignumber.js": { + "@noble/hashes": { "globals": { - "crypto": true, - "define": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>cbor-sync": { + "@metamask/scure-bip39>@noble/hashes": { "globals": { - "define": true - }, - "packages": { - "browserify>buffer": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>crc": { - "packages": { - "browserify>buffer": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>jsbi": { + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": { "globals": { - "define": true + "TextEncoder": true, + "crypto": true } }, - "@noble/hashes": { + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { "globals": { "TextEncoder": true, "crypto": true @@ -2835,6 +2557,20 @@ "navigator.userAgent": true } }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "globals": { + "console.log": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "globals": { + "XMLHttpRequest": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + } + }, "@reduxjs/toolkit": { "globals": { "AbortController": true, @@ -2846,42 +2582,46 @@ "setTimeout": true }, "packages": { - "@reduxjs/toolkit>reselect": true, "immer": true, "process": true, "redux": true, - "redux-thunk": true - } - }, - "@segment/loosely-validate-event": { - "packages": { - "@segment/loosely-validate-event>component-type": true, - "@segment/loosely-validate-event>join-component": true, - "browserify>assert": true, - "browserify>buffer": true + "redux-thunk": true, + "@reduxjs/toolkit>reselect": true } }, - "@sentry/browser": { + "react-router-dom-v5-compat>@remix-run/router": { "globals": { - "PerformanceObserver.supportedEntryTypes": true, + "AbortController": true, + "DOMException": true, + "FormData": true, + "Headers": true, "Request": true, + "Response": true, "URL": true, - "XMLHttpRequest.prototype": true, - "__SENTRY_DEBUG__": true, - "__SENTRY_RELEASE__": true, - "addEventListener": true, - "console.error": true, - "indexedDB.open": true, - "performance.timeOrigin": true, - "setTimeout": true - }, + "URLSearchParams": true, + "console": true, + "document.defaultView": true + } + }, + "@metamask/utils>@scure/base": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "packages": { + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true, + "@metamask/utils>@scure/base": true + } + }, + "@segment/loosely-validate-event": { "packages": { - "@sentry/browser>@sentry-internal/browser-utils": true, - "@sentry/browser>@sentry-internal/feedback": true, - "@sentry/browser>@sentry-internal/replay": true, - "@sentry/browser>@sentry-internal/replay-canvas": true, - "@sentry/browser>@sentry/core": true, - "@sentry/utils": true + "browserify>assert": true, + "browserify>buffer": true, + "@segment/loosely-validate-event>component-type": true, + "@segment/loosely-validate-event>join-component": true } }, "@sentry/browser>@sentry-internal/browser-utils": { @@ -2920,6 +2660,25 @@ "@sentry/utils": true } }, + "@sentry/browser>@sentry-internal/replay-canvas": { + "globals": { + "Blob": true, + "HTMLCanvasElement": true, + "HTMLImageElement": true, + "ImageData": true, + "URL.createObjectURL": true, + "WeakRef": true, + "Worker": true, + "cancelAnimationFrame": true, + "console.error": true, + "createImageBitmap": true, + "document": true + }, + "packages": { + "@sentry/browser>@sentry/core": true, + "@sentry/utils": true + } + }, "@sentry/browser>@sentry-internal/replay": { "globals": { "Blob": true, @@ -2969,21 +2728,25 @@ "@sentry/utils": true } }, - "@sentry/browser>@sentry-internal/replay-canvas": { + "@sentry/browser": { "globals": { - "Blob": true, - "HTMLCanvasElement": true, - "HTMLImageElement": true, - "ImageData": true, - "URL.createObjectURL": true, - "WeakRef": true, - "Worker": true, - "cancelAnimationFrame": true, + "PerformanceObserver.supportedEntryTypes": true, + "Request": true, + "URL": true, + "XMLHttpRequest.prototype": true, + "__SENTRY_DEBUG__": true, + "__SENTRY_RELEASE__": true, + "addEventListener": true, "console.error": true, - "createImageBitmap": true, - "document": true + "indexedDB.open": true, + "performance.timeOrigin": true, + "setTimeout": true }, "packages": { + "@sentry/browser>@sentry-internal/browser-utils": true, + "@sentry/browser>@sentry-internal/feedback": true, + "@sentry/browser>@sentry-internal/replay-canvas": true, + "@sentry/browser>@sentry-internal/replay": true, "@sentry/browser>@sentry/core": true, "@sentry/utils": true } @@ -3079,20 +2842,61 @@ "btoa": true } }, - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { + "@metamask/controller-utils>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "react-markdown>unist-util-visit": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true } }, - "@storybook/addon-knobs>qs": { + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "string.prototype.matchall>side-channel": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true + } + }, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true } }, - "@swc/helpers>tslib": { + "@metamask/profile-sync-controller>siwe>@stablelib/random": { "globals": { - "SuppressedError": true, - "define": true + "crypto": true, + "msCrypto": true + }, + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, + "browserify>browser-resolve": true + } + }, + "@trezor/connect-web>@trezor/connect-common": { + "globals": { + "console.warn": true, + "localStorage.getItem": true, + "localStorage.setItem": true, + "navigator": true, + "setTimeout": true, + "window": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, + "@trezor/connect-web>@trezor/utils": true, + "tslib": true + } + }, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "packages": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "tslib": true } }, "@trezor/connect-web": { @@ -3119,35 +2923,20 @@ "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/connect-common": true, + "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/utils": true, - "webpack>events": true + "webpack>events": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect": { "packages": { - "@swc/helpers>tslib": true, "@trezor/connect-web>@trezor/connect>@trezor/protobuf": true, "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, "@trezor/connect-web>@trezor/connect>@trezor/transport": true, - "@trezor/connect-web>@trezor/utils": true - } - }, - "@trezor/connect-web>@trezor/connect-common": { - "globals": { - "console.warn": true, - "localStorage.getItem": true, - "localStorage.setItem": true, - "navigator": true, - "setTimeout": true, - "window": true - }, - "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, - "@trezor/connect-web>@trezor/utils": true + "@trezor/connect-web>@trezor/utils": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": { @@ -3163,157 +2952,248 @@ "screen.width": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true, - "process": true + "process": true, + "tslib": true, + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true } }, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, + "browserify>buffer": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, + "tslib": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { "globals": { - "define": true + "console.warn": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, + "browserify>buffer": true, + "ts-mixer": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "@trezor/connect-web>@trezor/utils": { + "globals": { + "AbortController": true, + "Intl.NumberFormat": true, + "clearInterval": true, + "clearTimeout": true, + "console.error": true, + "console.info": true, + "console.log": true, + "console.warn": true, + "setInterval": true, + "setTimeout": true + }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, - "browserify>buffer": true + "@trezor/connect-web>@trezor/utils>bignumber.js": true, + "browserify>buffer": true, + "webpack>events": true, + "tslib": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { + "@welldone-software/why-did-you-render": { "globals": { - "process": true, + "Element": true, + "console.group": true, + "console.groupCollapsed": true, + "console.groupEnd": true, + "console.log": true, + "console.warn": true, + "define": true, "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true + "lodash": true, + "react": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "@zxing/browser": { "globals": { - "console.log": true + "HTMLElement": true, + "HTMLImageElement": true, + "HTMLVideoElement": true, + "clearTimeout": true, + "console.error": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library": true + } + }, + "@zxing/library": { + "globals": { + "HTMLImageElement": true, + "HTMLVideoElement": true, + "TextDecoder": true, + "TextEncoder": true, + "URL.createObjectURL": true, + "btoa": true, + "console.log": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library>ts-custom-error": true + } + }, + "@lavamoat/lavapack>readable-stream>abort-controller": { + "globals": { + "AbortController": true + } + }, + "currency-formatter>accounting": { + "globals": { + "define": true + } + }, + "ethers>@ethersproject/json-wallets>aes-js": { + "globals": { + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>aes-js": { + "globals": { + "define": true + } + }, + "chalk>ansi-styles": { + "packages": { + "chalk>ansi-styles>color-convert": true + } + }, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { + "packages": { + "browserify>buffer": true + } + }, + "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true + } + }, + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "browserify>vm-browserify": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "browserify>assert": { "globals": { - "XMLHttpRequest": true + "Buffer": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + "react>object-assign": true, + "browserify>assert>util": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { + "@metamask/name-controller>async-mutex": { "globals": { - "console.warn": true + "clearTimeout": true, + "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, - "browserify>buffer": true, - "ts-mixer": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils": { + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { "globals": { - "AbortController": true, - "Intl.NumberFormat": true, - "clearInterval": true, "clearTimeout": true, - "console.error": true, - "console.info": true, - "console.log": true, - "console.warn": true, - "setInterval": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/utils>bignumber.js": true, - "browserify>buffer": true, - "webpack>events": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "string.prototype.matchall>es-abstract>available-typed-arrays": { + "packages": { + "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true } }, - "@welldone-software/why-did-you-render": { + "await-semaphore": { + "packages": { + "process": true, + "browserify>timers-browserify": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { "globals": { - "Element": true, - "console.group": true, - "console.groupCollapsed": true, - "console.groupEnd": true, - "console.log": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, - "define": true, + "document": true, + "location.href": true, + "navigator": true, "setTimeout": true }, "packages": { - "lodash": true, - "react": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/browser": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { "globals": { - "HTMLElement": true, - "HTMLImageElement": true, - "HTMLVideoElement": true, - "clearTimeout": true, - "console.error": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/library": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { "globals": { - "HTMLImageElement": true, - "HTMLVideoElement": true, - "TextDecoder": true, - "TextEncoder": true, - "URL.createObjectURL": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, "btoa": true, - "console.log": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library>ts-custom-error": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "addons-linter>sha.js": { - "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@metamask/snaps-controllers>tar-stream>b4a": { + "globals": { + "TextDecoder": true, + "TextEncoder": true } }, - "await-semaphore": { + "@ensdomains/content-hash>multihashes>multibase>base-x": { "packages": { - "browserify>timers-browserify": true, - "process": true - } - }, - "axios>form-data": { - "globals": { - "FormData": true + "koa>content-disposition>safe-buffer": true } }, "base32-encode": { @@ -3327,139 +3207,178 @@ "define": true } }, - "blo": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { "globals": { - "btoa": true + "crypto": true, + "define": true } }, - "bn.js": { + "@metamask/notification-services-controller>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "define": true } }, - "bowser": { + "@metamask/smart-transactions-controller>bignumber.js": { "globals": { + "crypto": true, "define": true } }, - "browserify>assert": { + "@ngraveio/bc-ur>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>assert>util": true, - "react>object-assign": true + "crypto": true, + "define": true } }, - "browserify>assert>util": { + "@trezor/connect-web>@trezor/utils>bignumber.js": { "globals": { - "console.error": true, - "console.log": true, - "console.trace": true, - "process": true - }, + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bitwise": { "packages": { - "browserify>assert>util>inherits": true, - "process": true + "browserify>buffer": true } }, - "browserify>browserify-zlib": { + "blo": { + "globals": { + "btoa": true + } + }, + "bn.js": { + "globals": { + "Buffer": true + }, "packages": { - "browserify>assert": true, - "browserify>browserify-zlib>pako": true, - "browserify>buffer": true, - "browserify>util": true, - "process": true, - "stream-browserify": true + "browserify>browser-resolve": true } }, - "browserify>buffer": { + "eth-lattice-keyring>gridplus-sdk>borc": { "globals": { "console": true }, "packages": { - "base64-js": true, - "buffer>ieee754": true + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, + "browserify>buffer": true, + "buffer>ieee754": true, + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true } }, - "browserify>punycode": { + "bowser": { "globals": { "define": true } }, - "browserify>string_decoder": { + "@metamask/ppom-validator>elliptic>brorand": { + "globals": { + "crypto": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "ethereumjs-util>ethereum-cryptography>browserify-aes": { "packages": { + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "pumpify>inherits": true, "koa>content-disposition>safe-buffer": true } }, - "browserify>timers-browserify": { - "globals": { - "clearInterval": true, - "clearTimeout": true, - "setInterval": true, - "setTimeout": true - }, + "crypto-browserify>browserify-cipher": { "packages": { - "process": true + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "crypto-browserify>browserify-cipher>browserify-des": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true } }, - "browserify>url": { + "crypto-browserify>browserify-cipher>browserify-des": { "packages": { - "@storybook/addon-knobs>qs": true, - "browserify>punycode": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>browserify-des>des.js": true, + "pumpify>inherits": true } }, - "browserify>util": { - "globals": { - "console.error": true, - "console.log": true, - "console.trace": true - }, + "crypto-browserify>public-encrypt>browserify-rsa": { "packages": { - "browserify>util>is-arguments": true, - "browserify>util>is-typed-array": true, - "browserify>util>which-typed-array": true, - "koa>is-generator-function": true, + "bn.js": true, + "browserify>buffer": true, + "crypto-browserify>randombytes": true + } + }, + "crypto-browserify>browserify-sign": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>create-hmac": true, + "@metamask/ppom-validator>elliptic": true, + "pumpify>inherits": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "stream-browserify": true + } + }, + "browserify>browserify-zlib": { + "packages": { + "browserify>assert": true, + "browserify>buffer": true, + "browserify>browserify-zlib>pako": true, "process": true, - "pumpify>inherits": true + "stream-browserify": true, + "browserify>util": true } }, - "browserify>util>is-arguments": { + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true } }, - "browserify>util>is-typed-array": { + "ethereumjs-util>ethereum-cryptography>bs58check": { "packages": { - "browserify>util>which-typed-array": true + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, + "ethereumjs-util>create-hash": true, + "koa>content-disposition>safe-buffer": true } }, - "browserify>util>which-typed-array": { + "buffer": { + "globals": { + "console": true + }, "packages": { - "browserify>util>which-typed-array>for-each": true, - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>available-typed-arrays": true, - "string.prototype.matchall>es-abstract>gopd": true + "base64-js": true, + "buffer>ieee754": true } }, - "browserify>util>which-typed-array>for-each": { + "terser>source-map-support>buffer-from": { "packages": { - "string.prototype.matchall>es-abstract>is-callable": true + "browserify>buffer": true } }, - "browserify>vm-browserify": { - "globals": { - "document.body.appendChild": true, - "document.body.removeChild": true, - "document.createElement": true + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "packages": { + "browserify>buffer": true } }, - "buffer": { + "browserify>buffer": { "globals": { "console": true }, @@ -3468,20 +3387,33 @@ "buffer>ieee754": true } }, - "chalk": { + "@metamask/snaps-utils>validate-npm-package-name>builtins": { "packages": { - "chalk>ansi-styles": true, - "chalk>supports-color": true + "process": true, + "semver": true } }, - "chalk>ansi-styles": { + "string.prototype.matchall>call-bind": { "packages": { - "chalk>ansi-styles>color-convert": true + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>call-bind>set-function-length": true } }, - "chalk>ansi-styles>color-convert": { + "@ngraveio/bc-ur>cbor-sync": { + "globals": { + "define": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "browserify>buffer": true + } + }, + "chalk": { + "packages": { + "chalk>ansi-styles": true, + "chalk>supports-color": true } }, "chart.js": { @@ -3505,9 +3437,20 @@ "chart.js>@kurkle/color": true } }, - "chart.js>@kurkle/color": { - "globals": { - "define": true + "@ensdomains/content-hash>cids": { + "packages": { + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>cids>multihashes": true, + "@ensdomains/content-hash>cids>uint8arrays": true + } + }, + "ethereumjs-util>create-hash>cipher-base": { + "packages": { + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true, + "stream-browserify": true, + "browserify>string_decoder": true } }, "classnames": { @@ -3516,6 +3459,11 @@ "define": true } }, + "@metamask/jazzicon>color>clone": { + "packages": { + "browserify>buffer": true + } + }, "cockatiel": { "globals": { "AbortController": true, @@ -3529,6 +3477,37 @@ "process": true } }, + "chalk>ansi-styles>color-convert": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color>color-convert": { + "packages": { + "@metamask/jazzicon>color>color-convert>color-name": true + } + }, + "@metamask/jazzicon>color>color-string": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color": { + "packages": { + "@metamask/jazzicon>color>clone": true, + "@metamask/jazzicon>color>color-convert": true, + "@metamask/jazzicon>color>color-string": true + } + }, + "@metamask/snaps-controllers>concat-stream": { + "packages": { + "terser>source-map-support>buffer-from": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "readable-stream": true, + "browserify>concat-stream>typedarray": true + } + }, "copy-to-clipboard": { "globals": { "clipboardData": true, @@ -3547,10 +3526,47 @@ "copy-to-clipboard>toggle-selection": true } }, - "copy-to-clipboard>toggle-selection": { + "@ethereumjs/tx>@ethereumjs/common>crc-32": { "globals": { - "document.activeElement": true, - "document.getSelection": true + "DO_NOT_EXPORT_CRC": true, + "define": true + } + }, + "@ngraveio/bc-ur>crc": { + "packages": { + "browserify>buffer": true + } + }, + "crypto-browserify>create-ecdh": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "@metamask/ppom-validator>elliptic": true + } + }, + "ethereumjs-util>create-hash": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>md5.js": true, + "ethereumjs-util>create-hash>ripemd160": true, + "addons-linter>sha.js": true + } + }, + "crypto-browserify>create-hmac": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "ethereumjs-util>create-hash": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true + } + }, + "@metamask/snaps-utils>cron-parser": { + "packages": { + "browserify>browser-resolve": true, + "luxon": true } }, "crypto-browserify": { @@ -3558,303 +3574,453 @@ "crypto-browserify>browserify-cipher": true, "crypto-browserify>browserify-sign": true, "crypto-browserify>create-ecdh": true, + "ethereumjs-util>create-hash": true, "crypto-browserify>create-hmac": true, "crypto-browserify>diffie-hellman": true, "crypto-browserify>pbkdf2": true, "crypto-browserify>public-encrypt": true, "crypto-browserify>randombytes": true, - "crypto-browserify>randomfill": true, - "ethereumjs-util>create-hash": true + "crypto-browserify>randomfill": true } }, - "crypto-browserify>browserify-cipher": { + "@metamask/ppom-validator>crypto-js": { + "globals": { + "crypto": true, + "define": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "react-beautiful-dnd>css-box-model": { + "globals": { + "getComputedStyle": true, + "pageXOffset": true, + "pageYOffset": true + }, + "packages": { + "react-router-dom>tiny-invariant": true + } + }, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { + "globals": { + "document.createElement": true, + "document.documentElement": true, + "getComputedStyle": true + }, + "packages": { + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true + } + }, + "currency-formatter": { + "packages": { + "currency-formatter>accounting": true, + "currency-formatter>locale-currency": true, + "react>object-assign": true + } + }, + "debounce-stream": { + "packages": { + "debounce-stream>debounce": true, + "debounce-stream>duplexer": true, + "debounce-stream>through": true + } + }, + "debounce-stream>debounce": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "nock>debug": { + "globals": { + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true + }, + "packages": { + "nock>debug>ms": true, + "process": true + } + }, + "@metamask/eth-token-tracker>deep-equal": { + "packages": { + "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, + "string.prototype.matchall>call-bind": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, + "string.prototype.matchall>get-intrinsic": true, + "browserify>util>is-arguments": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "string.prototype.matchall>es-abstract>is-regex": true, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "@ngraveio/bc-ur>assert>object-is": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true, + "gulp>vinyl-fs>object.assign": true, + "string.prototype.matchall>regexp.prototype.flags": true, + "string.prototype.matchall>side-channel": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, + "@metamask/eth-token-tracker>deep-equal>which-collection": true, + "browserify>util>which-typed-array": true + } + }, + "string.prototype.matchall>define-properties>define-data-property": { + "packages": { + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>gopd": true + } + }, + "string.prototype.matchall>define-properties": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true + } + }, + "crypto-browserify>browserify-cipher>browserify-des>des.js": { "packages": { - "crypto-browserify>browserify-cipher>browserify-des": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true } }, - "crypto-browserify>browserify-cipher>browserify-des": { + "crypto-browserify>diffie-hellman": { "packages": { + "bn.js": true, "browserify>buffer": true, - "crypto-browserify>browserify-cipher>browserify-des>des.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "pumpify>inherits": true + "crypto-browserify>diffie-hellman>miller-rabin": true, + "crypto-browserify>randombytes": true } }, - "crypto-browserify>browserify-cipher>browserify-des>des.js": { + "@material-ui/core>react-transition-group>dom-helpers": { "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "@babel/runtime": true } }, - "crypto-browserify>browserify-cipher>evp_bytestokey": { + "debounce-stream>duplexer": { "packages": { - "ethereumjs-util>create-hash>md5.js": true, - "koa>content-disposition>safe-buffer": true + "stream-browserify": true } }, - "crypto-browserify>browserify-sign": { + "ethers>@ethersproject/signing-key>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "ethereumjs-util>create-hash": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, "pumpify>inherits": true, - "stream-browserify": true + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-ecdh": { + "@metamask/ppom-validator>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-hmac": { + "eth-lattice-keyring>gridplus-sdk>elliptic": { "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>diffie-hellman": { + "string.prototype.matchall>call-bind>es-define-property": { "packages": { - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>diffie-hellman>miller-rabin": true, - "crypto-browserify>randombytes": true + "string.prototype.matchall>get-intrinsic": true } }, - "crypto-browserify>diffie-hellman>miller-rabin": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "bn.js": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>has-symbols": true, + "browserify>util>is-arguments": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "eslint-plugin-react>array-includes>is-string": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "process": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true } }, - "crypto-browserify>pbkdf2": { + "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { "globals": { - "crypto": true, - "process": true, - "queueMicrotask": true, - "setImmediate": true, - "setTimeout": true + "intToBuffer": true }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "bn.js": true, + "buffer": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt": { + "eth-ens-namehash": { + "globals": { + "name": "write" + }, "packages": { - "bn.js": true, "browserify>buffer": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>create-hash": true + "eth-ens-namehash>idna-uts46-hx": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt>browserify-rsa": { + "eth-lattice-keyring": { + "globals": { + "addEventListener": true, + "browser": true, + "clearInterval": true, + "fetch": true, + "open": true, + "setInterval": true + }, "packages": { + "eth-lattice-keyring>@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, - "crypto-browserify>randombytes": true + "crypto-browserify": true, + "webpack>events": true, + "eth-lattice-keyring>gridplus-sdk": true, + "eth-lattice-keyring>rlp": true } }, - "crypto-browserify>public-encrypt>parse-asn1": { + "eth-method-registry": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "crypto-browserify>pbkdf2": true, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true } }, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "@ethereumjs/tx>ethereum-cryptography": { + "globals": { + "TextDecoder": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "bn.js": true, - "browserify>buffer": true, - "browserify>vm-browserify": true, - "pumpify>inherits": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "crypto-browserify>randombytes": { + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "crypto-browserify>randomfill": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "crypto-browserify>randombytes": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "currency-formatter": { + "ethereumjs-util>ethereum-cryptography": { "packages": { - "currency-formatter>accounting": true, - "currency-formatter>locale-currency": true, - "react>object-assign": true - } - }, - "currency-formatter>accounting": { - "globals": { - "define": true - } - }, - "currency-formatter>locale-currency": { - "globals": { - "countryCode": true + "browserify>buffer": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "ganache>secp256k1": true } }, - "debounce-stream": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { "packages": { - "debounce-stream>debounce": true, - "debounce-stream>duplexer": true, - "debounce-stream>through": true + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify>create-hmac": true, + "ethers>@ethersproject/sha2>hash.js": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true } }, - "debounce-stream>debounce": { - "globals": { - "clearTimeout": true, - "setTimeout": true + "ethereumjs-util": { + "packages": { + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "ethereumjs-util>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "ethereumjs-util>rlp": true } }, - "debounce-stream>duplexer": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { "packages": { - "stream-browserify": true + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true } }, - "debounce-stream>through": { + "@metamask/keyring-controller>ethereumjs-wallet": { "packages": { - "process": true, - "stream-browserify": true + "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, + "crypto-browserify>randombytes": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true, + "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, + "uuid": true } }, - "depcheck>@vue/compiler-sfc>postcss>nanoid": { - "globals": { - "crypto.getRandomValues": true + "ethers": { + "packages": { + "@ethersproject/abi": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/contracts": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/providers": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/solidity": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/units": true, + "@ethersproject/wallet": true, + "ethers>@ethersproject/web": true, + "ethers>@ethersproject/wordlists": true } }, - "depcheck>is-core-module>hasown": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": { "packages": { - "browserify>has>function-bind": true + "bn.js": true, + "browserify>buffer": true, + "eth-ens-namehash>js-sha3": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": true } }, - "dependency-tree>precinct>detective-postcss>postcss>nanoid": { + "webpack>events": { "globals": { - "crypto.getRandomValues": true + "console": true } }, - "eslint-plugin-react>array-includes>is-string": { + "crypto-browserify>browserify-cipher>evp_bytestokey": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash>md5.js": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-ens-namehash": { - "globals": { - "name": "write" - }, + "extension-port-stream": { "packages": { - "@metamask/ethjs>js-sha3": true, "browserify>buffer": true, - "eth-ens-namehash>idna-uts46-hx": true + "extension-port-stream>readable-stream": true } }, - "eth-ens-namehash>idna-uts46-hx": { + "fast-json-patch": { "globals": { - "define": true + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, + "@metamask/snaps-utils>fast-xml-parser": { + "globals": { + "entityName": true, + "val": true }, "packages": { - "browserify>punycode": true + "@metamask/snaps-utils>fast-xml-parser>strnum": true } }, - "eth-keyring-controller>@metamask/browser-passworder": { - "globals": { - "crypto": true + "@metamask/notification-services-controller>firebase": { + "packages": { + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/messaging": true } }, - "eth-lattice-keyring": { + "react-focus-lock>focus-lock": { "globals": { - "addEventListener": true, - "browser": true, - "clearInterval": true, - "fetch": true, - "open": true, - "setInterval": true + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify": true, - "eth-lattice-keyring>@ethereumjs/tx": true, - "eth-lattice-keyring>gridplus-sdk": true, - "eth-lattice-keyring>rlp": true, - "webpack>events": true + "tslib": true } }, - "eth-lattice-keyring>@ethereumjs/tx": { + "browserify>util>which-typed-array>for-each": { "packages": { - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>es-abstract>is-callable": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { - "packages": { - "browserify": true, - "browserify>buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true + "axios>form-data": { + "globals": { + "FormData": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { + "fuse.js": { "globals": { - "WeakRef": true - }, - "packages": { - "browserify": true + "console": true, + "define": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { + "string.prototype.matchall>get-intrinsic": { "globals": { - "TextDecoder": true, - "crypto": true + "AggregateError": true, + "FinalizationRegistry": true, + "WeakRef": true }, "packages": { - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true + "string.prototype.matchall>es-abstract>gopd": { + "packages": { + "string.prototype.matchall>get-intrinsic": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3872,230 +4038,307 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethersproject/abi": true, - "@metamask/ethjs>js-sha3": true, - "@metamask/keyring-api>bech32": true, - "bn.js": true, - "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": true, + "@ethersproject/abi": true, "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "@metamask/keyring-api>bech32": true, "eth-lattice-keyring>gridplus-sdk>bignumber.js": true, "eth-lattice-keyring>gridplus-sdk>bitwise": true, + "bn.js": true, "eth-lattice-keyring>gridplus-sdk>borc": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, "eth-lattice-keyring>gridplus-sdk>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, - "eth-lattice-keyring>gridplus-sdk>uuid": true, - "eth-lattice-keyring>rlp": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, "ethers>@ethersproject/sha2>hash.js": true, + "eth-ens-namehash>js-sha3": true, + "lodash": true, + "eth-lattice-keyring>rlp": true, "ganache>secp256k1": true, - "lodash": true + "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { + "string.prototype.matchall>es-abstract>has-property-descriptors": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "string.prototype.matchall>call-bind>es-define-property": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { + "koa>is-generator-function>has-tostringtag": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>has-symbols": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { + "ethereumjs-util>create-hash>md5.js>hash-base": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "pumpify>inherits": true, + "readable-stream": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { + "ethers>@ethersproject/sha2>hash.js": { + "packages": { + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true + } + }, + "depcheck>is-core-module>hasown": { + "packages": { + "browserify>has>function-bind": true + } + }, + "@metamask/eth-trezor-keyring>hdkey": { + "packages": { + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "crypto-browserify": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true + } + }, + "he": { "globals": { - "TextDecoder": true, - "crypto": true + "define": true + } + }, + "history": { + "globals": { + "console": true, + "define": true, + "document.defaultView": true, + "document.querySelector": true + } + }, + "react-router-dom>history": { + "globals": { + "addEventListener": true, + "confirm": true, + "document": true, + "history": true, + "location": true, + "navigator.userAgent": true, + "removeEventListener": true }, "packages": { - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "react-router-dom>history>resolve-pathname": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true, + "react-router-dom>history>value-equal": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "@metamask/ppom-validator>elliptic>hmac-drbg": { + "packages": { + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true + } + }, + "react-redux>hoist-non-react-statics": { + "packages": { + "prop-types>react-is": true + } + }, + "https-browserify": { + "packages": { + "stream-http": true, + "browserify>url": true + } + }, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": { "globals": { - "TextEncoder": true, - "crypto": true + "DOMException": true, + "IDBCursor": true, + "IDBDatabase": true, + "IDBIndex": true, + "IDBObjectStore": true, + "IDBRequest": true, + "IDBTransaction": true, + "indexedDB.deleteDatabase": true, + "indexedDB.open": true } }, - "eth-lattice-keyring>gridplus-sdk>aes-js": { + "eth-ens-namehash>idna-uts46-hx": { "globals": { "define": true + }, + "packages": { + "browserify>punycode": true + } + }, + "string.prototype.matchall>internal-slot": { + "packages": { + "string.prototype.matchall>call-bind>es-errors": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>side-channel": true + } + }, + "browserify>util>is-arguments": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true + } + }, + "string.prototype.matchall>es-abstract>is-array-buffer": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "packages": { + "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "string.prototype.matchall>es-abstract>is-callable": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>bitwise": { + "@metamask/eth-token-tracker>deep-equal>is-date-object": { "packages": { - "browserify>buffer": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc": { - "globals": { - "console": true - }, + "koa>is-generator-function": { "packages": { - "browserify>buffer": true, - "buffer>ieee754": true, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "@material-ui/core>@material-ui/styles>jss>is-in-browser": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { - "globals": { - "URL": true, - "URLSearchParams": true, - "location": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>elliptic": { + "string.prototype.matchall>es-abstract>is-regex": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { - "globals": { - "intToBuffer": true - }, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": { "packages": { - "@metamask/ethjs>js-sha3": true, - "bn.js": true, - "buffer": true + "string.prototype.matchall>call-bind": true } }, - "eth-lattice-keyring>gridplus-sdk>uuid": { - "globals": { - "crypto": true + "eslint-plugin-react>array-includes>is-string": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>rlp": { - "globals": { - "TextEncoder": true + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "packages": { + "string.prototype.matchall>has-symbols": true } }, - "eth-method-registry": { + "browserify>util>is-typed-array": { "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true + "browserify>util>which-typed-array": true } }, - "ethereumjs-util": { + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { "packages": { - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography": true, - "ethereumjs-util>rlp": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true } }, - "ethereumjs-util>create-hash": { + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { + "globals": { + "URL": true, + "URLSearchParams": true, + "location": true + } + }, + "@ensdomains/content-hash>js-base64": { + "globals": { + "Base64": "write", + "TextDecoder": true, + "TextEncoder": true, + "atob": true, + "btoa": true, + "define": true + }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>md5.js": true, - "ethereumjs-util>create-hash>ripemd160": true, - "pumpify>inherits": true + "browserify>buffer": true } }, - "ethereumjs-util>create-hash>cipher-base": { + "eth-ens-namehash>js-sha3": { + "globals": { + "define": true + }, "packages": { - "browserify>string_decoder": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "stream-browserify": true + "process": true } }, - "ethereumjs-util>create-hash>md5.js": { + "@ngraveio/bc-ur>jsbi": { + "globals": { + "define": true + } + }, + "@metamask/message-manager>jsonschema": { "packages": { - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "browserify>url": true } }, - "ethereumjs-util>create-hash>md5.js>hash-base": { + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "readable-stream": true + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true } }, - "ethereumjs-util>create-hash>ripemd160": { + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { + "globals": { + "CSS": true + }, "packages": { - "browserify>buffer": true, - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "pumpify>inherits": true + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography": { + "@material-ui/core>@material-ui/styles>jss-plugin-global": { "packages": { - "browserify>buffer": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ganache>secp256k1": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes": { + "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@babel/runtime": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { - "browserify>buffer": true + "@material-ui/core>@material-ui/styles>jss": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check": { + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { "packages": { - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, - "koa>content-disposition>safe-buffer": true + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { + "@material-ui/core>@material-ui/styles>jss": { + "globals": { + "CSS": true, + "document.createElement": true, + "document.querySelector": true + }, "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, + "react-router-dom>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4104,536 +4347,496 @@ "readable-stream": true } }, - "ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "currency-formatter>locale-currency": { + "globals": { + "countryCode": true } }, - "ethereumjs-wallet>randombytes": { + "localforage": { "globals": { - "crypto.getRandomValues": true + "Blob": true, + "BlobBuilder": true, + "FileReader": true, + "IDBKeyRange": true, + "MSBlobBuilder": true, + "MozBlobBuilder": true, + "OIndexedDB": true, + "WebKitBlobBuilder": true, + "atob": true, + "btoa": true, + "console.error": true, + "console.info": true, + "console.warn": true, + "define": true, + "fetch": true, + "indexedDB": true, + "localStorage": true, + "mozIndexedDB": true, + "msIndexedDB": true, + "navigator.platform": true, + "navigator.userAgent": true, + "openDatabase": true, + "setTimeout": true, + "webkitIndexedDB": true } }, - "ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/web": true, - "ethers>@ethersproject/wordlists": true + "lodash": { + "globals": { + "clearTimeout": true, + "define": true, + "setTimeout": true } }, - "ethers>@ethersproject/abstract-provider": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "loglevel": { + "globals": { + "console": true, + "define": true, + "document.cookie": true, + "localStorage": true, + "log": "write", + "navigator": true } }, - "ethers>@ethersproject/abstract-signer": { - "packages": { - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "lottie-web": { + "globals": { + "Blob": true, + "Howl": true, + "OffscreenCanvas": true, + "URL.createObjectURL": true, + "Worker": true, + "XMLHttpRequest": true, + "bodymovin": "write", + "clearInterval": true, + "console": true, + "define": true, + "document.body": true, + "document.createElement": true, + "document.createElementNS": true, + "document.getElementsByClassName": true, + "document.getElementsByTagName": true, + "document.querySelectorAll": true, + "document.readyState": true, + "location.origin": true, + "location.pathname": true, + "navigator": true, + "requestAnimationFrame": true, + "setInterval": true, + "setTimeout": true } }, - "ethers>@ethersproject/address": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/rlp": true + "luxon": { + "globals": { + "Intl": true } }, - "ethers>@ethersproject/base64": { + "@metamask/snaps-utils>marked": { "globals": { - "atob": true, - "btoa": true - }, - "packages": { - "@ethersproject/bytes": true + "console.error": true, + "console.warn": true, + "define": true } }, - "ethers>@ethersproject/basex": { + "ethereumjs-util>create-hash>md5.js": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/properties": true + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "ethers>@ethersproject/constants": { + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { "packages": { - "@ethersproject/bignumber": true + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/json-wallets": { + "react-markdown>remark-parse>mdast-util-from-markdown": { "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets>aes-js": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/pbkdf2": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "ethers>@ethersproject/json-wallets>aes-js": { - "globals": { - "define": true + "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true } }, - "ethers>@ethersproject/json-wallets>scrypt-js": { + "react-markdown>remark-rehype>mdast-util-to-hast": { "globals": { - "define": true, - "setTimeout": true + "console.warn": true }, "packages": { - "browserify>timers-browserify": true - } - }, - "ethers>@ethersproject/keccak256": { - "packages": { - "@ethersproject/bytes": true, - "@metamask/ethjs>js-sha3": true + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, + "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/logger": { + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { "globals": { - "console": true + "Headers": true, + "TextDecoder": true, + "URL": true, + "btoa": true, + "fetch": true + }, + "packages": { + "browserify>browserify-zlib": true, + "browserify>buffer": true, + "https-browserify": true, + "process": true, + "stream-http": true, + "browserify>url": true, + "browserify>util": true } }, - "ethers>@ethersproject/pbkdf2": { + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/sha2": true + "react-syntax-highlighter>refractor>parse-entities": true } }, - "ethers>@ethersproject/properties": { + "crypto-browserify>diffie-hellman>miller-rabin": { "packages": { - "ethers>@ethersproject/logger": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true } }, - "ethers>@ethersproject/providers": { + "@ensdomains/content-hash>cids>multibase": { "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers>@ethersproject/networks": true, - "ethers>@ethersproject/providers>@ethersproject/web": true, - "ethers>@ethersproject/providers>bech32": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true + "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true } }, - "ethers>@ethersproject/providers>@ethersproject/networks": { + "@ensdomains/content-hash>multihashes>multibase": { "packages": { - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true, + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, + "@ensdomains/content-hash>multicodec": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@ensdomains/content-hash>multicodec>uint8arrays": true, + "sass-embedded>varint": true } }, - "ethers>@ethersproject/random": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "console.warn": true, + "crypto.subtle.digest": true } }, - "ethers>@ethersproject/rlp": { + "@ensdomains/content-hash>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>multibase": true, + "@ensdomains/content-hash>multihashes>varint": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/sha2": { + "@ensdomains/content-hash>cids>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2>hash.js": true + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>cids>uint8arrays": true, + "@ensdomains/content-hash>cids>multihashes>varint": true } }, - "ethers>@ethersproject/sha2>hash.js": { - "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/signing-key>elliptic": true + "@metamask/approval-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/solidity": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true + "@metamask/notification-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/strings": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true + "@metamask/permission-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/transactions": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/signing-key": true + "@metamask/rpc-methods>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/units": { - "packages": { - "@ethersproject/bignumber": true, - "ethers>@ethersproject/logger": true + "@metamask/rpc-methods-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/web": { + "@metamask/snaps-controllers>nanoid": { "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/wordlists": { - "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@metamask/snaps-controllers-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream": { - "packages": { - "browserify>buffer": true, - "extension-port-stream>readable-stream": true + "depcheck>@vue/compiler-sfc>postcss>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream": { + "dependency-tree>precinct>detective-postcss>postcss>nanoid": { "globals": { - "AbortController": true, - "AggregateError": true, - "Blob": true - }, - "packages": { - "browserify>buffer": true, - "browserify>string_decoder": true, - "extension-port-stream>readable-stream>abort-controller": true, - "process": true, - "webpack>events": true + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream>abort-controller": { + "node-fetch": { "globals": { - "AbortController": true + "Headers": true, + "Request": true, + "Response": true, + "fetch": true } }, - "fast-json-patch": { + "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true + "fetch": true } }, - "fuse.js": { + "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { "globals": { - "console": true, - "define": true + "fetch": true } }, - "ganache>secp256k1": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": { "packages": { - "@metamask/ppom-validator>elliptic": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true + } + }, + "string.prototype.matchall>es-abstract>object-inspect": { + "globals": { + "HTMLElement": true, + "WeakRef": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "@ngraveio/bc-ur>assert>object-is": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true } }, "gulp>vinyl-fs>object.assign": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>has-symbols": true + "string.prototype.matchall>has-symbols": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "he": { - "globals": { - "define": true + "@metamask/object-multiplex>once": { + "packages": { + "@metamask/object-multiplex>once>wrappy": true } }, - "history": { + "crypto-browserify>public-encrypt>parse-asn1": { + "packages": { + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "browserify>buffer": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "crypto-browserify>pbkdf2": true + } + }, + "react-syntax-highlighter>refractor>parse-entities": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true + "document.createElement": true } }, - "https-browserify": { + "path-browserify": { "packages": { - "browserify>url": true, - "stream-http": true + "process": true } }, - "koa>content-disposition>safe-buffer": { + "serve-handler>path-to-regexp": { "packages": { - "browserify>buffer": true + "serve-handler>path-to-regexp>isarray": true } }, - "koa>is-generator-function": { + "crypto-browserify>pbkdf2": { + "globals": { + "crypto": true, + "process": true, + "queueMicrotask": true, + "setImmediate": true, + "setTimeout": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash": true, + "process": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true } }, - "koa>is-generator-function>has-tostringtag": { - "packages": { - "string.prototype.matchall>has-symbols": true + "@material-ui/core>popper.js": { + "globals": { + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, + "console.warn": true, + "define": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator": true, + "requestAnimationFrame": true, + "setTimeout": true } }, - "localforage": { + "react-tippy>popper.js": { "globals": { - "Blob": true, - "BlobBuilder": true, - "FileReader": true, - "IDBKeyRange": true, - "MSBlobBuilder": true, - "MozBlobBuilder": true, - "OIndexedDB": true, - "WebKitBlobBuilder": true, - "atob": true, - "btoa": true, - "console.error": true, - "console.info": true, + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, "console.warn": true, "define": true, - "fetch": true, - "indexedDB": true, - "localStorage": true, - "mozIndexedDB": true, - "msIndexedDB": true, - "navigator.platform": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, "navigator.userAgent": true, - "openDatabase": true, - "setTimeout": true, - "webkitIndexedDB": true + "requestAnimationFrame": true, + "setTimeout": true } }, - "lodash": { + "process": { "globals": { "clearTimeout": true, - "define": true, "setTimeout": true } }, - "loglevel": { + "promise-to-callback": { + "packages": { + "promise-to-callback>is-fn": true, + "promise-to-callback>set-immediate-shim": true + } + }, + "prop-types": { "globals": { - "console": true, - "define": true, - "document.cookie": true, - "localStorage": true, - "log": "write", - "navigator": true + "console": true + }, + "packages": { + "react>object-assign": true, + "prop-types>react-is": true } }, - "lottie-web": { + "react-markdown>property-information": { + "packages": { + "watchify>xtend": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { "globals": { - "Blob": true, - "Howl": true, - "OffscreenCanvas": true, - "URL.createObjectURL": true, - "Worker": true, - "XMLHttpRequest": true, - "bodymovin": "write", - "clearInterval": true, - "console": true, - "define": true, - "document.body": true, - "document.createElement": true, - "document.createElementNS": true, - "document.getElementsByClassName": true, - "document.getElementsByTagName": true, - "document.querySelectorAll": true, - "document.readyState": true, - "location.origin": true, - "location.pathname": true, - "navigator": true, - "requestAnimationFrame": true, - "setInterval": true, + "process": true, "setTimeout": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true } }, - "luxon": { + "crypto-browserify>public-encrypt": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "crypto-browserify>randombytes": true + } + }, + "browserify>punycode": { "globals": { - "Intl": true + "define": true } }, - "nanoid": { + "qrcode-generator": { "globals": { - "crypto.getRandomValues": true + "define": true } }, - "nock>debug": { + "qrcode.react": { "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "Path2D": true, + "devicePixelRatio": true }, "packages": { - "nock>debug>ms": true, - "process": true - } - }, - "node-fetch": { - "globals": { - "Headers": true, - "Request": true, - "Response": true, - "fetch": true + "react": true } }, - "path-browserify": { + "@storybook/addon-knobs>qs": { "packages": { - "process": true + "string.prototype.matchall>side-channel": true } }, - "process": { + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { "globals": { - "clearTimeout": true, - "setTimeout": true - } - }, - "promise-to-callback": { - "packages": { - "promise-to-callback>is-fn": true, - "promise-to-callback>set-immediate-shim": true + "queueMicrotask": true } }, - "promise-to-callback>set-immediate-shim": { + "react-beautiful-dnd>raf-schd": { "globals": { - "setTimeout.apply": true - }, - "packages": { - "browserify>timers-browserify": true + "cancelAnimationFrame": true, + "requestAnimationFrame": true } }, - "prop-types": { + "crypto-browserify>randombytes": { "globals": { - "console": true + "crypto": true, + "msCrypto": true }, "packages": { - "prop-types>react-is": true, - "react>object-assign": true - } - }, - "prop-types>react-is": { - "globals": { - "console": true + "process": true, + "koa>content-disposition>safe-buffer": true } }, - "qrcode-generator": { + "ethereumjs-wallet>randombytes": { "globals": { - "define": true + "crypto.getRandomValues": true } }, - "qrcode.react": { + "crypto-browserify>randomfill": { "globals": { - "Path2D": true, - "devicePixelRatio": true + "crypto": true, + "msCrypto": true }, "packages": { - "react": true + "process": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true } }, "react": { @@ -4641,8 +4844,8 @@ "console": true }, "packages": { - "prop-types": true, - "react>object-assign": true + "react>object-assign": true, + "prop-types": true } }, "react-beautiful-dnd": { @@ -4664,43 +4867,28 @@ }, "packages": { "@babel/runtime": true, - "react": true, "react-beautiful-dnd>css-box-model": true, "react-beautiful-dnd>memoize-one": true, "react-beautiful-dnd>raf-schd": true, - "react-beautiful-dnd>use-memo-one": true, + "react": true, "react-dom": true, "react-redux": true, - "redux": true + "redux": true, + "react-beautiful-dnd>use-memo-one": true } }, - "react-beautiful-dnd>css-box-model": { + "react-chartjs-2": { "globals": { - "getComputedStyle": true, - "pageXOffset": true, - "pageYOffset": true + "setTimeout": true }, "packages": { - "react-router-dom>tiny-invariant": true - } - }, - "react-beautiful-dnd>raf-schd": { - "globals": { - "cancelAnimationFrame": true, - "requestAnimationFrame": true - } - }, - "react-beautiful-dnd>use-memo-one": { - "packages": { + "chart.js": true, "react": true } }, - "react-chartjs-2": { - "globals": { - "setTimeout": true - }, + "react-focus-lock>react-clientside-effect": { "packages": { - "chart.js": true, + "@babel/runtime": true, "react": true } }, @@ -4745,22 +4933,28 @@ "trustedTypes": true }, "packages": { + "react>object-assign": true, "prop-types": true, "react": true, - "react-dom>scheduler": true, - "react>object-assign": true + "react-dom>scheduler": true } }, - "react-dom>scheduler": { + "react-responsive-carousel>react-easy-swipe": { "globals": { - "MessageChannel": true, - "cancelAnimationFrame": true, - "clearTimeout": true, - "console": true, - "navigator": true, - "performance": true, - "requestAnimationFrame": true, - "setTimeout": true + "addEventListener": true, + "define": true, + "document.addEventListener": true, + "document.removeEventListener": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-popper>react-fast-compare": { + "globals": { + "Element": true, + "console.warn": true } }, "react-focus-lock": { @@ -4774,667 +4968,726 @@ }, "packages": { "@babel/runtime": true, + "react-focus-lock>focus-lock": true, "prop-types": true, "react": true, - "react-focus-lock>focus-lock": true, "react-focus-lock>react-clientside-effect": true, "react-focus-lock>use-callback-ref": true, "react-focus-lock>use-sidecar": true } }, - "react-focus-lock>focus-lock": { + "react-idle-timer": { "globals": { - "HTMLIFrameElement": true, - "Node.DOCUMENT_FRAGMENT_NODE": true, - "Node.DOCUMENT_NODE": true, - "Node.DOCUMENT_POSITION_CONTAINED_BY": true, - "Node.DOCUMENT_POSITION_CONTAINS": true, - "Node.ELEMENT_NODE": true, - "console.error": true, + "clearTimeout": true, + "document": true, + "setTimeout": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-inspector": { + "globals": { + "Node": true, + "chromeDark": true, + "chromeLight": true + }, + "packages": { + "react": true + } + }, + "prop-types>react-is": { + "globals": { + "console": true + } + }, + "react-markdown>react-is": { + "globals": { + "console": true + } + }, + "react-redux>react-is": { + "globals": { + "console": true + } + }, + "react-markdown": { + "globals": { + "console.warn": true + }, + "packages": { + "react-markdown>comma-separated-tokens": true, + "prop-types": true, + "react-markdown>property-information": true, + "react": true, + "react-markdown>react-is": true, + "react-markdown>remark-parse": true, + "react-markdown>remark-rehype": true, + "react-markdown>space-separated-tokens": true, + "react-markdown>style-to-object": true, + "react-markdown>unified": true, + "react-markdown>unist-util-visit": true, + "react-markdown>vfile": true + } + }, + "react-popper": { + "globals": { + "document": true + }, + "packages": { + "@popperjs/core": true, + "react": true, + "react-popper>react-fast-compare": true, + "react-popper>warning": true + } + }, + "react-redux": { + "globals": { + "console": true, + "document": true + }, + "packages": { + "@babel/runtime": true, + "react-redux>hoist-non-react-statics": true, + "prop-types": true, + "react": true, + "react-dom": true, + "react-redux>react-is": true + } + }, + "react-responsive-carousel": { + "globals": { + "HTMLElement": true, + "addEventListener": true, + "clearTimeout": true, "console.warn": true, "document": true, - "getComputedStyle": true, + "getComputedStyle": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "classnames": true, + "react": true, + "react-dom": true, + "react-responsive-carousel>react-easy-swipe": true + } + }, + "react-router-dom": { + "packages": { + "react-router-dom>history": true, + "prop-types": true, + "react": true, + "react-router-dom>react-router": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true + } + }, + "react-router-dom-v5-compat": { + "globals": { + "FormData": true, + "URL": true, + "URLSearchParams": true, + "__reactRouterVersion": "write", + "addEventListener": true, + "confirm": true, + "define": true, + "document": true, + "history.scrollRestoration": true, + "location.href": true, + "removeEventListener": true, + "scrollTo": true, + "scrollY": true, + "sessionStorage.getItem": true, + "sessionStorage.setItem": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true + "react-router-dom-v5-compat>@remix-run/router": true, + "history": true, + "react": true, + "react-dom": true, + "react-router-dom": true, + "react-router-dom-v5-compat>react-router": true } }, - "react-focus-lock>react-clientside-effect": { + "react-router-dom>react-router": { "packages": { - "@babel/runtime": true, - "react": true + "react-router-dom>history": true, + "react-redux>hoist-non-react-statics": true, + "serve-handler>path-to-regexp": true, + "prop-types": true, + "react": true, + "prop-types>react-is": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true } }, - "react-focus-lock>use-callback-ref": { + "react-router-dom-v5-compat>react-router": { + "globals": { + "console.error": true, + "define": true + }, "packages": { + "react-router-dom-v5-compat>@remix-run/router": true, "react": true } }, - "react-focus-lock>use-sidecar": { + "react-simple-file-input": { "globals": { - "console.error": true + "File": true, + "FileReader": true, + "console.warn": true }, "packages": { - "@swc/helpers>tslib": true, - "react": true, - "react-focus-lock>use-sidecar>detect-node-es": true + "prop-types": true, + "react": true } }, - "react-idle-timer": { + "react-tippy": { "globals": { + "Element": true, + "MSStream": true, + "MutationObserver": true, + "addEventListener": true, "clearTimeout": true, + "console.error": true, + "console.warn": true, + "define": true, "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator.maxTouchPoints": true, + "navigator.msMaxTouchPoints": true, + "navigator.userAgent": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "react-tippy>popper.js": true, + "react": true, + "react-dom": true } }, - "react-inspector": { + "react-toggle-button": { "globals": { - "Node": true, - "chromeDark": true, - "chromeLight": true + "clearTimeout": true, + "console.warn": true, + "define": true, + "performance": true, + "setTimeout": true }, "packages": { "react": true } }, - "react-markdown": { + "@material-ui/core>react-transition-group": { "globals": { - "console.warn": true + "Element": true, + "setTimeout": true }, "packages": { + "@material-ui/core>react-transition-group>dom-helpers": true, "prop-types": true, "react": true, - "react-markdown>comma-separated-tokens": true, - "react-markdown>property-information": true, - "react-markdown>react-is": true, - "react-markdown>remark-parse": true, - "react-markdown>remark-rehype": true, - "react-markdown>space-separated-tokens": true, - "react-markdown>style-to-object": true, - "react-markdown>unified": true, - "react-markdown>unist-util-visit": true, - "react-markdown>vfile": true + "react-dom": true } }, - "react-markdown>property-information": { + "readable-stream": { "packages": { - "watchify>xtend": true + "browserify>browser-resolve": true, + "browserify>buffer": true, + "webpack>events": true, + "pumpify>inherits": true, + "process": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true } }, - "react-markdown>react-is": { + "extension-port-stream>readable-stream": { "globals": { - "console": true - } - }, - "react-markdown>remark-parse": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, - "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true, - "react-syntax-highlighter>refractor>parse-entities": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "queueMicrotask": true + }, "packages": { - "react-syntax-highlighter>refractor>parse-entities": true + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "browserify>buffer": true, + "webpack>events": true, + "process": true, + "browserify>string_decoder": true } }, - "react-markdown>remark-rehype": { + "@metamask/snaps-controllers>readable-web-to-node-stream": { "packages": { - "react-markdown>remark-rehype>mdast-util-to-hast": true + "readable-stream": true } }, - "react-markdown>remark-rehype>mdast-util-to-hast": { + "redux": { "globals": { - "console.warn": true + "console": true }, "packages": { - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, - "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, - "react-markdown>unist-util-visit": true + "@babel/runtime": true } }, - "react-markdown>style-to-object": { + "string.prototype.matchall>regexp.prototype.flags": { "packages": { - "react-markdown>style-to-object>inline-style-parser": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": true } }, - "react-markdown>unified": { + "react-markdown>remark-parse": { "packages": { - "mocha>yargs-unparser>is-plain-obj": true, - "react-markdown>unified>bail": true, - "react-markdown>unified>extend": true, - "react-markdown>unified>is-buffer": true, - "react-markdown>unified>trough": true, - "react-markdown>vfile": true + "react-markdown>remark-parse>mdast-util-from-markdown": true } }, - "react-markdown>unist-util-visit": { + "react-markdown>remark-rehype": { "packages": { - "react-markdown>unist-util-visit>unist-util-visit-parents": true + "react-markdown>remark-rehype>mdast-util-to-hast": true } }, - "react-markdown>unist-util-visit>unist-util-visit-parents": { + "react-markdown>vfile>replace-ext": { "packages": { - "react-markdown>unist-util-visit>unist-util-is": true + "path-browserify": true } }, - "react-markdown>vfile": { - "packages": { - "path-browserify": true, - "process": true, - "react-markdown>vfile>is-buffer": true, - "react-markdown>vfile>replace-ext": true, - "react-markdown>vfile>vfile-message": true + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true } }, - "react-markdown>vfile>replace-ext": { + "@metamask/snaps-utils>rfdc": { "packages": { - "path-browserify": true + "browserify>buffer": true } }, - "react-markdown>vfile>vfile-message": { + "ethereumjs-util>create-hash>ripemd160": { "packages": { - "react-markdown>vfile>unist-util-stringify-position": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true } }, - "react-popper": { - "globals": { - "document": true - }, + "@keystonehq/metamask-airgapped-keyring>rlp": { "packages": { - "@popperjs/core": true, - "react": true, - "react-popper>react-fast-compare": true, - "react-popper>warning": true - } - }, - "react-popper>react-fast-compare": { - "globals": { - "Element": true, - "console.warn": true + "bn.js": true, + "browserify>buffer": true } }, - "react-popper>warning": { + "eth-lattice-keyring>rlp": { "globals": { - "console": true + "TextEncoder": true } }, - "react-redux": { - "globals": { - "console": true, - "document": true - }, + "ethereumjs-util>rlp": { "packages": { - "@babel/runtime": true, - "prop-types": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true, - "react-redux>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>hoist-non-react-statics": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { "packages": { - "prop-types>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>react-is": { + "wait-on>rxjs": { "globals": { - "console": true + "cancelAnimationFrame": true, + "clearInterval": true, + "clearTimeout": true, + "performance": true, + "requestAnimationFrame": true, + "setInterval.apply": true, + "setTimeout.apply": true } }, - "react-responsive-carousel": { + "koa>content-disposition>safe-buffer": { + "packages": { + "browserify>buffer": true + } + }, + "react-dom>scheduler": { "globals": { - "HTMLElement": true, - "addEventListener": true, + "MessageChannel": true, + "cancelAnimationFrame": true, "clearTimeout": true, - "console.warn": true, - "document": true, - "getComputedStyle": true, - "removeEventListener": true, + "console": true, + "navigator": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true - }, - "packages": { - "classnames": true, - "react": true, - "react-dom": true, - "react-responsive-carousel>react-easy-swipe": true } }, - "react-responsive-carousel>react-easy-swipe": { + "ethers>@ethersproject/json-wallets>scrypt-js": { "globals": { - "addEventListener": true, "define": true, - "document.addEventListener": true, - "document.removeEventListener": true + "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "browserify>timers-browserify": true } }, - "react-router-dom": { + "ganache>secp256k1": { "packages": { - "prop-types": true, - "react": true, - "react-router-dom>history": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "@metamask/ppom-validator>elliptic": true } }, - "react-router-dom-v5-compat": { + "semver": { "globals": { - "FormData": true, - "URL": true, - "URLSearchParams": true, - "__reactRouterVersion": "write", - "addEventListener": true, - "confirm": true, - "define": true, - "document": true, - "history.scrollRestoration": true, - "location.href": true, - "removeEventListener": true, - "scrollTo": true, - "scrollY": true, - "sessionStorage.getItem": true, - "sessionStorage.setItem": true, - "setTimeout": true + "console.error": true }, "packages": { - "history": true, - "react": true, - "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>@remix-run/router": true, - "react-router-dom-v5-compat>react-router": true + "process": true } }, - "react-router-dom-v5-compat>@remix-run/router": { - "globals": { - "AbortController": true, - "DOMException": true, - "FormData": true, - "Headers": true, - "Request": true, - "Response": true, - "URL": true, - "URLSearchParams": true, - "console": true, - "document.defaultView": true + "string.prototype.matchall>call-bind>set-function-length": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom-v5-compat>react-router": { - "globals": { - "console.error": true, - "define": true - }, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": { "packages": { - "react": true, - "react-router-dom-v5-compat>@remix-run/router": true + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom>history": { + "promise-to-callback>set-immediate-shim": { "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true + "setTimeout.apply": true }, "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>history>value-equal": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "browserify>timers-browserify": true } }, - "react-router-dom>react-router": { + "addons-linter>sha.js": { "packages": { - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-redux>hoist-non-react-statics": true, - "react-router-dom>history": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "serve-handler>path-to-regexp": true + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "react-router-dom>tiny-warning": { - "globals": { - "console": true + "string.prototype.matchall>side-channel": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>object-inspect": true } }, - "react-simple-file-input": { + "@metamask/profile-sync-controller>siwe": { "globals": { - "File": true, - "FileReader": true, + "console.error": true, "console.warn": true }, "packages": { - "prop-types": true, - "react": true + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random": true, + "ethers": true, + "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true } }, - "react-syntax-highlighter>refractor>parse-entities": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { "globals": { - "document.createElement": true + "StopIteration": true + }, + "packages": { + "string.prototype.matchall>internal-slot": true } }, - "react-tippy": { + "stream-browserify": { + "packages": { + "webpack>events": true, + "pumpify>inherits": true, + "readable-stream": true + } + }, + "stream-http": { "globals": { - "Element": true, - "MSStream": true, - "MutationObserver": true, - "addEventListener": true, + "AbortController": true, + "Blob": true, + "MSStreamReader": true, + "ReadableStream": true, + "WritableStream": true, + "XDomainRequest": true, + "XMLHttpRequest": true, "clearTimeout": true, - "console.error": true, - "console.warn": true, - "define": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.maxTouchPoints": true, - "navigator.msMaxTouchPoints": true, - "navigator.userAgent": true, - "performance": true, - "requestAnimationFrame": true, + "fetch": true, + "location.protocol.search": true, "setTimeout": true }, "packages": { - "react": true, - "react-dom": true, - "react-tippy>popper.js": true + "browserify>buffer": true, + "stream-http>builtin-status-codes": true, + "pumpify>inherits": true, + "process": true, + "readable-stream": true, + "browserify>url": true, + "watchify>xtend": true } }, - "react-tippy>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.userAgent": true, - "requestAnimationFrame": true, - "setTimeout": true + "@metamask/snaps-controllers>tar-stream>streamx": { + "packages": { + "webpack>events": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true } }, - "react-toggle-button": { - "globals": { - "clearTimeout": true, - "console.warn": true, - "define": true, - "performance": true, - "setTimeout": true - }, + "browserify>string_decoder": { "packages": { - "react": true + "koa>content-disposition>safe-buffer": true } }, - "readable-stream": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": { "packages": { - "browserify>browser-resolve": true, - "browserify>buffer": true, - "browserify>string_decoder": true, - "process": true, - "pumpify>inherits": true, - "readable-stream>util-deprecate": true, - "webpack>events": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true } }, - "readable-stream>util-deprecate": { - "globals": { - "console.trace": true, - "console.warn": true, - "localStorage": true + "react-markdown>style-to-object": { + "packages": { + "react-markdown>style-to-object>inline-style-parser": true } }, - "redux": { - "globals": { - "console": true - }, + "@metamask/snaps-controllers>tar-stream": { "packages": { - "@babel/runtime": true + "@metamask/snaps-controllers>tar-stream>b4a": true, + "browserify>browser-resolve": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx": true } }, - "reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true + "debounce-stream>through": { + "packages": { + "process": true, + "stream-browserify": true } }, - "semver": { + "browserify>timers-browserify": { "globals": { - "console.error": true + "clearInterval": true, + "clearTimeout": true, + "setInterval": true, + "setTimeout": true }, "packages": { "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true + "react-router-dom>tiny-warning": { + "globals": { + "console": true } }, - "stream-browserify": { - "packages": { - "pumpify>inherits": true, - "readable-stream": true, - "webpack>events": true + "copy-to-clipboard>toggle-selection": { + "globals": { + "document.activeElement": true, + "document.getSelection": true + } + }, + "tslib": { + "globals": { + "SuppressedError": true, + "define": true } }, - "stream-http": { + "@metamask/eth-sig-util>tweetnacl": { "globals": { - "AbortController": true, - "Blob": true, - "MSStreamReader": true, - "ReadableStream": true, - "WritableStream": true, - "XDomainRequest": true, - "XMLHttpRequest": true, - "clearTimeout": true, - "fetch": true, - "location.protocol.search": true, - "setTimeout": true + "crypto": true, + "msCrypto": true, + "nacl": "write" }, "packages": { - "browserify>buffer": true, - "browserify>url": true, - "process": true, - "pumpify>inherits": true, - "readable-stream": true, - "stream-http>builtin-status-codes": true, - "watchify>xtend": true + "browserify>browser-resolve": true } }, - "string.prototype.matchall>call-bind": { - "packages": { - "browserify>has>function-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>call-bind>set-function-length": true, - "string.prototype.matchall>get-intrinsic": true + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>call-bind>es-define-property": { + "@ensdomains/content-hash>cids>uint8arrays": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>cids>multibase": true } }, - "string.prototype.matchall>call-bind>set-function-length": { + "@ensdomains/content-hash>multicodec>uint8arrays": { + "globals": { + "Buffer": true, + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "string.prototype.matchall>define-properties": { + "react-markdown>unified": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "react-markdown>unified>bail": true, + "react-markdown>unified>extend": true, + "react-markdown>unified>is-buffer": true, + "mocha>yargs-unparser>is-plain-obj": true, + "react-markdown>unified>trough": true, + "react-markdown>vfile": true } }, - "string.prototype.matchall>define-properties>define-data-property": { + "react-markdown>unist-util-visit>unist-util-visit-parents": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "react-markdown>unist-util-visit>unist-util-is": true } }, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "react-markdown>unist-util-visit": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true + "react-markdown>unist-util-visit>unist-util-visit-parents": true } }, - "string.prototype.matchall>es-abstract>available-typed-arrays": { - "packages": { - "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true + "uri-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "browserify>url": { "packages": { - "string.prototype.matchall>has-symbols": true + "browserify>punycode": true, + "@storybook/addon-knobs>qs": true } }, - "string.prototype.matchall>es-abstract>gopd": { + "react-focus-lock>use-callback-ref": { "packages": { - "string.prototype.matchall>get-intrinsic": true + "react": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "react-beautiful-dnd>use-memo-one": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true + "react": true } }, - "string.prototype.matchall>es-abstract>is-array-buffer": { + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "react-focus-lock>use-sidecar>detect-node-es": true, + "react": true, + "tslib": true } }, - "string.prototype.matchall>es-abstract>is-callable": { + "readable-stream>util-deprecate": { "globals": { - "document": true + "console.trace": true, + "console.warn": true, + "localStorage": true } }, - "string.prototype.matchall>es-abstract>is-regex": { + "browserify>assert>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true, + "process": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "browserify>assert>util>inherits": true, + "process": true } }, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": { + "browserify>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true + }, "packages": { - "string.prototype.matchall>call-bind": true + "pumpify>inherits": true, + "browserify>util>is-arguments": true, + "koa>is-generator-function": true, + "browserify>util>is-typed-array": true, + "process": true, + "browserify>util>which-typed-array": true } }, - "string.prototype.matchall>es-abstract>object-inspect": { + "uuid": { "globals": { - "HTMLElement": true, - "WeakRef": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "msCrypto": true } }, - "string.prototype.matchall>get-intrinsic": { + "@metamask/eth-snap-keyring>uuid": { "globals": { - "AggregateError": true, - "FinalizationRegistry": true, - "WeakRef": true - }, - "packages": { - "browserify>has>function-bind": true, - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true + "crypto": true } }, - "string.prototype.matchall>internal-slot": { - "packages": { - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>side-channel": true + "@metamask/keyring-snap-client>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eth-lattice-keyring>gridplus-sdk>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "web3-stream-provider>uuid": { + "globals": { + "crypto": true + } + }, + "@metamask/snaps-utils>validate-npm-package-name": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "@metamask/snaps-utils>validate-npm-package-name>builtins": true } }, - "string.prototype.matchall>side-channel": { + "react-markdown>vfile>vfile-message": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>get-intrinsic": true + "react-markdown>vfile>unist-util-stringify-position": true } }, - "terser>source-map-support>buffer-from": { + "react-markdown>vfile": { "packages": { - "browserify>buffer": true + "react-markdown>vfile>is-buffer": true, + "path-browserify": true, + "process": true, + "react-markdown>vfile>replace-ext": true, + "react-markdown>vfile>vfile-message": true } }, - "uri-js": { + "browserify>vm-browserify": { "globals": { - "define": true + "document.body.appendChild": true, + "document.body.removeChild": true, + "document.createElement": true } }, - "uuid": { + "react-popper>warning": { "globals": { - "crypto": true, - "msCrypto": true + "console": true } }, - "wait-on>rxjs": { + "@ensdomains/content-hash>multihashes>web-encoding": { "globals": { - "cancelAnimationFrame": true, - "clearInterval": true, - "clearTimeout": true, - "performance": true, - "requestAnimationFrame": true, - "setInterval.apply": true, - "setTimeout.apply": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>util": true } }, "web3": { @@ -5447,14 +5700,14 @@ "setTimeout": true }, "packages": { - "browserify>util": true, "readable-stream": true, + "browserify>util": true, "web3-stream-provider>uuid": true } }, - "web3-stream-provider>uuid": { + "@metamask/controllers>web3": { "globals": { - "crypto": true + "XMLHttpRequest": true } }, "webextension-polyfill": { @@ -5466,9 +5719,30 @@ "define": true } }, - "webpack>events": { - "globals": { - "console": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, + "eslint-plugin-react>array-includes>is-string": true, + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-collection": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + } + }, + "browserify>util>which-typed-array": { + "packages": { + "string.prototype.matchall>es-abstract>available-typed-arrays": true, + "string.prototype.matchall>call-bind": true, + "browserify>util>which-typed-array>for-each": true, + "string.prototype.matchall>es-abstract>gopd": true, + "koa>is-generator-function>has-tostringtag": true } } } diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index ddd92183c786..7a6974a03193 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -5,144 +5,124 @@ "regeneratorRuntime": "write" } }, - "@ensdomains/content-hash": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { "globals": { - "console.warn": true + "WeakRef": true }, "packages": { - "@ensdomains/content-hash>cids": true, - "@ensdomains/content-hash>js-base64": true, - "@ensdomains/content-hash>multicodec": true, - "@ensdomains/content-hash>multihashes": true, - "browserify>buffer": true + "browserify": true } }, - "@ensdomains/content-hash>cids": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes": true, - "@ensdomains/content-hash>cids>uint8arrays": true, - "@ensdomains/content-hash>multicodec": true + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, + "browserify": true, + "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true } }, - "@ensdomains/content-hash>cids>multibase": { + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "SuppressedError": true + } + }, + "@ensdomains/content-hash": { + "globals": { + "console.warn": true }, "packages": { - "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true + "browserify>buffer": true, + "@ensdomains/content-hash>cids": true, + "@ensdomains/content-hash>js-base64": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>multihashes": true } }, - "@ensdomains/content-hash>cids>multihashes": { + "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes>varint": true, - "@ensdomains/content-hash>cids>uint8arrays": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>cids>uint8arrays": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "webpack>events": true } }, - "@ensdomains/content-hash>js-base64": { - "globals": { - "Base64": "write", - "TextDecoder": true, - "TextEncoder": true, - "atob": true, - "btoa": true, - "define": true - }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "browserify>buffer": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays": true, - "sass-embedded>varint": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays": { + "@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "Buffer": true, - "TextDecoder": true, "TextEncoder": true - }, - "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "console.warn": true, - "crypto.subtle.digest": true - } - }, - "@ensdomains/content-hash>multihashes": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase": true, - "@ensdomains/content-hash>multihashes>varint": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase>base-x": { + "@ethereumjs/tx": { "packages": { - "koa>content-disposition>safe-buffer": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, - "@ensdomains/content-hash>multihashes>web-encoding": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx": { "packages": { - "browserify>util": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@ethereumjs/tx": { + "eth-lattice-keyring>@ethereumjs/tx": { "packages": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, + "@ethersproject/providers": true, "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@ethereumjs/tx>@ethereumjs/common": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/providers": true, "browserify>buffer": true, - "webpack>events": true - } - }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { - "globals": { - "DO_NOT_EXPORT_CRC": true, - "define": true - } - }, - "@ethereumjs/tx>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "@ethereumjs/tx>@ethereumjs/util": { @@ -151,78 +131,83 @@ }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true, - "@ethereumjs/tx>ethereum-cryptography": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "webpack>events": true + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "@metamask/smart-transactions-controller>@ethereumjs/util": { "globals": { - "Headers": true, - "TextDecoder": true, - "URL": true, - "btoa": true, + "console.warn": true, "fetch": true }, "packages": { - "browserify>browserify-zlib": true, - "browserify>buffer": true, - "browserify>url": true, - "browserify>util": true, - "https-browserify": true, - "process": true, - "stream-http": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, - "@ethereumjs/tx>ethereum-cryptography": { + "@ethersproject/abi": { "globals": { - "TextDecoder": true, - "crypto": true + "console.log": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true, - "@noble/hashes": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { - "globals": { - "TextEncoder": true - }, + "ethers>@ethersproject/abstract-provider": { "packages": { - "@noble/hashes": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "ethers>@ethersproject/abstract-signer": { "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethersproject/abi": { - "globals": { - "console.log": true - }, + "ethers>@ethersproject/address": { "packages": { "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/rlp": true + } + }, + "ethers>@ethersproject/base64": { + "globals": { + "atob": true, + "btoa": true + }, + "packages": { + "@ethersproject/bytes": true + } + }, + "ethers>@ethersproject/basex": { + "packages": { + "@ethersproject/bytes": true, + "ethers>@ethersproject/properties": true } }, "@ethersproject/bignumber": { "packages": { "@ethersproject/bytes": true, - "bn.js": true, - "ethers>@ethersproject/logger": true + "ethers>@ethersproject/logger": true, + "bn.js": true } }, "@ethersproject/bytes": { @@ -230,17 +215,22 @@ "ethers>@ethersproject/logger": true } }, + "ethers>@ethersproject/constants": { + "packages": { + "@ethersproject/bignumber": true + } + }, "@ethersproject/contracts": { "globals": { "setTimeout": true }, "packages": { "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/abstract-provider": true, "ethers>@ethersproject/abstract-signer": true, "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/transactions": true @@ -248,10 +238,10 @@ }, "@ethersproject/hash": { "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/address": true, "ethers>@ethersproject/base64": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, @@ -260,9 +250,9 @@ }, "@ethersproject/hdnode": { "packages": { + "ethers>@ethersproject/basex": true, "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "ethers>@ethersproject/basex": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, @@ -273,1692 +263,1236 @@ "ethers>@ethersproject/wordlists": true } }, - "@ethersproject/providers": { - "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/json-wallets": { "packages": { - "@ethersproject/bignumber": true, + "ethers>@ethersproject/address": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/providers>bech32": true, - "@metamask/test-bundler>@ethersproject/networks": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "@ethersproject/providers>@ethersproject/random": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/json-wallets>aes-js": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true } }, - "@ethersproject/wallet": { + "ethers>@ethersproject/keccak256": { "packages": { "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/transactions": true + "eth-ens-namehash>js-sha3": true } }, - "@keystonehq/bc-ur-registry-eth": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "uuid": true + "ethers>@ethersproject/logger": { + "globals": { + "console": true } }, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { - "globals": { - "define": true - }, + "ethers>@ethersproject/providers>@ethersproject/networks": { "packages": { - "@ngraveio/bc-ur": true, - "@swc/helpers>tslib": true, - "browserify>buffer": true, - "buffer": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring": { + "@metamask/test-bundler>@ethersproject/networks": { "packages": { - "@ethereumjs/tx": true, - "@keystonehq/bc-ur-registry-eth": true, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, - "@keystonehq/metamask-airgapped-keyring>rlp": true, - "@metamask/obs-store": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { + "ethers>@ethersproject/pbkdf2": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "eth-lattice-keyring>rlp": true, - "uuid": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/sha2": true } }, - "@keystonehq/metamask-airgapped-keyring>rlp": { + "ethers>@ethersproject/properties": { "packages": { - "bn.js": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@lavamoat/lavadome-react": { + "@ethersproject/providers": { "globals": { - "Document.prototype": true, - "DocumentFragment.prototype": true, - "Element.prototype": true, - "Node.prototype": true, + "WebSocket": true, + "clearInterval": true, + "clearTimeout": true, + "console.log": true, "console.warn": true, - "document": true + "setInterval": true, + "setTimeout": true }, "packages": { - "react": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "@metamask/test-bundler>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "@ethersproject/providers>@ethersproject/web": true, + "@ethersproject/providers>bech32": true } }, - "@material-ui/core": { + "ethers>@ethersproject/providers": { "globals": { - "Image": true, - "_formatMuiErrorMessage": true, - "addEventListener": true, + "WebSocket": true, "clearInterval": true, "clearTimeout": true, - "console.error": true, + "console.log": true, "console.warn": true, - "document": true, - "getComputedStyle": true, - "getSelection": true, - "innerHeight": true, - "innerWidth": true, - "matchMedia": true, - "navigator": true, - "performance.now": true, - "removeEventListener": true, - "requestAnimationFrame": true, "setInterval": true, "setTimeout": true }, "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles": true, - "@material-ui/core>@material-ui/system": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "@material-ui/core>popper.js": true, - "@material-ui/core>react-transition-group": true, - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/providers>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/providers>@ethersproject/web": true, + "ethers>@ethersproject/providers>bech32": true } }, - "@material-ui/core>@material-ui/styles": { + "@ethersproject/providers>@ethersproject/random": { "globals": { - "console.error": true, - "console.warn": true, - "document.createComment": true, - "document.head": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, - "@material-ui/core>@material-ui/styles>jss-plugin-global": true, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, - "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "prop-types": true, - "react": true, - "react-redux>hoist-non-react-statics": true + "crypto.getRandomValues": true } }, - "@material-ui/core>@material-ui/styles>jss": { - "globals": { - "CSS": true, - "document.createElement": true, - "document.querySelector": true - }, + "ethers>@ethersproject/random": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { + "ethers>@ethersproject/rlp": { "packages": { - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { - "globals": { - "CSS": true - }, + "ethers>@ethersproject/sha2": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2>hash.js": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-global": { + "ethers>@ethersproject/signing-key": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/signing-key>elliptic": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": { + "ethers>@ethersproject/solidity": { "packages": { - "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { + "ethers>@ethersproject/strings": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { + "ethers>@ethersproject/transactions": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/signing-key": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { - "globals": { - "document.createElement": true, - "document.documentElement": true, - "getComputedStyle": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true - } - }, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": { - "globals": { - "document": true - } - }, - "@material-ui/core>@material-ui/system": { - "globals": { - "console.error": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/utils": true, - "prop-types": true - } - }, - "@material-ui/core>@material-ui/utils": { - "packages": { - "@babel/runtime": true, - "prop-types": true, - "prop-types>react-is": true - } - }, - "@material-ui/core>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator": true, - "requestAnimationFrame": true, - "setTimeout": true - } - }, - "@material-ui/core>react-transition-group": { - "globals": { - "Element": true, - "setTimeout": true - }, - "packages": { - "@material-ui/core>react-transition-group>dom-helpers": true, - "prop-types": true, - "react": true, - "react-dom": true - } - }, - "@material-ui/core>react-transition-group>dom-helpers": { - "packages": { - "@babel/runtime": true - } - }, - "@metamask/abi-utils": { - "packages": { - "@metamask/abi-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true - } - }, - "@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/accounts-controller": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/base-controller": true, - "@metamask/eth-snap-keyring": true, - "@metamask/keyring-api": true, - "@metamask/keyring-controller": true, - "@metamask/utils": true, - "uuid": true - } - }, - "@metamask/address-book-controller": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true - } - }, - "@metamask/announcement-controller": { - "packages": { - "@metamask/announcement-controller>@metamask/base-controller": true - } - }, - "@metamask/announcement-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/approval-controller": { - "globals": { - "console.info": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/rpc-errors": true, - "nanoid": true - } - }, - "@metamask/approval-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/assets-controllers": { - "globals": { - "AbortController": true, - "Headers": true, - "URL": true, - "URLSearchParams": true, - "clearInterval": true, - "clearTimeout": true, - "console.error": true, - "console.log": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/units": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, - "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/bignumber": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/abi-utils": true, - "@metamask/base-controller": true, - "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "bn.js": true, - "cockatiel": true, - "ethers>@ethersproject/address": true, - "lodash": true, - "single-call-balance-checker-abi": true, - "uuid": true - } - }, - "@metamask/base-controller": { - "globals": { - "setTimeout": true - }, - "packages": { - "immer": true - } - }, - "@metamask/browser-passworder": { - "globals": { - "CryptoKey": true, - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, - "packages": { - "@metamask/browser-passworder>@metamask/utils": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@metamask/browser-passworder>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@ethersproject/wallet": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/transactions": true } }, - "@metamask/controller-utils": { + "@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, "fetch": true, "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/controller-utils>@spruceid/siwe-parser": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/utils": true, - "bn.js": true, - "browserify>buffer": true, - "eslint>fast-deep-equal": true, - "eth-ens-namehash": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser": { - "globals": { - "console.error": true, - "console.log": true - }, - "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true - } - }, - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/controllers>web3": { - "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { - "globals": { - "fetch": true - } - }, - "@metamask/ens-controller": { - "packages": { - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "punycode": true - } - }, - "@metamask/eth-json-rpc-filters": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/safe-event-emitter": true, - "pify": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-json-rpc-middleware": { + "ethers>@ethersproject/providers>@ethersproject/web": { "globals": { - "URL": true, - "console.error": true, + "clearTimeout": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, - "@metamask/eth-json-rpc-middleware>klona": true, - "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-sig-util": true, - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true - } - }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-json-rpc-provider": { - "packages": { - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true, - "uuid": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring": { + "ethers>@ethersproject/web": { "globals": { - "addEventListener": true, - "console.error": true, - "document.createElement": true, - "document.head.appendChild": true, + "clearTimeout": true, "fetch": true, - "removeEventListener": true + "setTimeout": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, - "@metamask/eth-sig-util": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "webpack>events": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "ethers>@ethersproject/wordlists": { + "packages": { + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { + "@metamask/notification-services-controller>firebase>@firebase/app": { "globals": { + "FinalizationRegistry": true, "console.warn": true }, "packages": { - "@ethersproject/abi": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, - "browserify>buffer": true, - "ethers>@ethersproject/rlp": true, - "semver": true + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true + "@metamask/notification-services-controller>firebase>@firebase/util": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { + "@metamask/notification-services-controller>firebase>@firebase/installations": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "BroadcastChannel": true, + "Headers": true, "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, + "console.error": true, + "crypto": true, + "fetch": true, + "msCrypto": true, + "navigator.onLine": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { - "globals": { - "console.warn": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { - "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": true, - "@metamask/ppom-validator>crypto-js": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { "globals": { - "console.warn": true + "console": true }, "packages": { - "wait-on>rxjs": true + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { + "@metamask/notification-services-controller>firebase>@firebase/messaging": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "Headers": true, + "Notification.maxActions": true, + "Notification.permission": true, + "Notification.requestPermission": true, + "PushSubscription.prototype.hasOwnProperty": true, + "ServiceWorkerRegistration": true, + "URL": true, + "addEventListener": true, + "atob": true, "btoa": true, + "clients.matchAll": true, + "clients.openWindow": true, "console.warn": true, "document": true, + "fetch": true, + "indexedDB": true, "location.href": true, + "location.origin": true, "navigator": true, + "origin.replace": true, + "registration.showNotification": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/providers": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/wordlists": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { - "globals": { - "__ledgerLogsListen": "write", - "console.error": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/installations": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, + "tslib": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { + "@metamask/notification-services-controller>firebase>@firebase/util": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, + "atob": true, + "browser": true, "btoa": true, - "console.warn": true, + "chrome": true, + "console": true, "document": true, - "location.href": true, + "indexedDB": true, "navigator": true, + "process": true, + "self": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, "process": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { - "globals": { - "crypto": true, - "define": true - } - }, - "@metamask/eth-query": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "watchify>xtend": true + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/bc-ur-registry-eth": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "eth-lattice-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-sig-util": { + "@keystonehq/bc-ur-registry-eth": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>@metamask/utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "uuid": true } }, - "@metamask/eth-sig-util>@metamask/utils": { + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "define": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ngraveio/bc-ur": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "buffer": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "tslib": true } }, - "@metamask/eth-sig-util>tweetnacl": { - "globals": { - "crypto": true, - "msCrypto": true, - "nacl": "write" - }, + "@keystonehq/metamask-airgapped-keyring": { "packages": { - "browserify>browser-resolve": true + "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, + "@keystonehq/bc-ur-registry-eth": true, + "@metamask/obs-store": true, + "browserify>buffer": true, + "webpack>events": true, + "@keystonehq/metamask-airgapped-keyring>rlp": true, + "uuid": true } }, - "@metamask/eth-snap-keyring": { + "chart.js>@kurkle/color": { "globals": { - "URL": true, - "console.error": true + "define": true + } + }, + "@lavamoat/lavadome-react": { + "globals": { + "Document.prototype": true, + "DocumentFragment.prototype": true, + "Element.prototype": true, + "Node.prototype": true, + "console.warn": true, + "document": true }, "packages": { - "@ethereumjs/tx": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/eth-snap-keyring>uuid": true, - "@metamask/keyring-api": true, - "@metamask/utils>@metamask/superstruct": true, - "webpack>events": true + "react": true } }, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { + "globals": { + "console.warn": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { + "packages": { + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, + "@metamask/ppom-validator>crypto-js": true } }, - "@metamask/eth-snap-keyring>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.warn": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ethersproject/abi": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/transactions": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, "browserify>buffer": true, - "nock>debug": true, "semver": true } }, - "@metamask/eth-snap-keyring>uuid": { - "globals": { - "crypto": true - } - }, - "@metamask/eth-token-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { "globals": { "console.warn": true }, "packages": { - "@babel/runtime": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, - "@metamask/eth-token-tracker>deep-equal": true, - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/safe-event-emitter": true, - "bn.js": true, - "human-standard-token-abi": true + "wait-on>rxjs": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { + "globals": { + "__ledgerLogsListen": "write", + "console.error": true + } + }, + "@material-ui/core": { "globals": { + "Image": true, + "_formatMuiErrorMessage": true, + "addEventListener": true, + "clearInterval": true, "clearTimeout": true, "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "getSelection": true, + "innerHeight": true, + "innerWidth": true, + "matchMedia": true, + "navigator": true, + "performance.now": true, + "removeEventListener": true, + "requestAnimationFrame": true, + "setInterval": true, "setTimeout": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true, - "pify": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles": true, + "@material-ui/core>@material-ui/system": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>popper.js": true, + "prop-types": true, + "react": true, + "react-dom": true, + "prop-types>react-is": true, + "@material-ui/core>react-transition-group": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { + "@material-ui/core>@material-ui/styles": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.error": true, + "console.warn": true, + "document.createComment": true, + "document.head": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-token-tracker>deep-equal": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, - "@metamask/eth-token-tracker>deep-equal>is-date-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, - "@metamask/eth-token-tracker>deep-equal>which-collection": true, - "@ngraveio/bc-ur>assert>object-is": true, - "browserify>util>is-arguments": true, - "browserify>util>which-typed-array": true, - "gulp>vinyl-fs>object.assign": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>regexp.prototype.flags": true, - "string.prototype.matchall>side-channel": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, + "@material-ui/core>@material-ui/styles>jss-plugin-global": true, + "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, + "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, + "@material-ui/core>@material-ui/styles>jss": true, + "prop-types": true, + "react": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { + "@material-ui/core>@material-ui/system": { + "globals": { + "console.error": true + }, "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true, - "browserify>util>is-arguments": true, - "eslint-plugin-react>array-includes>is-string": true, - "process": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>has-symbols": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "prop-types": true } }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { - "globals": { - "StopIteration": true - }, + "@material-ui/core>@material-ui/utils": { "packages": { - "string.prototype.matchall>internal-slot": true + "@babel/runtime": true, + "prop-types": true, + "prop-types>react-is": true } }, - "@metamask/eth-token-tracker>deep-equal>is-date-object": { + "@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection": { + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-controller>@metamask/utils": true } }, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-trezor-keyring": { - "globals": { - "setTimeout": true - }, + "@metamask/accounts-controller": { "packages": { - "@ethereumjs/tx": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "@trezor/connect-web": true, - "browserify>buffer": true, - "webpack>events": true + "@metamask/base-controller": true, + "@metamask/eth-snap-keyring": true, + "@metamask/keyring-api": true, + "@metamask/keyring-controller": true, + "@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "uuid": true } }, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "@metamask/address-book-controller": { "packages": { - "@metamask/eth-sig-util": true, - "@swc/helpers>tslib": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true } }, - "@metamask/eth-trezor-keyring>hdkey": { + "@metamask/announcement-controller": { "packages": { - "browserify>assert": true, - "crypto-browserify": true, - "ethereumjs-util>create-hash>ripemd160": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true + "@metamask/announcement-controller>@metamask/base-controller": true } }, - "@metamask/etherscan-link": { + "@metamask/approval-controller": { "globals": { - "URL": true + "console.info": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/rpc-errors": true, + "nanoid": true } }, - "@metamask/ethjs": { + "@metamask/assets-controllers": { "globals": { + "AbortController": true, + "Headers": true, + "URL": true, + "URLSearchParams": true, "clearInterval": true, - "setInterval": true + "clearTimeout": true, + "console.error": true, + "console.log": true, + "setInterval": true, + "setTimeout": true }, "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-provider-http": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/number-to-bn": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/abi-utils": true, + "@metamask/base-controller": true, + "@metamask/contract-metadata": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/metamask-eth-abis": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, "bn.js": true, - "browserify>buffer": true - } - }, - "@metamask/ethjs-contract": { - "packages": { - "@babel/runtime": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, - "promise-to-callback": true + "cockatiel": true, + "lodash": true, + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, + "single-call-balance-checker-abi": true, + "uuid": true } }, - "@metamask/ethjs-query": { + "@metamask/base-controller": { "globals": { - "console": true + "setTimeout": true }, "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format": true, - "@metamask/ethjs-query>@metamask/ethjs-rpc": true, - "promise-to-callback": true - } - }, - "@metamask/ethjs-query>@metamask/ethjs-format": { - "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "@metamask/ethjs>@metamask/number-to-bn": true + "immer": true } }, - "@metamask/ethjs-query>@metamask/ethjs-rpc": { + "@metamask/announcement-controller>@metamask/base-controller": { + "globals": { + "setTimeout": true + }, "packages": { - "promise-to-callback": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-filter": { + "@metamask/name-controller>@metamask/base-controller": { "globals": { - "clearInterval": true, - "setInterval": true - } - }, - "@metamask/ethjs>@metamask/ethjs-provider-http": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": { + "@metamask/rate-limit-controller>@metamask/base-controller": { "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/ethjs>@metamask/ethjs-unit": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/number-to-bn": true, - "bn.js": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-util": { + "@metamask/browser-passworder": { + "globals": { + "CryptoKey": true, + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, + "@metamask/browser-passworder>@metamask/utils": true, "browserify>buffer": true } }, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true - } - }, - "@metamask/ethjs>@metamask/number-to-bn": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "eth-keyring-controller>@metamask/browser-passworder": { + "globals": { + "crypto": true } }, - "@metamask/ethjs>ethjs-abi": { + "@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/ethjs>ethjs-abi>number-to-bn": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@metamask/ethjs-unit": true, + "@metamask/controller-utils>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, "bn.js": true, - "browserify>buffer": true + "browserify>buffer": true, + "eth-ens-namehash": true, + "eslint>fast-deep-equal": true } }, - "@metamask/ethjs>ethjs-abi>number-to-bn": { + "@metamask/ens-controller": { "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "punycode": true } }, - "@metamask/ethjs>js-sha3": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { "globals": { - "define": true + "clearTimeout": true, + "console.error": true, + "setTimeout": true }, "packages": { - "process": true + "@metamask/safe-event-emitter": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true, + "pify": true } }, - "@metamask/gas-fee-controller": { + "@metamask/network-controller>@metamask/eth-block-tracker": { "globals": { - "clearInterval": true, + "clearTimeout": true, "console.error": true, - "setInterval": true + "setTimeout": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "bn.js": true, - "uuid": true + "@metamask/safe-event-emitter": true, + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, - "@metamask/jazzicon": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring": { "globals": { - "document.createElement": true, - "document.createElementNS": true + "TextEncoder": true }, "packages": { - "@metamask/jazzicon>color": true, - "@metamask/jazzicon>mersenne-twister": true - } - }, - "@metamask/jazzicon>color": { - "packages": { - "@metamask/jazzicon>color>clone": true, - "@metamask/jazzicon>color>color-convert": true, - "@metamask/jazzicon>color>color-string": true - } - }, - "@metamask/jazzicon>color>clone": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/jazzicon>color>color-convert": { - "packages": { - "@metamask/jazzicon>color>color-convert>color-name": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-sig-util": true, + "@metamask/scure-bip39": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@metamask/jazzicon>color>color-string": { + "@metamask/eth-json-rpc-filters": { + "globals": { + "console.error": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/safe-event-emitter": true, + "@metamask/name-controller>async-mutex": true, + "pify": true } }, - "@metamask/json-rpc-engine": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "globals": { + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/json-rpc-engine>@metamask/utils": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true } }, - "@metamask/json-rpc-engine>@metamask/utils": { + "@metamask/eth-json-rpc-middleware": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true, + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>klona": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true } }, - "@metamask/json-rpc-middleware-stream": { - "globals": { - "console.warn": true, - "setTimeout": true - }, + "@metamask/eth-json-rpc-provider": { "packages": { - "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, "@metamask/safe-event-emitter": true, - "readable-stream": true + "uuid": true } }, - "@metamask/json-rpc-middleware-stream>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "addEventListener": true, + "console.error": true, + "document.createElement": true, + "document.head.appendChild": true, + "fetch": true, + "removeEventListener": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-api": { - "globals": { - "URL": true - }, + "@metamask/controller-utils>@metamask/eth-query": { "packages": { - "@metamask/keyring-api>@metamask/utils": true, - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-api>uuid": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/ppom-validator>json-rpc-random-id": true, + "watchify>xtend": true } }, - "@metamask/keyring-api>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/abi-utils": true, + "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-api>uuid": { - "globals": { - "crypto": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/base-controller": true, - "@metamask/browser-passworder": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>ethereumjs-wallet": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/utils": true + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": { - "globals": { - "TextEncoder": true - }, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, - "@metamask/scure-bip39": true, - "browserify>buffer": true + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/keyring-controller>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/eth-sig-util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, "crypto-browserify>randombytes": true } }, - "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "@metamask/eth-snap-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true }, "packages": { + "@ethereumjs/tx": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/keyring-api": true, + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-snap-keyring>@metamask/utils": true, + "webpack>events": true, + "@metamask/eth-snap-keyring>uuid": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": { + "@metamask/eth-token-tracker": { "globals": { - "URL": true + "console.warn": true }, "packages": { - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@babel/runtime": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true, + "@metamask/safe-event-emitter": true, + "bn.js": true, + "@metamask/eth-token-tracker>deep-equal": true, + "human-standard-token-abi": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { + "@metamask/eth-trezor-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, - "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, - "browserify>buffer": true, - "crypto-browserify": true, - "crypto-browserify>randombytes": true, - "eth-lattice-keyring>gridplus-sdk>aes-js": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "uuid": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { - "packages": { - "browserify>assert": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethers>@ethersproject/sha2>hash.js": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true, - "bn.js": true, - "browserify>assert": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, + "@trezor/connect-web": true, "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "@metamask/etherscan-link": { + "globals": { + "URL": true } }, - "@metamask/logging-controller": { + "eth-method-registry>@metamask/ethjs-contract": { "packages": { - "@metamask/base-controller": true, - "uuid": true + "@babel/runtime": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": true, + "eth-ens-namehash>js-sha3": true, + "promise-to-callback": true } }, - "@metamask/logo": { + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": { "globals": { - "addEventListener": true, - "document.body.appendChild": true, - "document.createElementNS": true, - "innerHeight": true, - "innerWidth": true, - "requestAnimationFrame": true - }, - "packages": { - "@metamask/logo>gl-mat4": true, - "@metamask/logo>gl-vec3": true - } - }, - "@metamask/message-manager": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "clearInterval": true, + "setInterval": true } }, - "@metamask/message-manager>jsonschema": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": { "packages": { - "browserify>url": true + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/name-controller": { + "eth-method-registry>@metamask/ethjs-query": { "globals": { - "fetch": true + "console": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/name-controller>@metamask/base-controller": true, - "@metamask/name-controller>@metamask/utils": true, - "@metamask/name-controller>async-mutex": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": true, + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": { "packages": { - "immer": true + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "bn.js": true } }, - "@metamask/name-controller>async-mutex": { - "globals": { - "clearTimeout": true, - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": { "packages": { - "@swc/helpers>tslib": true + "browserify>buffer": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/network-controller": { + "@metamask/gas-fee-controller": { "globals": { - "btoa": true, - "fetch": true, - "setTimeout": true + "clearInterval": true, + "console.error": true, + "setInterval": true }, "packages": { - "@metamask/base-controller": true, "@metamask/controller-utils": true, - "@metamask/eth-json-rpc-middleware": true, - "@metamask/eth-json-rpc-provider": true, - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-block-tracker": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "eslint>fast-deep-equal": true, - "reselect": true, - "uri-js": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "bn.js": true, "uuid": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker": { + "@metamask/jazzicon": { "globals": { - "clearTimeout": true, - "console.error": true, - "setTimeout": true + "document.createElement": true, + "document.createElementNS": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true + "@metamask/jazzicon>color": true, + "@metamask/jazzicon>mersenne-twister": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/json-rpc-engine": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/rpc-errors": true, + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-engine>@metamask/utils": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "@metamask/json-rpc-middleware-stream": { "globals": { - "fetch": true, + "console.warn": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-provider": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true, - "@metamask/rpc-errors": true + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { + "@metamask/snaps-sdk>@metamask/key-tree": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "crypto.subtle": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, + "@metamask/scure-bip39": true, + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/utils>@scure/base": true } }, - "@metamask/notification-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/keyring-api": { + "packages": { + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller": { - "globals": { - "Intl.NumberFormat": true, - "addEventListener": true, - "fetch": true, - "registration": true, - "removeEventListener": true - }, + "@metamask/profile-sync-controller>@metamask/keyring-api": { "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, - "@metamask/notification-services-controller>bignumber.js": true, - "@metamask/notification-services-controller>firebase": true, - "@metamask/profile-sync-controller": true, - "@metamask/utils": true, - "loglevel": true, - "uuid": true + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { - "globals": { - "SuppressedError": true + "@metamask/keyring-controller": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/base-controller": true, + "@metamask/browser-passworder": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, + "@metamask/keyring-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, + "@metamask/keyring-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "@metamask/keyring-controller>ethereumjs-wallet": true } }, - "@metamask/notification-services-controller>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { + "packages": { + "@metamask/keyring-snap-client": true } }, - "@metamask/notification-services-controller>firebase": { + "@metamask/keyring-snap-client": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/messaging": true + "@metamask/keyring-api": true, + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-snap-client>uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app": { + "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { - "FinalizationRegistry": true, - "console.warn": true + "URL": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { + "@metamask/logging-controller": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { + "@metamask/logo": { "globals": { - "console": true + "addEventListener": true, + "document.body.appendChild": true, + "document.createElementNS": true, + "innerHeight": true, + "innerWidth": true, + "requestAnimationFrame": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/logo>gl-mat4": true, + "@metamask/logo>gl-vec3": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": { + "@metamask/message-manager": { + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "uuid": true + } + }, + "@metamask/name-controller": { "globals": { - "DOMException": true, - "IDBCursor": true, - "IDBDatabase": true, - "IDBIndex": true, - "IDBObjectStore": true, - "IDBRequest": true, - "IDBTransaction": true, - "indexedDB.deleteDatabase": true, - "indexedDB.open": true + "fetch": true + }, + "packages": { + "@metamask/name-controller>@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/name-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true } }, - "@metamask/notification-services-controller>firebase>@firebase/installations": { + "@metamask/network-controller": { "globals": { - "BroadcastChannel": true, - "Headers": true, "btoa": true, - "console.error": true, - "crypto": true, "fetch": true, - "msCrypto": true, - "navigator.onLine": true, "setTimeout": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/network-controller>@metamask/eth-block-tracker": true, + "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, + "@metamask/eth-json-rpc-middleware": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true, + "@metamask/utils": true, + "eslint>fast-deep-equal": true, + "reselect": true, + "uri-js": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/messaging": { + "@metamask/transaction-controller>@metamask/nonce-tracker": { + "packages": { + "@ethersproject/providers": true, + "browserify>assert": true, + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true + } + }, + "@metamask/notification-services-controller": { "globals": { - "Headers": true, - "Notification.maxActions": true, - "Notification.permission": true, - "Notification.requestPermission": true, - "PushSubscription.prototype.hasOwnProperty": true, - "ServiceWorkerRegistration": true, - "URL": true, + "Intl.NumberFormat": true, "addEventListener": true, - "atob": true, - "btoa": true, - "clients.matchAll": true, - "clients.openWindow": true, - "console.warn": true, - "document": true, "fetch": true, - "indexedDB": true, - "location.href": true, - "location.origin": true, - "navigator": true, - "origin.replace": true, - "registration.showNotification": true, - "setTimeout": true + "registration": true, + "removeEventListener": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/installations": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true, - "@swc/helpers>tslib": true + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/profile-sync-controller": true, + "@metamask/utils": true, + "@metamask/notification-services-controller>bignumber.js": true, + "@metamask/notification-services-controller>firebase": true, + "loglevel": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/util": { - "globals": { - "atob": true, - "browser": true, - "btoa": true, - "chrome": true, - "console": true, - "document": true, - "indexedDB": true, - "navigator": true, - "process": true, - "self": true, - "setTimeout": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": { "packages": { - "process": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, "@metamask/object-multiplex": { @@ -1970,11 +1504,6 @@ "readable-stream": true } }, - "@metamask/object-multiplex>once": { - "packages": { - "@metamask/object-multiplex>once>wrappy": true - } - }, "@metamask/obs-store": { "packages": { "@metamask/safe-event-emitter": true, @@ -1990,38 +1519,18 @@ "@metamask/controller-utils": true, "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, + "@metamask/permission-controller>@metamask/utils": true, "deep-freeze-strict": true, "immer": true, "nanoid": true } }, - "@metamask/permission-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, "@metamask/permission-log-controller": { "packages": { "@metamask/base-controller": true, "@metamask/permission-log-controller>@metamask/utils": true } }, - "@metamask/permission-log-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, "@metamask/phishing-controller": { "globals": { "TextEncoder": true, @@ -2030,12 +1539,12 @@ "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/base-controller": true, "@metamask/controller-utils": true, "@noble/hashes": true, - "punycode": true, - "webpack-cli>fastest-levenshtein": true + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack-cli>fastest-levenshtein": true, + "punycode": true } }, "@metamask/polling-controller": { @@ -2054,84 +1563,32 @@ "globals": { "MessageEvent.prototype": true, "WorkerGlobalScope": true, - "addEventListener": true, - "browser": true, - "chrome": true, - "location.origin": true, - "postMessage": true, - "removeEventListener": true - }, - "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/ppom-validator": { - "globals": { - "URL": true, - "console.error": true, - "crypto": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/ppom-validator>crypto-js": true, - "@metamask/ppom-validator>elliptic": true, - "await-semaphore": true, - "browserify>buffer": true - } - }, - "@metamask/ppom-validator>crypto-js": { - "globals": { - "crypto": true, - "define": true, - "msCrypto": true - }, - "packages": { - "browserify>browser-resolve": true - } - }, - "@metamask/ppom-validator>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true - } - }, - "@metamask/ppom-validator>elliptic>brorand": { - "globals": { - "crypto": true, - "msCrypto": true + "addEventListener": true, + "browser": true, + "chrome": true, + "location.origin": true, + "postMessage": true, + "removeEventListener": true }, "packages": { - "browserify>browser-resolve": true + "@metamask/post-message-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/ppom-validator>elliptic>hmac-drbg": { + "@metamask/ppom-validator": { + "globals": { + "URL": true, + "console.error": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "ethers>@ethersproject/sha2>hash.js": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "await-semaphore": true, + "browserify>buffer": true, + "@metamask/ppom-validator>crypto-js": true, + "@metamask/ppom-validator>elliptic": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, "@metamask/preferences-controller": { @@ -2157,668 +1614,933 @@ }, "packages": { "@metamask/base-controller": true, + "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/keyring-controller": true, "@metamask/network-controller": true, - "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/profile-sync-controller>@noble/ciphers": true, - "@metamask/profile-sync-controller>siwe": true, "@noble/hashes": true, "browserify>buffer": true, - "loglevel": true + "loglevel": true, + "@metamask/profile-sync-controller>siwe": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api": { + "@metamask/queued-request-controller": { "packages": { - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": true, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/selected-network-controller": true, + "@metamask/utils": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { + "@metamask/rate-limit-controller": { + "globals": { + "setTimeout": true + }, + "packages": { + "@metamask/rate-limit-controller>@metamask/base-controller": true, + "@metamask/rate-limit-controller>@metamask/rpc-errors": true, + "@metamask/rate-limit-controller>@metamask/utils": true + } + }, + "@metamask/remote-feature-flag-controller": { + "packages": { + "@metamask/base-controller": true, + "cockatiel": true, + "uuid": true + } + }, + "@metamask/rpc-errors": { + "packages": { + "@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/rate-limit-controller>@metamask/rpc-errors": { + "packages": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "webpack>events": true + } + }, + "@metamask/scure-bip39": { "globals": { - "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/scure-bip39>@noble/hashes": true, + "@metamask/utils>@scure/base": true } }, - "@metamask/profile-sync-controller>@noble/ciphers": { + "@metamask/selected-network-controller": { + "packages": { + "@metamask/base-controller": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true + } + }, + "@metamask/signature-controller": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "crypto": true + "fetch": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller": true, + "@metamask/logging-controller": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "@metamask/message-manager>jsonschema": true, + "uuid": true } }, - "@metamask/profile-sync-controller>siwe": { + "@metamask/smart-transactions-controller": { "globals": { + "URLSearchParams": true, + "clearInterval": true, "console.error": true, - "console.warn": true + "console.log": true, + "fetch": true, + "setInterval": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random": true, - "ethers": true + "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethersproject/bytes": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "@metamask/transaction-controller": true, + "@metamask/smart-transactions-controller>bignumber.js": true, + "browserify>buffer": true, + "fast-json-patch": true, + "lodash": true } }, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "@metamask/snaps-controllers": { "globals": { - "console.error": true, - "console.log": true + "DecompressionStream": true, + "URL": true, + "clearTimeout": true, + "document.getElementById": true, + "fetch.bind": true, + "setTimeout": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/json-rpc-middleware-stream": true, + "@metamask/object-multiplex": true, + "@metamask/permission-controller": true, + "@metamask/post-message-stream": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/snaps-registry": true, + "@metamask/snaps-rpc-methods": true, + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/snaps-controllers>@metamask/utils": true, + "@metamask/snaps-controllers>@xstate/fsm": true, + "@metamask/name-controller>async-mutex": true, + "browserify>browserify-zlib": true, + "@metamask/snaps-controllers>concat-stream": true, + "eslint>fast-deep-equal": true, + "@metamask/snaps-controllers>get-npm-tarball-url": true, + "immer": true, + "luxon": true, + "nanoid": true, + "readable-stream": true, + "@metamask/snaps-controllers>readable-web-to-node-stream": true, + "semver": true, + "@metamask/snaps-controllers>tar-stream": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random": { + "@metamask/snaps-execution-environments": { "globals": { - "crypto": true, - "msCrypto": true + "document.getElementById": true }, "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, - "browserify>browser-resolve": true + "@metamask/post-message-stream": true, + "@metamask/snaps-utils": true, + "@metamask/utils": true, + "@metamask/snaps-execution-environments>@metamask/utils": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "@metamask/snaps-utils>@metamask/snaps-registry": { "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@noble/hashes": true } }, - "@metamask/queued-request-controller": { + "@metamask/snaps-rpc-methods": { "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, "@metamask/rpc-errors": true, - "@metamask/selected-network-controller": true, - "@metamask/utils": true + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-rpc-methods>@metamask/utils": true, + "@noble/hashes": true, + "luxon": true } }, - "@metamask/rate-limit-controller": { + "@metamask/snaps-sdk": { "globals": { + "fetch": true + }, + "packages": { + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-sdk>@metamask/utils": true + } + }, + "@metamask/snaps-utils": { + "globals": { + "File": true, + "FileReader": true, + "TextDecoder": true, + "TextEncoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "crypto": true, + "document.body.appendChild": true, + "document.createElement": true, + "fetch": true + }, + "packages": { + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/slip44": true, + "@metamask/snaps-sdk": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/utils": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "chalk": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>fast-xml-parser": true, + "@metamask/snaps-utils>marked": true, + "@metamask/snaps-utils>rfdc": true, + "semver": true, + "@metamask/snaps-utils>validate-npm-package-name": true + } + }, + "@metamask/transaction-controller": { + "globals": { + "clearTimeout": true, + "console.error": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/rate-limit-controller>@metamask/base-controller": true, - "@metamask/rate-limit-controller>@metamask/rpc-errors": true, - "@metamask/rate-limit-controller>@metamask/utils": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/abi": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/metamask-eth-abis": true, + "@metamask/network-controller": true, + "@metamask/transaction-controller>@metamask/nonce-tracker": true, + "@metamask/rpc-errors": true, + "@metamask/transaction-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "bn.js": true, + "browserify>buffer": true, + "eth-method-registry": true, + "webpack>events": true, + "fast-json-patch": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/base-controller": { + "@metamask/user-operation-controller": { "globals": { - "setTimeout": true + "fetch": true }, "packages": { - "immer": true - } - }, - "@metamask/rate-limit-controller>@metamask/rpc-errors": { - "packages": { - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/transaction-controller": true, + "@metamask/utils": true, + "bn.js": true, + "webpack>events": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rate-limit-controller>@metamask/utils": { + "@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/remote-feature-flag-controller": { - "packages": { - "@metamask/base-controller": true, - "cockatiel": true - } - }, - "@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true - } - }, - "@metamask/rpc-errors>@metamask/utils": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rpc-methods-flask>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/rpc-methods>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/safe-event-emitter": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39": { + "@metamask/browser-passworder>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/scure-bip39>@noble/hashes": true, - "@metamask/utils>@scure/base": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39>@noble/hashes": { + "@metamask/controller-utils>@metamask/utils": { "globals": { - "TextEncoder": true, - "crypto": true - } - }, - "@metamask/selected-network-controller": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/base-controller": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/keyring-controller": true, - "@metamask/logging-controller": true, - "@metamask/message-manager>jsonschema": true, - "@metamask/signature-controller>@metamask/eth-sig-util": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util": { + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/smart-transactions-controller": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { "globals": { - "URLSearchParams": true, - "clearInterval": true, - "console.error": true, - "console.log": true, - "fetch": true, - "setInterval": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bytes": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/transaction-controller": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "fast-json-patch": true, - "lodash": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { - "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { - "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/eth-json-rpc-middleware>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/util": { - "globals": { - "console.warn": true, - "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "webpack>events": true - } - }, - "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>bignumber.js": { + "@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "DecompressionStream": true, - "URL": true, - "clearTimeout": true, - "document.getElementById": true, - "fetch.bind": true, - "setTimeout": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, - "@metamask/json-rpc-middleware-stream": true, - "@metamask/object-multiplex": true, - "@metamask/permission-controller": true, - "@metamask/post-message-stream": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-controllers>@xstate/fsm": true, - "@metamask/snaps-controllers>concat-stream": true, - "@metamask/snaps-controllers>get-npm-tarball-url": true, - "@metamask/snaps-controllers>readable-web-to-node-stream": true, - "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-rpc-methods": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-utils": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/utils": true, - "browserify>browserify-zlib": true, - "eslint>fast-deep-equal": true, - "immer": true, - "nanoid": true, - "readable-stream": true, + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-controllers-flask>nanoid": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/snaps-controllers>concat-stream": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "readable-stream": true, - "terser>source-map-support>buffer-from": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>nanoid": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>readable-web-to-node-stream": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "readable-stream": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>b4a": true, - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx": true, - "browserify>browser-resolve": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>b4a": { + "@metamask/eth-snap-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx": { + "@metamask/json-rpc-engine>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true, - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { + "@metamask/json-rpc-middleware-stream>@metamask/utils": { "globals": { - "queueMicrotask": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-execution-environments": { + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": { "globals": { - "document.getElementById": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/post-message-stream": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-rpc-methods": { + "@metamask/keyring-api>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk": { + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk>@metamask/key-tree": { + "@metamask/keyring-controller>@metamask/utils": { "globals": { - "crypto.subtle": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/scure-bip39": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils": { + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { "globals": { - "File": true, - "FileReader": true, "TextDecoder": true, - "TextEncoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "crypto": true, - "document.body.appendChild": true, - "document.createElement": true, - "fetch": true + "TextEncoder": true }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils>@metamask/slip44": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>fast-xml-parser": true, - "@metamask/snaps-utils>marked": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, "@noble/hashes": true, - "chalk": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>cron-parser": { + "@metamask/permission-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>browser-resolve": true, - "luxon": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>fast-xml-parser": { + "@metamask/permission-log-controller>@metamask/utils": { "globals": { - "entityName": true, - "val": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/snaps-utils>fast-xml-parser>strnum": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>marked": { + "@metamask/post-message-stream>@metamask/utils": { "globals": { - "console.error": true, - "console.warn": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>rfdc": { + "@metamask/rate-limit-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>buffer": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name": { + "@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-utils>validate-npm-package-name>builtins": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name>builtins": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "process": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/test-bundler>@ethersproject/networks": { + "@metamask/snaps-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "ethers>@ethersproject/logger": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller": { + "@metamask/snaps-execution-environments>@metamask/utils": { "globals": { - "clearTimeout": true, - "console.error": true, - "fetch": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/abi": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/network-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller>@metamask/nonce-tracker": true, - "@metamask/utils": true, - "bn.js": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "eth-method-registry": true, - "fast-json-patch": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker": { + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true, - "browserify>assert": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { + "@metamask/snaps-rpc-methods>@metamask/utils": { "globals": { - "clearTimeout": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/user-operation-controller": { + "@metamask/snaps-sdk>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "bn.js": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/utils": { + "@metamask/snaps-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/utils>@scure/base": { + "@metamask/transaction-controller>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, "@ngraveio/bc-ur": { "packages": { "@ngraveio/bc-ur>@keystonehq/alias-sampling": true, + "browserify>assert": true, "@ngraveio/bc-ur>bignumber.js": true, + "browserify>buffer": true, "@ngraveio/bc-ur>cbor-sync": true, "@ngraveio/bc-ur>crc": true, "@ngraveio/bc-ur>jsbi": true, - "addons-linter>sha.js": true, - "browserify>assert": true, - "browserify>buffer": true + "addons-linter>sha.js": true } }, - "@ngraveio/bc-ur>assert>object-is": { + "@metamask/profile-sync-controller>@noble/ciphers": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "crypto": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { + "globals": { + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true } }, - "@ngraveio/bc-ur>bignumber.js": { + "@noble/hashes": { "globals": { - "crypto": true, - "define": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>cbor-sync": { + "@metamask/scure-bip39>@noble/hashes": { "globals": { - "define": true - }, - "packages": { - "browserify>buffer": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>crc": { - "packages": { - "browserify>buffer": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>jsbi": { + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": { "globals": { - "define": true + "TextEncoder": true, + "crypto": true } }, - "@noble/hashes": { + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { "globals": { "TextEncoder": true, "crypto": true @@ -2835,6 +2557,20 @@ "navigator.userAgent": true } }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "globals": { + "console.log": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "globals": { + "XMLHttpRequest": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + } + }, "@reduxjs/toolkit": { "globals": { "AbortController": true, @@ -2846,42 +2582,46 @@ "setTimeout": true }, "packages": { - "@reduxjs/toolkit>reselect": true, "immer": true, "process": true, "redux": true, - "redux-thunk": true - } - }, - "@segment/loosely-validate-event": { - "packages": { - "@segment/loosely-validate-event>component-type": true, - "@segment/loosely-validate-event>join-component": true, - "browserify>assert": true, - "browserify>buffer": true + "redux-thunk": true, + "@reduxjs/toolkit>reselect": true } }, - "@sentry/browser": { + "react-router-dom-v5-compat>@remix-run/router": { "globals": { - "PerformanceObserver.supportedEntryTypes": true, + "AbortController": true, + "DOMException": true, + "FormData": true, + "Headers": true, "Request": true, + "Response": true, "URL": true, - "XMLHttpRequest.prototype": true, - "__SENTRY_DEBUG__": true, - "__SENTRY_RELEASE__": true, - "addEventListener": true, - "console.error": true, - "indexedDB.open": true, - "performance.timeOrigin": true, - "setTimeout": true - }, + "URLSearchParams": true, + "console": true, + "document.defaultView": true + } + }, + "@metamask/utils>@scure/base": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "packages": { + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true, + "@metamask/utils>@scure/base": true + } + }, + "@segment/loosely-validate-event": { "packages": { - "@sentry/browser>@sentry-internal/browser-utils": true, - "@sentry/browser>@sentry-internal/feedback": true, - "@sentry/browser>@sentry-internal/replay": true, - "@sentry/browser>@sentry-internal/replay-canvas": true, - "@sentry/browser>@sentry/core": true, - "@sentry/utils": true + "browserify>assert": true, + "browserify>buffer": true, + "@segment/loosely-validate-event>component-type": true, + "@segment/loosely-validate-event>join-component": true } }, "@sentry/browser>@sentry-internal/browser-utils": { @@ -2920,6 +2660,25 @@ "@sentry/utils": true } }, + "@sentry/browser>@sentry-internal/replay-canvas": { + "globals": { + "Blob": true, + "HTMLCanvasElement": true, + "HTMLImageElement": true, + "ImageData": true, + "URL.createObjectURL": true, + "WeakRef": true, + "Worker": true, + "cancelAnimationFrame": true, + "console.error": true, + "createImageBitmap": true, + "document": true + }, + "packages": { + "@sentry/browser>@sentry/core": true, + "@sentry/utils": true + } + }, "@sentry/browser>@sentry-internal/replay": { "globals": { "Blob": true, @@ -2969,21 +2728,25 @@ "@sentry/utils": true } }, - "@sentry/browser>@sentry-internal/replay-canvas": { + "@sentry/browser": { "globals": { - "Blob": true, - "HTMLCanvasElement": true, - "HTMLImageElement": true, - "ImageData": true, - "URL.createObjectURL": true, - "WeakRef": true, - "Worker": true, - "cancelAnimationFrame": true, + "PerformanceObserver.supportedEntryTypes": true, + "Request": true, + "URL": true, + "XMLHttpRequest.prototype": true, + "__SENTRY_DEBUG__": true, + "__SENTRY_RELEASE__": true, + "addEventListener": true, "console.error": true, - "createImageBitmap": true, - "document": true + "indexedDB.open": true, + "performance.timeOrigin": true, + "setTimeout": true }, "packages": { + "@sentry/browser>@sentry-internal/browser-utils": true, + "@sentry/browser>@sentry-internal/feedback": true, + "@sentry/browser>@sentry-internal/replay-canvas": true, + "@sentry/browser>@sentry-internal/replay": true, "@sentry/browser>@sentry/core": true, "@sentry/utils": true } @@ -3079,20 +2842,61 @@ "btoa": true } }, - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { + "@metamask/controller-utils>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "react-markdown>unist-util-visit": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true } }, - "@storybook/addon-knobs>qs": { + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "string.prototype.matchall>side-channel": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true + } + }, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true } }, - "@swc/helpers>tslib": { + "@metamask/profile-sync-controller>siwe>@stablelib/random": { "globals": { - "SuppressedError": true, - "define": true + "crypto": true, + "msCrypto": true + }, + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, + "browserify>browser-resolve": true + } + }, + "@trezor/connect-web>@trezor/connect-common": { + "globals": { + "console.warn": true, + "localStorage.getItem": true, + "localStorage.setItem": true, + "navigator": true, + "setTimeout": true, + "window": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, + "@trezor/connect-web>@trezor/utils": true, + "tslib": true + } + }, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "packages": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "tslib": true } }, "@trezor/connect-web": { @@ -3119,35 +2923,20 @@ "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/connect-common": true, + "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/utils": true, - "webpack>events": true + "webpack>events": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect": { "packages": { - "@swc/helpers>tslib": true, "@trezor/connect-web>@trezor/connect>@trezor/protobuf": true, "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, "@trezor/connect-web>@trezor/connect>@trezor/transport": true, - "@trezor/connect-web>@trezor/utils": true - } - }, - "@trezor/connect-web>@trezor/connect-common": { - "globals": { - "console.warn": true, - "localStorage.getItem": true, - "localStorage.setItem": true, - "navigator": true, - "setTimeout": true, - "window": true - }, - "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, - "@trezor/connect-web>@trezor/utils": true + "@trezor/connect-web>@trezor/utils": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": { @@ -3163,157 +2952,248 @@ "screen.width": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true, - "process": true + "process": true, + "tslib": true, + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true } }, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, + "browserify>buffer": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, + "tslib": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { "globals": { - "define": true + "console.warn": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, + "browserify>buffer": true, + "ts-mixer": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "@trezor/connect-web>@trezor/utils": { + "globals": { + "AbortController": true, + "Intl.NumberFormat": true, + "clearInterval": true, + "clearTimeout": true, + "console.error": true, + "console.info": true, + "console.log": true, + "console.warn": true, + "setInterval": true, + "setTimeout": true + }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, - "browserify>buffer": true + "@trezor/connect-web>@trezor/utils>bignumber.js": true, + "browserify>buffer": true, + "webpack>events": true, + "tslib": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { + "@welldone-software/why-did-you-render": { "globals": { - "process": true, + "Element": true, + "console.group": true, + "console.groupCollapsed": true, + "console.groupEnd": true, + "console.log": true, + "console.warn": true, + "define": true, "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true + "lodash": true, + "react": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "@zxing/browser": { "globals": { - "console.log": true + "HTMLElement": true, + "HTMLImageElement": true, + "HTMLVideoElement": true, + "clearTimeout": true, + "console.error": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library": true + } + }, + "@zxing/library": { + "globals": { + "HTMLImageElement": true, + "HTMLVideoElement": true, + "TextDecoder": true, + "TextEncoder": true, + "URL.createObjectURL": true, + "btoa": true, + "console.log": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library>ts-custom-error": true + } + }, + "@lavamoat/lavapack>readable-stream>abort-controller": { + "globals": { + "AbortController": true + } + }, + "currency-formatter>accounting": { + "globals": { + "define": true + } + }, + "ethers>@ethersproject/json-wallets>aes-js": { + "globals": { + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>aes-js": { + "globals": { + "define": true + } + }, + "chalk>ansi-styles": { + "packages": { + "chalk>ansi-styles>color-convert": true + } + }, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { + "packages": { + "browserify>buffer": true + } + }, + "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true + } + }, + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "browserify>vm-browserify": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "browserify>assert": { "globals": { - "XMLHttpRequest": true + "Buffer": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + "react>object-assign": true, + "browserify>assert>util": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { + "@metamask/name-controller>async-mutex": { "globals": { - "console.warn": true + "clearTimeout": true, + "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, - "browserify>buffer": true, - "ts-mixer": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils": { + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { "globals": { - "AbortController": true, - "Intl.NumberFormat": true, - "clearInterval": true, "clearTimeout": true, - "console.error": true, - "console.info": true, - "console.log": true, - "console.warn": true, - "setInterval": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/utils>bignumber.js": true, - "browserify>buffer": true, - "webpack>events": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "string.prototype.matchall>es-abstract>available-typed-arrays": { + "packages": { + "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true } }, - "@welldone-software/why-did-you-render": { + "await-semaphore": { + "packages": { + "process": true, + "browserify>timers-browserify": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { "globals": { - "Element": true, - "console.group": true, - "console.groupCollapsed": true, - "console.groupEnd": true, - "console.log": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, - "define": true, + "document": true, + "location.href": true, + "navigator": true, "setTimeout": true }, "packages": { - "lodash": true, - "react": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/browser": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { "globals": { - "HTMLElement": true, - "HTMLImageElement": true, - "HTMLVideoElement": true, - "clearTimeout": true, - "console.error": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/library": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { "globals": { - "HTMLImageElement": true, - "HTMLVideoElement": true, - "TextDecoder": true, - "TextEncoder": true, - "URL.createObjectURL": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, "btoa": true, - "console.log": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library>ts-custom-error": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "addons-linter>sha.js": { - "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@metamask/snaps-controllers>tar-stream>b4a": { + "globals": { + "TextDecoder": true, + "TextEncoder": true } }, - "await-semaphore": { + "@ensdomains/content-hash>multihashes>multibase>base-x": { "packages": { - "browserify>timers-browserify": true, - "process": true - } - }, - "axios>form-data": { - "globals": { - "FormData": true + "koa>content-disposition>safe-buffer": true } }, "base32-encode": { @@ -3327,139 +3207,178 @@ "define": true } }, - "blo": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { "globals": { - "btoa": true + "crypto": true, + "define": true } }, - "bn.js": { + "@metamask/notification-services-controller>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "define": true } }, - "bowser": { + "@metamask/smart-transactions-controller>bignumber.js": { "globals": { + "crypto": true, "define": true } }, - "browserify>assert": { + "@ngraveio/bc-ur>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>assert>util": true, - "react>object-assign": true + "crypto": true, + "define": true } }, - "browserify>assert>util": { + "@trezor/connect-web>@trezor/utils>bignumber.js": { "globals": { - "console.error": true, - "console.log": true, - "console.trace": true, - "process": true - }, + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bitwise": { "packages": { - "browserify>assert>util>inherits": true, - "process": true + "browserify>buffer": true } }, - "browserify>browserify-zlib": { + "blo": { + "globals": { + "btoa": true + } + }, + "bn.js": { + "globals": { + "Buffer": true + }, "packages": { - "browserify>assert": true, - "browserify>browserify-zlib>pako": true, - "browserify>buffer": true, - "browserify>util": true, - "process": true, - "stream-browserify": true + "browserify>browser-resolve": true } }, - "browserify>buffer": { + "eth-lattice-keyring>gridplus-sdk>borc": { "globals": { "console": true }, "packages": { - "base64-js": true, - "buffer>ieee754": true + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, + "browserify>buffer": true, + "buffer>ieee754": true, + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true } }, - "browserify>punycode": { + "bowser": { "globals": { "define": true } }, - "browserify>string_decoder": { + "@metamask/ppom-validator>elliptic>brorand": { + "globals": { + "crypto": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "ethereumjs-util>ethereum-cryptography>browserify-aes": { "packages": { + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "pumpify>inherits": true, "koa>content-disposition>safe-buffer": true } }, - "browserify>timers-browserify": { - "globals": { - "clearInterval": true, - "clearTimeout": true, - "setInterval": true, - "setTimeout": true - }, + "crypto-browserify>browserify-cipher": { "packages": { - "process": true + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "crypto-browserify>browserify-cipher>browserify-des": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true } }, - "browserify>url": { + "crypto-browserify>browserify-cipher>browserify-des": { "packages": { - "@storybook/addon-knobs>qs": true, - "browserify>punycode": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>browserify-des>des.js": true, + "pumpify>inherits": true } }, - "browserify>util": { - "globals": { - "console.error": true, - "console.log": true, - "console.trace": true - }, + "crypto-browserify>public-encrypt>browserify-rsa": { "packages": { - "browserify>util>is-arguments": true, - "browserify>util>is-typed-array": true, - "browserify>util>which-typed-array": true, - "koa>is-generator-function": true, + "bn.js": true, + "browserify>buffer": true, + "crypto-browserify>randombytes": true + } + }, + "crypto-browserify>browserify-sign": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>create-hmac": true, + "@metamask/ppom-validator>elliptic": true, + "pumpify>inherits": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "stream-browserify": true + } + }, + "browserify>browserify-zlib": { + "packages": { + "browserify>assert": true, + "browserify>buffer": true, + "browserify>browserify-zlib>pako": true, "process": true, - "pumpify>inherits": true + "stream-browserify": true, + "browserify>util": true } }, - "browserify>util>is-arguments": { + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true } }, - "browserify>util>is-typed-array": { + "ethereumjs-util>ethereum-cryptography>bs58check": { "packages": { - "browserify>util>which-typed-array": true + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, + "ethereumjs-util>create-hash": true, + "koa>content-disposition>safe-buffer": true } }, - "browserify>util>which-typed-array": { + "buffer": { + "globals": { + "console": true + }, "packages": { - "browserify>util>which-typed-array>for-each": true, - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>available-typed-arrays": true, - "string.prototype.matchall>es-abstract>gopd": true + "base64-js": true, + "buffer>ieee754": true } }, - "browserify>util>which-typed-array>for-each": { + "terser>source-map-support>buffer-from": { "packages": { - "string.prototype.matchall>es-abstract>is-callable": true + "browserify>buffer": true } }, - "browserify>vm-browserify": { - "globals": { - "document.body.appendChild": true, - "document.body.removeChild": true, - "document.createElement": true + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "packages": { + "browserify>buffer": true } }, - "buffer": { + "browserify>buffer": { "globals": { "console": true }, @@ -3468,20 +3387,33 @@ "buffer>ieee754": true } }, - "chalk": { + "@metamask/snaps-utils>validate-npm-package-name>builtins": { "packages": { - "chalk>ansi-styles": true, - "chalk>supports-color": true + "process": true, + "semver": true } }, - "chalk>ansi-styles": { + "string.prototype.matchall>call-bind": { "packages": { - "chalk>ansi-styles>color-convert": true + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>call-bind>set-function-length": true } }, - "chalk>ansi-styles>color-convert": { + "@ngraveio/bc-ur>cbor-sync": { + "globals": { + "define": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "browserify>buffer": true + } + }, + "chalk": { + "packages": { + "chalk>ansi-styles": true, + "chalk>supports-color": true } }, "chart.js": { @@ -3505,9 +3437,20 @@ "chart.js>@kurkle/color": true } }, - "chart.js>@kurkle/color": { - "globals": { - "define": true + "@ensdomains/content-hash>cids": { + "packages": { + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>cids>multihashes": true, + "@ensdomains/content-hash>cids>uint8arrays": true + } + }, + "ethereumjs-util>create-hash>cipher-base": { + "packages": { + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true, + "stream-browserify": true, + "browserify>string_decoder": true } }, "classnames": { @@ -3516,6 +3459,11 @@ "define": true } }, + "@metamask/jazzicon>color>clone": { + "packages": { + "browserify>buffer": true + } + }, "cockatiel": { "globals": { "AbortController": true, @@ -3529,6 +3477,37 @@ "process": true } }, + "chalk>ansi-styles>color-convert": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color>color-convert": { + "packages": { + "@metamask/jazzicon>color>color-convert>color-name": true + } + }, + "@metamask/jazzicon>color>color-string": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color": { + "packages": { + "@metamask/jazzicon>color>clone": true, + "@metamask/jazzicon>color>color-convert": true, + "@metamask/jazzicon>color>color-string": true + } + }, + "@metamask/snaps-controllers>concat-stream": { + "packages": { + "terser>source-map-support>buffer-from": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "readable-stream": true, + "browserify>concat-stream>typedarray": true + } + }, "copy-to-clipboard": { "globals": { "clipboardData": true, @@ -3547,10 +3526,47 @@ "copy-to-clipboard>toggle-selection": true } }, - "copy-to-clipboard>toggle-selection": { + "@ethereumjs/tx>@ethereumjs/common>crc-32": { "globals": { - "document.activeElement": true, - "document.getSelection": true + "DO_NOT_EXPORT_CRC": true, + "define": true + } + }, + "@ngraveio/bc-ur>crc": { + "packages": { + "browserify>buffer": true + } + }, + "crypto-browserify>create-ecdh": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "@metamask/ppom-validator>elliptic": true + } + }, + "ethereumjs-util>create-hash": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>md5.js": true, + "ethereumjs-util>create-hash>ripemd160": true, + "addons-linter>sha.js": true + } + }, + "crypto-browserify>create-hmac": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "ethereumjs-util>create-hash": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true + } + }, + "@metamask/snaps-utils>cron-parser": { + "packages": { + "browserify>browser-resolve": true, + "luxon": true } }, "crypto-browserify": { @@ -3558,303 +3574,453 @@ "crypto-browserify>browserify-cipher": true, "crypto-browserify>browserify-sign": true, "crypto-browserify>create-ecdh": true, + "ethereumjs-util>create-hash": true, "crypto-browserify>create-hmac": true, "crypto-browserify>diffie-hellman": true, "crypto-browserify>pbkdf2": true, "crypto-browserify>public-encrypt": true, "crypto-browserify>randombytes": true, - "crypto-browserify>randomfill": true, - "ethereumjs-util>create-hash": true + "crypto-browserify>randomfill": true } }, - "crypto-browserify>browserify-cipher": { + "@metamask/ppom-validator>crypto-js": { + "globals": { + "crypto": true, + "define": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "react-beautiful-dnd>css-box-model": { + "globals": { + "getComputedStyle": true, + "pageXOffset": true, + "pageYOffset": true + }, + "packages": { + "react-router-dom>tiny-invariant": true + } + }, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { + "globals": { + "document.createElement": true, + "document.documentElement": true, + "getComputedStyle": true + }, + "packages": { + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true + } + }, + "currency-formatter": { + "packages": { + "currency-formatter>accounting": true, + "currency-formatter>locale-currency": true, + "react>object-assign": true + } + }, + "debounce-stream": { + "packages": { + "debounce-stream>debounce": true, + "debounce-stream>duplexer": true, + "debounce-stream>through": true + } + }, + "debounce-stream>debounce": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "nock>debug": { + "globals": { + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true + }, + "packages": { + "nock>debug>ms": true, + "process": true + } + }, + "@metamask/eth-token-tracker>deep-equal": { + "packages": { + "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, + "string.prototype.matchall>call-bind": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, + "string.prototype.matchall>get-intrinsic": true, + "browserify>util>is-arguments": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "string.prototype.matchall>es-abstract>is-regex": true, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "@ngraveio/bc-ur>assert>object-is": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true, + "gulp>vinyl-fs>object.assign": true, + "string.prototype.matchall>regexp.prototype.flags": true, + "string.prototype.matchall>side-channel": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, + "@metamask/eth-token-tracker>deep-equal>which-collection": true, + "browserify>util>which-typed-array": true + } + }, + "string.prototype.matchall>define-properties>define-data-property": { + "packages": { + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>gopd": true + } + }, + "string.prototype.matchall>define-properties": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true + } + }, + "crypto-browserify>browserify-cipher>browserify-des>des.js": { "packages": { - "crypto-browserify>browserify-cipher>browserify-des": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true } }, - "crypto-browserify>browserify-cipher>browserify-des": { + "crypto-browserify>diffie-hellman": { "packages": { + "bn.js": true, "browserify>buffer": true, - "crypto-browserify>browserify-cipher>browserify-des>des.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "pumpify>inherits": true + "crypto-browserify>diffie-hellman>miller-rabin": true, + "crypto-browserify>randombytes": true } }, - "crypto-browserify>browserify-cipher>browserify-des>des.js": { + "@material-ui/core>react-transition-group>dom-helpers": { "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "@babel/runtime": true } }, - "crypto-browserify>browserify-cipher>evp_bytestokey": { + "debounce-stream>duplexer": { "packages": { - "ethereumjs-util>create-hash>md5.js": true, - "koa>content-disposition>safe-buffer": true + "stream-browserify": true } }, - "crypto-browserify>browserify-sign": { + "ethers>@ethersproject/signing-key>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "ethereumjs-util>create-hash": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, "pumpify>inherits": true, - "stream-browserify": true + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-ecdh": { + "@metamask/ppom-validator>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-hmac": { + "eth-lattice-keyring>gridplus-sdk>elliptic": { "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>diffie-hellman": { + "string.prototype.matchall>call-bind>es-define-property": { "packages": { - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>diffie-hellman>miller-rabin": true, - "crypto-browserify>randombytes": true + "string.prototype.matchall>get-intrinsic": true } }, - "crypto-browserify>diffie-hellman>miller-rabin": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "bn.js": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>has-symbols": true, + "browserify>util>is-arguments": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "eslint-plugin-react>array-includes>is-string": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "process": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true } }, - "crypto-browserify>pbkdf2": { + "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { "globals": { - "crypto": true, - "process": true, - "queueMicrotask": true, - "setImmediate": true, - "setTimeout": true + "intToBuffer": true }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "bn.js": true, + "buffer": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt": { + "eth-ens-namehash": { + "globals": { + "name": "write" + }, "packages": { - "bn.js": true, "browserify>buffer": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>create-hash": true + "eth-ens-namehash>idna-uts46-hx": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt>browserify-rsa": { + "eth-lattice-keyring": { + "globals": { + "addEventListener": true, + "browser": true, + "clearInterval": true, + "fetch": true, + "open": true, + "setInterval": true + }, "packages": { + "eth-lattice-keyring>@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, - "crypto-browserify>randombytes": true + "crypto-browserify": true, + "webpack>events": true, + "eth-lattice-keyring>gridplus-sdk": true, + "eth-lattice-keyring>rlp": true } }, - "crypto-browserify>public-encrypt>parse-asn1": { + "eth-method-registry": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "crypto-browserify>pbkdf2": true, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true } }, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "@ethereumjs/tx>ethereum-cryptography": { + "globals": { + "TextDecoder": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "bn.js": true, - "browserify>buffer": true, - "browserify>vm-browserify": true, - "pumpify>inherits": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "crypto-browserify>randombytes": { + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "crypto-browserify>randomfill": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "crypto-browserify>randombytes": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "currency-formatter": { + "ethereumjs-util>ethereum-cryptography": { "packages": { - "currency-formatter>accounting": true, - "currency-formatter>locale-currency": true, - "react>object-assign": true - } - }, - "currency-formatter>accounting": { - "globals": { - "define": true - } - }, - "currency-formatter>locale-currency": { - "globals": { - "countryCode": true + "browserify>buffer": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "ganache>secp256k1": true } }, - "debounce-stream": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { "packages": { - "debounce-stream>debounce": true, - "debounce-stream>duplexer": true, - "debounce-stream>through": true + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify>create-hmac": true, + "ethers>@ethersproject/sha2>hash.js": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true } }, - "debounce-stream>debounce": { - "globals": { - "clearTimeout": true, - "setTimeout": true + "ethereumjs-util": { + "packages": { + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "ethereumjs-util>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "ethereumjs-util>rlp": true } }, - "debounce-stream>duplexer": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { "packages": { - "stream-browserify": true + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true } }, - "debounce-stream>through": { + "@metamask/keyring-controller>ethereumjs-wallet": { "packages": { - "process": true, - "stream-browserify": true + "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, + "crypto-browserify>randombytes": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true, + "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, + "uuid": true } }, - "depcheck>@vue/compiler-sfc>postcss>nanoid": { - "globals": { - "crypto.getRandomValues": true + "ethers": { + "packages": { + "@ethersproject/abi": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/contracts": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/providers": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/solidity": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/units": true, + "@ethersproject/wallet": true, + "ethers>@ethersproject/web": true, + "ethers>@ethersproject/wordlists": true } }, - "depcheck>is-core-module>hasown": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": { "packages": { - "browserify>has>function-bind": true + "bn.js": true, + "browserify>buffer": true, + "eth-ens-namehash>js-sha3": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": true } }, - "dependency-tree>precinct>detective-postcss>postcss>nanoid": { + "webpack>events": { "globals": { - "crypto.getRandomValues": true + "console": true } }, - "eslint-plugin-react>array-includes>is-string": { + "crypto-browserify>browserify-cipher>evp_bytestokey": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash>md5.js": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-ens-namehash": { - "globals": { - "name": "write" - }, + "extension-port-stream": { "packages": { - "@metamask/ethjs>js-sha3": true, "browserify>buffer": true, - "eth-ens-namehash>idna-uts46-hx": true + "extension-port-stream>readable-stream": true } }, - "eth-ens-namehash>idna-uts46-hx": { + "fast-json-patch": { "globals": { - "define": true + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, + "@metamask/snaps-utils>fast-xml-parser": { + "globals": { + "entityName": true, + "val": true }, "packages": { - "browserify>punycode": true + "@metamask/snaps-utils>fast-xml-parser>strnum": true } }, - "eth-keyring-controller>@metamask/browser-passworder": { - "globals": { - "crypto": true + "@metamask/notification-services-controller>firebase": { + "packages": { + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/messaging": true } }, - "eth-lattice-keyring": { + "react-focus-lock>focus-lock": { "globals": { - "addEventListener": true, - "browser": true, - "clearInterval": true, - "fetch": true, - "open": true, - "setInterval": true + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify": true, - "eth-lattice-keyring>@ethereumjs/tx": true, - "eth-lattice-keyring>gridplus-sdk": true, - "eth-lattice-keyring>rlp": true, - "webpack>events": true + "tslib": true } }, - "eth-lattice-keyring>@ethereumjs/tx": { + "browserify>util>which-typed-array>for-each": { "packages": { - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>es-abstract>is-callable": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { - "packages": { - "browserify": true, - "browserify>buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true + "axios>form-data": { + "globals": { + "FormData": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { + "fuse.js": { "globals": { - "WeakRef": true - }, - "packages": { - "browserify": true + "console": true, + "define": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { + "string.prototype.matchall>get-intrinsic": { "globals": { - "TextDecoder": true, - "crypto": true + "AggregateError": true, + "FinalizationRegistry": true, + "WeakRef": true }, "packages": { - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true + "string.prototype.matchall>es-abstract>gopd": { + "packages": { + "string.prototype.matchall>get-intrinsic": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3872,230 +4038,307 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethersproject/abi": true, - "@metamask/ethjs>js-sha3": true, - "@metamask/keyring-api>bech32": true, - "bn.js": true, - "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": true, + "@ethersproject/abi": true, "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "@metamask/keyring-api>bech32": true, "eth-lattice-keyring>gridplus-sdk>bignumber.js": true, "eth-lattice-keyring>gridplus-sdk>bitwise": true, + "bn.js": true, "eth-lattice-keyring>gridplus-sdk>borc": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, "eth-lattice-keyring>gridplus-sdk>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, - "eth-lattice-keyring>gridplus-sdk>uuid": true, - "eth-lattice-keyring>rlp": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, "ethers>@ethersproject/sha2>hash.js": true, + "eth-ens-namehash>js-sha3": true, + "lodash": true, + "eth-lattice-keyring>rlp": true, "ganache>secp256k1": true, - "lodash": true + "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { + "string.prototype.matchall>es-abstract>has-property-descriptors": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "string.prototype.matchall>call-bind>es-define-property": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { + "koa>is-generator-function>has-tostringtag": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>has-symbols": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { + "ethereumjs-util>create-hash>md5.js>hash-base": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "pumpify>inherits": true, + "readable-stream": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { + "ethers>@ethersproject/sha2>hash.js": { + "packages": { + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true + } + }, + "depcheck>is-core-module>hasown": { + "packages": { + "browserify>has>function-bind": true + } + }, + "@metamask/eth-trezor-keyring>hdkey": { + "packages": { + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "crypto-browserify": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true + } + }, + "he": { "globals": { - "TextDecoder": true, - "crypto": true + "define": true + } + }, + "history": { + "globals": { + "console": true, + "define": true, + "document.defaultView": true, + "document.querySelector": true + } + }, + "react-router-dom>history": { + "globals": { + "addEventListener": true, + "confirm": true, + "document": true, + "history": true, + "location": true, + "navigator.userAgent": true, + "removeEventListener": true }, "packages": { - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "react-router-dom>history>resolve-pathname": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true, + "react-router-dom>history>value-equal": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "@metamask/ppom-validator>elliptic>hmac-drbg": { + "packages": { + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true + } + }, + "react-redux>hoist-non-react-statics": { + "packages": { + "prop-types>react-is": true + } + }, + "https-browserify": { + "packages": { + "stream-http": true, + "browserify>url": true + } + }, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": { "globals": { - "TextEncoder": true, - "crypto": true + "DOMException": true, + "IDBCursor": true, + "IDBDatabase": true, + "IDBIndex": true, + "IDBObjectStore": true, + "IDBRequest": true, + "IDBTransaction": true, + "indexedDB.deleteDatabase": true, + "indexedDB.open": true } }, - "eth-lattice-keyring>gridplus-sdk>aes-js": { + "eth-ens-namehash>idna-uts46-hx": { "globals": { "define": true + }, + "packages": { + "browserify>punycode": true + } + }, + "string.prototype.matchall>internal-slot": { + "packages": { + "string.prototype.matchall>call-bind>es-errors": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>side-channel": true + } + }, + "browserify>util>is-arguments": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true + } + }, + "string.prototype.matchall>es-abstract>is-array-buffer": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "packages": { + "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "string.prototype.matchall>es-abstract>is-callable": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>bitwise": { + "@metamask/eth-token-tracker>deep-equal>is-date-object": { "packages": { - "browserify>buffer": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc": { - "globals": { - "console": true - }, + "koa>is-generator-function": { "packages": { - "browserify>buffer": true, - "buffer>ieee754": true, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "@material-ui/core>@material-ui/styles>jss>is-in-browser": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { - "globals": { - "URL": true, - "URLSearchParams": true, - "location": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>elliptic": { + "string.prototype.matchall>es-abstract>is-regex": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { - "globals": { - "intToBuffer": true - }, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": { "packages": { - "@metamask/ethjs>js-sha3": true, - "bn.js": true, - "buffer": true + "string.prototype.matchall>call-bind": true } }, - "eth-lattice-keyring>gridplus-sdk>uuid": { - "globals": { - "crypto": true + "eslint-plugin-react>array-includes>is-string": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>rlp": { - "globals": { - "TextEncoder": true + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "packages": { + "string.prototype.matchall>has-symbols": true } }, - "eth-method-registry": { + "browserify>util>is-typed-array": { "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true + "browserify>util>which-typed-array": true } }, - "ethereumjs-util": { + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { "packages": { - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography": true, - "ethereumjs-util>rlp": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true } }, - "ethereumjs-util>create-hash": { + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { + "globals": { + "URL": true, + "URLSearchParams": true, + "location": true + } + }, + "@ensdomains/content-hash>js-base64": { + "globals": { + "Base64": "write", + "TextDecoder": true, + "TextEncoder": true, + "atob": true, + "btoa": true, + "define": true + }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>md5.js": true, - "ethereumjs-util>create-hash>ripemd160": true, - "pumpify>inherits": true + "browserify>buffer": true } }, - "ethereumjs-util>create-hash>cipher-base": { + "eth-ens-namehash>js-sha3": { + "globals": { + "define": true + }, "packages": { - "browserify>string_decoder": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "stream-browserify": true + "process": true } }, - "ethereumjs-util>create-hash>md5.js": { + "@ngraveio/bc-ur>jsbi": { + "globals": { + "define": true + } + }, + "@metamask/message-manager>jsonschema": { "packages": { - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "browserify>url": true } }, - "ethereumjs-util>create-hash>md5.js>hash-base": { + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "readable-stream": true + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true } }, - "ethereumjs-util>create-hash>ripemd160": { + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { + "globals": { + "CSS": true + }, "packages": { - "browserify>buffer": true, - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "pumpify>inherits": true + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography": { + "@material-ui/core>@material-ui/styles>jss-plugin-global": { "packages": { - "browserify>buffer": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ganache>secp256k1": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes": { + "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@babel/runtime": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { - "browserify>buffer": true + "@material-ui/core>@material-ui/styles>jss": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check": { + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { "packages": { - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, - "koa>content-disposition>safe-buffer": true + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { + "@material-ui/core>@material-ui/styles>jss": { + "globals": { + "CSS": true, + "document.createElement": true, + "document.querySelector": true + }, "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, + "react-router-dom>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4104,536 +4347,496 @@ "readable-stream": true } }, - "ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "currency-formatter>locale-currency": { + "globals": { + "countryCode": true } }, - "ethereumjs-wallet>randombytes": { + "localforage": { "globals": { - "crypto.getRandomValues": true + "Blob": true, + "BlobBuilder": true, + "FileReader": true, + "IDBKeyRange": true, + "MSBlobBuilder": true, + "MozBlobBuilder": true, + "OIndexedDB": true, + "WebKitBlobBuilder": true, + "atob": true, + "btoa": true, + "console.error": true, + "console.info": true, + "console.warn": true, + "define": true, + "fetch": true, + "indexedDB": true, + "localStorage": true, + "mozIndexedDB": true, + "msIndexedDB": true, + "navigator.platform": true, + "navigator.userAgent": true, + "openDatabase": true, + "setTimeout": true, + "webkitIndexedDB": true } }, - "ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/web": true, - "ethers>@ethersproject/wordlists": true + "lodash": { + "globals": { + "clearTimeout": true, + "define": true, + "setTimeout": true } }, - "ethers>@ethersproject/abstract-provider": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "loglevel": { + "globals": { + "console": true, + "define": true, + "document.cookie": true, + "localStorage": true, + "log": "write", + "navigator": true } }, - "ethers>@ethersproject/abstract-signer": { - "packages": { - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "lottie-web": { + "globals": { + "Blob": true, + "Howl": true, + "OffscreenCanvas": true, + "URL.createObjectURL": true, + "Worker": true, + "XMLHttpRequest": true, + "bodymovin": "write", + "clearInterval": true, + "console": true, + "define": true, + "document.body": true, + "document.createElement": true, + "document.createElementNS": true, + "document.getElementsByClassName": true, + "document.getElementsByTagName": true, + "document.querySelectorAll": true, + "document.readyState": true, + "location.origin": true, + "location.pathname": true, + "navigator": true, + "requestAnimationFrame": true, + "setInterval": true, + "setTimeout": true } }, - "ethers>@ethersproject/address": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/rlp": true + "luxon": { + "globals": { + "Intl": true } }, - "ethers>@ethersproject/base64": { + "@metamask/snaps-utils>marked": { "globals": { - "atob": true, - "btoa": true - }, - "packages": { - "@ethersproject/bytes": true + "console.error": true, + "console.warn": true, + "define": true } }, - "ethers>@ethersproject/basex": { + "ethereumjs-util>create-hash>md5.js": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/properties": true + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "ethers>@ethersproject/constants": { + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { "packages": { - "@ethersproject/bignumber": true + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/json-wallets": { + "react-markdown>remark-parse>mdast-util-from-markdown": { "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets>aes-js": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/pbkdf2": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "ethers>@ethersproject/json-wallets>aes-js": { - "globals": { - "define": true + "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true } }, - "ethers>@ethersproject/json-wallets>scrypt-js": { + "react-markdown>remark-rehype>mdast-util-to-hast": { "globals": { - "define": true, - "setTimeout": true + "console.warn": true }, "packages": { - "browserify>timers-browserify": true - } - }, - "ethers>@ethersproject/keccak256": { - "packages": { - "@ethersproject/bytes": true, - "@metamask/ethjs>js-sha3": true + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, + "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/logger": { + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { "globals": { - "console": true + "Headers": true, + "TextDecoder": true, + "URL": true, + "btoa": true, + "fetch": true + }, + "packages": { + "browserify>browserify-zlib": true, + "browserify>buffer": true, + "https-browserify": true, + "process": true, + "stream-http": true, + "browserify>url": true, + "browserify>util": true } }, - "ethers>@ethersproject/pbkdf2": { + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/sha2": true + "react-syntax-highlighter>refractor>parse-entities": true } }, - "ethers>@ethersproject/properties": { + "crypto-browserify>diffie-hellman>miller-rabin": { "packages": { - "ethers>@ethersproject/logger": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true } }, - "ethers>@ethersproject/providers": { + "@ensdomains/content-hash>cids>multibase": { "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers>@ethersproject/networks": true, - "ethers>@ethersproject/providers>@ethersproject/web": true, - "ethers>@ethersproject/providers>bech32": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true + "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true } }, - "ethers>@ethersproject/providers>@ethersproject/networks": { + "@ensdomains/content-hash>multihashes>multibase": { "packages": { - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true, + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, + "@ensdomains/content-hash>multicodec": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@ensdomains/content-hash>multicodec>uint8arrays": true, + "sass-embedded>varint": true } }, - "ethers>@ethersproject/random": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "console.warn": true, + "crypto.subtle.digest": true } }, - "ethers>@ethersproject/rlp": { + "@ensdomains/content-hash>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>multibase": true, + "@ensdomains/content-hash>multihashes>varint": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/sha2": { + "@ensdomains/content-hash>cids>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2>hash.js": true + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>cids>uint8arrays": true, + "@ensdomains/content-hash>cids>multihashes>varint": true } }, - "ethers>@ethersproject/sha2>hash.js": { - "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/signing-key>elliptic": true + "@metamask/approval-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/solidity": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true + "@metamask/notification-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/strings": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true + "@metamask/permission-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/transactions": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/signing-key": true + "@metamask/rpc-methods>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/units": { - "packages": { - "@ethersproject/bignumber": true, - "ethers>@ethersproject/logger": true + "@metamask/rpc-methods-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/web": { + "@metamask/snaps-controllers>nanoid": { "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/wordlists": { - "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@metamask/snaps-controllers-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream": { - "packages": { - "browserify>buffer": true, - "extension-port-stream>readable-stream": true + "depcheck>@vue/compiler-sfc>postcss>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream": { + "dependency-tree>precinct>detective-postcss>postcss>nanoid": { "globals": { - "AbortController": true, - "AggregateError": true, - "Blob": true - }, - "packages": { - "browserify>buffer": true, - "browserify>string_decoder": true, - "extension-port-stream>readable-stream>abort-controller": true, - "process": true, - "webpack>events": true + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream>abort-controller": { + "node-fetch": { "globals": { - "AbortController": true + "Headers": true, + "Request": true, + "Response": true, + "fetch": true } }, - "fast-json-patch": { + "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true + "fetch": true } }, - "fuse.js": { + "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { "globals": { - "console": true, - "define": true + "fetch": true } }, - "ganache>secp256k1": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": { "packages": { - "@metamask/ppom-validator>elliptic": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true + } + }, + "string.prototype.matchall>es-abstract>object-inspect": { + "globals": { + "HTMLElement": true, + "WeakRef": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "@ngraveio/bc-ur>assert>object-is": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true } }, "gulp>vinyl-fs>object.assign": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>has-symbols": true + "string.prototype.matchall>has-symbols": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "he": { - "globals": { - "define": true + "@metamask/object-multiplex>once": { + "packages": { + "@metamask/object-multiplex>once>wrappy": true } }, - "history": { + "crypto-browserify>public-encrypt>parse-asn1": { + "packages": { + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "browserify>buffer": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "crypto-browserify>pbkdf2": true + } + }, + "react-syntax-highlighter>refractor>parse-entities": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true + "document.createElement": true } }, - "https-browserify": { + "path-browserify": { "packages": { - "browserify>url": true, - "stream-http": true + "process": true } }, - "koa>content-disposition>safe-buffer": { + "serve-handler>path-to-regexp": { "packages": { - "browserify>buffer": true + "serve-handler>path-to-regexp>isarray": true } }, - "koa>is-generator-function": { + "crypto-browserify>pbkdf2": { + "globals": { + "crypto": true, + "process": true, + "queueMicrotask": true, + "setImmediate": true, + "setTimeout": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash": true, + "process": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true } }, - "koa>is-generator-function>has-tostringtag": { - "packages": { - "string.prototype.matchall>has-symbols": true + "@material-ui/core>popper.js": { + "globals": { + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, + "console.warn": true, + "define": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator": true, + "requestAnimationFrame": true, + "setTimeout": true } }, - "localforage": { + "react-tippy>popper.js": { "globals": { - "Blob": true, - "BlobBuilder": true, - "FileReader": true, - "IDBKeyRange": true, - "MSBlobBuilder": true, - "MozBlobBuilder": true, - "OIndexedDB": true, - "WebKitBlobBuilder": true, - "atob": true, - "btoa": true, - "console.error": true, - "console.info": true, + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, "console.warn": true, "define": true, - "fetch": true, - "indexedDB": true, - "localStorage": true, - "mozIndexedDB": true, - "msIndexedDB": true, - "navigator.platform": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, "navigator.userAgent": true, - "openDatabase": true, - "setTimeout": true, - "webkitIndexedDB": true + "requestAnimationFrame": true, + "setTimeout": true } }, - "lodash": { + "process": { "globals": { "clearTimeout": true, - "define": true, "setTimeout": true } }, - "loglevel": { + "promise-to-callback": { + "packages": { + "promise-to-callback>is-fn": true, + "promise-to-callback>set-immediate-shim": true + } + }, + "prop-types": { "globals": { - "console": true, - "define": true, - "document.cookie": true, - "localStorage": true, - "log": "write", - "navigator": true + "console": true + }, + "packages": { + "react>object-assign": true, + "prop-types>react-is": true } }, - "lottie-web": { + "react-markdown>property-information": { + "packages": { + "watchify>xtend": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { "globals": { - "Blob": true, - "Howl": true, - "OffscreenCanvas": true, - "URL.createObjectURL": true, - "Worker": true, - "XMLHttpRequest": true, - "bodymovin": "write", - "clearInterval": true, - "console": true, - "define": true, - "document.body": true, - "document.createElement": true, - "document.createElementNS": true, - "document.getElementsByClassName": true, - "document.getElementsByTagName": true, - "document.querySelectorAll": true, - "document.readyState": true, - "location.origin": true, - "location.pathname": true, - "navigator": true, - "requestAnimationFrame": true, - "setInterval": true, + "process": true, "setTimeout": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true } }, - "luxon": { + "crypto-browserify>public-encrypt": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "crypto-browserify>randombytes": true + } + }, + "browserify>punycode": { "globals": { - "Intl": true + "define": true } }, - "nanoid": { + "qrcode-generator": { "globals": { - "crypto.getRandomValues": true + "define": true } }, - "nock>debug": { + "qrcode.react": { "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "Path2D": true, + "devicePixelRatio": true }, "packages": { - "nock>debug>ms": true, - "process": true - } - }, - "node-fetch": { - "globals": { - "Headers": true, - "Request": true, - "Response": true, - "fetch": true + "react": true } }, - "path-browserify": { + "@storybook/addon-knobs>qs": { "packages": { - "process": true + "string.prototype.matchall>side-channel": true } }, - "process": { + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { "globals": { - "clearTimeout": true, - "setTimeout": true - } - }, - "promise-to-callback": { - "packages": { - "promise-to-callback>is-fn": true, - "promise-to-callback>set-immediate-shim": true + "queueMicrotask": true } }, - "promise-to-callback>set-immediate-shim": { + "react-beautiful-dnd>raf-schd": { "globals": { - "setTimeout.apply": true - }, - "packages": { - "browserify>timers-browserify": true + "cancelAnimationFrame": true, + "requestAnimationFrame": true } }, - "prop-types": { + "crypto-browserify>randombytes": { "globals": { - "console": true + "crypto": true, + "msCrypto": true }, "packages": { - "prop-types>react-is": true, - "react>object-assign": true - } - }, - "prop-types>react-is": { - "globals": { - "console": true + "process": true, + "koa>content-disposition>safe-buffer": true } }, - "qrcode-generator": { + "ethereumjs-wallet>randombytes": { "globals": { - "define": true + "crypto.getRandomValues": true } }, - "qrcode.react": { + "crypto-browserify>randomfill": { "globals": { - "Path2D": true, - "devicePixelRatio": true + "crypto": true, + "msCrypto": true }, "packages": { - "react": true + "process": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true } }, "react": { @@ -4641,8 +4844,8 @@ "console": true }, "packages": { - "prop-types": true, - "react>object-assign": true + "react>object-assign": true, + "prop-types": true } }, "react-beautiful-dnd": { @@ -4664,43 +4867,28 @@ }, "packages": { "@babel/runtime": true, - "react": true, "react-beautiful-dnd>css-box-model": true, "react-beautiful-dnd>memoize-one": true, "react-beautiful-dnd>raf-schd": true, - "react-beautiful-dnd>use-memo-one": true, + "react": true, "react-dom": true, "react-redux": true, - "redux": true + "redux": true, + "react-beautiful-dnd>use-memo-one": true } }, - "react-beautiful-dnd>css-box-model": { + "react-chartjs-2": { "globals": { - "getComputedStyle": true, - "pageXOffset": true, - "pageYOffset": true + "setTimeout": true }, "packages": { - "react-router-dom>tiny-invariant": true - } - }, - "react-beautiful-dnd>raf-schd": { - "globals": { - "cancelAnimationFrame": true, - "requestAnimationFrame": true - } - }, - "react-beautiful-dnd>use-memo-one": { - "packages": { + "chart.js": true, "react": true } }, - "react-chartjs-2": { - "globals": { - "setTimeout": true - }, + "react-focus-lock>react-clientside-effect": { "packages": { - "chart.js": true, + "@babel/runtime": true, "react": true } }, @@ -4745,22 +4933,28 @@ "trustedTypes": true }, "packages": { + "react>object-assign": true, "prop-types": true, "react": true, - "react-dom>scheduler": true, - "react>object-assign": true + "react-dom>scheduler": true } }, - "react-dom>scheduler": { + "react-responsive-carousel>react-easy-swipe": { "globals": { - "MessageChannel": true, - "cancelAnimationFrame": true, - "clearTimeout": true, - "console": true, - "navigator": true, - "performance": true, - "requestAnimationFrame": true, - "setTimeout": true + "addEventListener": true, + "define": true, + "document.addEventListener": true, + "document.removeEventListener": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-popper>react-fast-compare": { + "globals": { + "Element": true, + "console.warn": true } }, "react-focus-lock": { @@ -4774,667 +4968,726 @@ }, "packages": { "@babel/runtime": true, + "react-focus-lock>focus-lock": true, "prop-types": true, "react": true, - "react-focus-lock>focus-lock": true, "react-focus-lock>react-clientside-effect": true, "react-focus-lock>use-callback-ref": true, "react-focus-lock>use-sidecar": true } }, - "react-focus-lock>focus-lock": { + "react-idle-timer": { "globals": { - "HTMLIFrameElement": true, - "Node.DOCUMENT_FRAGMENT_NODE": true, - "Node.DOCUMENT_NODE": true, - "Node.DOCUMENT_POSITION_CONTAINED_BY": true, - "Node.DOCUMENT_POSITION_CONTAINS": true, - "Node.ELEMENT_NODE": true, - "console.error": true, + "clearTimeout": true, + "document": true, + "setTimeout": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-inspector": { + "globals": { + "Node": true, + "chromeDark": true, + "chromeLight": true + }, + "packages": { + "react": true + } + }, + "prop-types>react-is": { + "globals": { + "console": true + } + }, + "react-markdown>react-is": { + "globals": { + "console": true + } + }, + "react-redux>react-is": { + "globals": { + "console": true + } + }, + "react-markdown": { + "globals": { + "console.warn": true + }, + "packages": { + "react-markdown>comma-separated-tokens": true, + "prop-types": true, + "react-markdown>property-information": true, + "react": true, + "react-markdown>react-is": true, + "react-markdown>remark-parse": true, + "react-markdown>remark-rehype": true, + "react-markdown>space-separated-tokens": true, + "react-markdown>style-to-object": true, + "react-markdown>unified": true, + "react-markdown>unist-util-visit": true, + "react-markdown>vfile": true + } + }, + "react-popper": { + "globals": { + "document": true + }, + "packages": { + "@popperjs/core": true, + "react": true, + "react-popper>react-fast-compare": true, + "react-popper>warning": true + } + }, + "react-redux": { + "globals": { + "console": true, + "document": true + }, + "packages": { + "@babel/runtime": true, + "react-redux>hoist-non-react-statics": true, + "prop-types": true, + "react": true, + "react-dom": true, + "react-redux>react-is": true + } + }, + "react-responsive-carousel": { + "globals": { + "HTMLElement": true, + "addEventListener": true, + "clearTimeout": true, "console.warn": true, "document": true, - "getComputedStyle": true, + "getComputedStyle": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "classnames": true, + "react": true, + "react-dom": true, + "react-responsive-carousel>react-easy-swipe": true + } + }, + "react-router-dom": { + "packages": { + "react-router-dom>history": true, + "prop-types": true, + "react": true, + "react-router-dom>react-router": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true + } + }, + "react-router-dom-v5-compat": { + "globals": { + "FormData": true, + "URL": true, + "URLSearchParams": true, + "__reactRouterVersion": "write", + "addEventListener": true, + "confirm": true, + "define": true, + "document": true, + "history.scrollRestoration": true, + "location.href": true, + "removeEventListener": true, + "scrollTo": true, + "scrollY": true, + "sessionStorage.getItem": true, + "sessionStorage.setItem": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true + "react-router-dom-v5-compat>@remix-run/router": true, + "history": true, + "react": true, + "react-dom": true, + "react-router-dom": true, + "react-router-dom-v5-compat>react-router": true } }, - "react-focus-lock>react-clientside-effect": { + "react-router-dom>react-router": { "packages": { - "@babel/runtime": true, - "react": true + "react-router-dom>history": true, + "react-redux>hoist-non-react-statics": true, + "serve-handler>path-to-regexp": true, + "prop-types": true, + "react": true, + "prop-types>react-is": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true } }, - "react-focus-lock>use-callback-ref": { + "react-router-dom-v5-compat>react-router": { + "globals": { + "console.error": true, + "define": true + }, "packages": { + "react-router-dom-v5-compat>@remix-run/router": true, "react": true } }, - "react-focus-lock>use-sidecar": { + "react-simple-file-input": { "globals": { - "console.error": true + "File": true, + "FileReader": true, + "console.warn": true }, "packages": { - "@swc/helpers>tslib": true, - "react": true, - "react-focus-lock>use-sidecar>detect-node-es": true + "prop-types": true, + "react": true } }, - "react-idle-timer": { + "react-tippy": { "globals": { + "Element": true, + "MSStream": true, + "MutationObserver": true, + "addEventListener": true, "clearTimeout": true, + "console.error": true, + "console.warn": true, + "define": true, "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator.maxTouchPoints": true, + "navigator.msMaxTouchPoints": true, + "navigator.userAgent": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "react-tippy>popper.js": true, + "react": true, + "react-dom": true } }, - "react-inspector": { + "react-toggle-button": { "globals": { - "Node": true, - "chromeDark": true, - "chromeLight": true + "clearTimeout": true, + "console.warn": true, + "define": true, + "performance": true, + "setTimeout": true }, "packages": { "react": true } }, - "react-markdown": { + "@material-ui/core>react-transition-group": { "globals": { - "console.warn": true + "Element": true, + "setTimeout": true }, "packages": { + "@material-ui/core>react-transition-group>dom-helpers": true, "prop-types": true, "react": true, - "react-markdown>comma-separated-tokens": true, - "react-markdown>property-information": true, - "react-markdown>react-is": true, - "react-markdown>remark-parse": true, - "react-markdown>remark-rehype": true, - "react-markdown>space-separated-tokens": true, - "react-markdown>style-to-object": true, - "react-markdown>unified": true, - "react-markdown>unist-util-visit": true, - "react-markdown>vfile": true + "react-dom": true } }, - "react-markdown>property-information": { + "readable-stream": { "packages": { - "watchify>xtend": true + "browserify>browser-resolve": true, + "browserify>buffer": true, + "webpack>events": true, + "pumpify>inherits": true, + "process": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true } }, - "react-markdown>react-is": { + "extension-port-stream>readable-stream": { "globals": { - "console": true - } - }, - "react-markdown>remark-parse": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, - "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true, - "react-syntax-highlighter>refractor>parse-entities": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "queueMicrotask": true + }, "packages": { - "react-syntax-highlighter>refractor>parse-entities": true + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "browserify>buffer": true, + "webpack>events": true, + "process": true, + "browserify>string_decoder": true } }, - "react-markdown>remark-rehype": { + "@metamask/snaps-controllers>readable-web-to-node-stream": { "packages": { - "react-markdown>remark-rehype>mdast-util-to-hast": true + "readable-stream": true } }, - "react-markdown>remark-rehype>mdast-util-to-hast": { + "redux": { "globals": { - "console.warn": true + "console": true }, "packages": { - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, - "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, - "react-markdown>unist-util-visit": true + "@babel/runtime": true } }, - "react-markdown>style-to-object": { + "string.prototype.matchall>regexp.prototype.flags": { "packages": { - "react-markdown>style-to-object>inline-style-parser": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": true } }, - "react-markdown>unified": { + "react-markdown>remark-parse": { "packages": { - "mocha>yargs-unparser>is-plain-obj": true, - "react-markdown>unified>bail": true, - "react-markdown>unified>extend": true, - "react-markdown>unified>is-buffer": true, - "react-markdown>unified>trough": true, - "react-markdown>vfile": true + "react-markdown>remark-parse>mdast-util-from-markdown": true } }, - "react-markdown>unist-util-visit": { + "react-markdown>remark-rehype": { "packages": { - "react-markdown>unist-util-visit>unist-util-visit-parents": true + "react-markdown>remark-rehype>mdast-util-to-hast": true } }, - "react-markdown>unist-util-visit>unist-util-visit-parents": { + "react-markdown>vfile>replace-ext": { "packages": { - "react-markdown>unist-util-visit>unist-util-is": true + "path-browserify": true } }, - "react-markdown>vfile": { - "packages": { - "path-browserify": true, - "process": true, - "react-markdown>vfile>is-buffer": true, - "react-markdown>vfile>replace-ext": true, - "react-markdown>vfile>vfile-message": true + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true } }, - "react-markdown>vfile>replace-ext": { + "@metamask/snaps-utils>rfdc": { "packages": { - "path-browserify": true + "browserify>buffer": true } }, - "react-markdown>vfile>vfile-message": { + "ethereumjs-util>create-hash>ripemd160": { "packages": { - "react-markdown>vfile>unist-util-stringify-position": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true } }, - "react-popper": { - "globals": { - "document": true - }, + "@keystonehq/metamask-airgapped-keyring>rlp": { "packages": { - "@popperjs/core": true, - "react": true, - "react-popper>react-fast-compare": true, - "react-popper>warning": true - } - }, - "react-popper>react-fast-compare": { - "globals": { - "Element": true, - "console.warn": true + "bn.js": true, + "browserify>buffer": true } }, - "react-popper>warning": { + "eth-lattice-keyring>rlp": { "globals": { - "console": true + "TextEncoder": true } }, - "react-redux": { - "globals": { - "console": true, - "document": true - }, + "ethereumjs-util>rlp": { "packages": { - "@babel/runtime": true, - "prop-types": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true, - "react-redux>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>hoist-non-react-statics": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { "packages": { - "prop-types>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>react-is": { + "wait-on>rxjs": { "globals": { - "console": true + "cancelAnimationFrame": true, + "clearInterval": true, + "clearTimeout": true, + "performance": true, + "requestAnimationFrame": true, + "setInterval.apply": true, + "setTimeout.apply": true } }, - "react-responsive-carousel": { + "koa>content-disposition>safe-buffer": { + "packages": { + "browserify>buffer": true + } + }, + "react-dom>scheduler": { "globals": { - "HTMLElement": true, - "addEventListener": true, + "MessageChannel": true, + "cancelAnimationFrame": true, "clearTimeout": true, - "console.warn": true, - "document": true, - "getComputedStyle": true, - "removeEventListener": true, + "console": true, + "navigator": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true - }, - "packages": { - "classnames": true, - "react": true, - "react-dom": true, - "react-responsive-carousel>react-easy-swipe": true } }, - "react-responsive-carousel>react-easy-swipe": { + "ethers>@ethersproject/json-wallets>scrypt-js": { "globals": { - "addEventListener": true, "define": true, - "document.addEventListener": true, - "document.removeEventListener": true + "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "browserify>timers-browserify": true } }, - "react-router-dom": { + "ganache>secp256k1": { "packages": { - "prop-types": true, - "react": true, - "react-router-dom>history": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "@metamask/ppom-validator>elliptic": true } }, - "react-router-dom-v5-compat": { + "semver": { "globals": { - "FormData": true, - "URL": true, - "URLSearchParams": true, - "__reactRouterVersion": "write", - "addEventListener": true, - "confirm": true, - "define": true, - "document": true, - "history.scrollRestoration": true, - "location.href": true, - "removeEventListener": true, - "scrollTo": true, - "scrollY": true, - "sessionStorage.getItem": true, - "sessionStorage.setItem": true, - "setTimeout": true + "console.error": true }, "packages": { - "history": true, - "react": true, - "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>@remix-run/router": true, - "react-router-dom-v5-compat>react-router": true + "process": true } }, - "react-router-dom-v5-compat>@remix-run/router": { - "globals": { - "AbortController": true, - "DOMException": true, - "FormData": true, - "Headers": true, - "Request": true, - "Response": true, - "URL": true, - "URLSearchParams": true, - "console": true, - "document.defaultView": true + "string.prototype.matchall>call-bind>set-function-length": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom-v5-compat>react-router": { - "globals": { - "console.error": true, - "define": true - }, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": { "packages": { - "react": true, - "react-router-dom-v5-compat>@remix-run/router": true + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom>history": { + "promise-to-callback>set-immediate-shim": { "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true + "setTimeout.apply": true }, "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>history>value-equal": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "browserify>timers-browserify": true } }, - "react-router-dom>react-router": { + "addons-linter>sha.js": { "packages": { - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-redux>hoist-non-react-statics": true, - "react-router-dom>history": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "serve-handler>path-to-regexp": true + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "react-router-dom>tiny-warning": { - "globals": { - "console": true + "string.prototype.matchall>side-channel": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>object-inspect": true } }, - "react-simple-file-input": { + "@metamask/profile-sync-controller>siwe": { "globals": { - "File": true, - "FileReader": true, + "console.error": true, "console.warn": true }, "packages": { - "prop-types": true, - "react": true + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random": true, + "ethers": true, + "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true } }, - "react-syntax-highlighter>refractor>parse-entities": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { "globals": { - "document.createElement": true + "StopIteration": true + }, + "packages": { + "string.prototype.matchall>internal-slot": true } }, - "react-tippy": { + "stream-browserify": { + "packages": { + "webpack>events": true, + "pumpify>inherits": true, + "readable-stream": true + } + }, + "stream-http": { "globals": { - "Element": true, - "MSStream": true, - "MutationObserver": true, - "addEventListener": true, + "AbortController": true, + "Blob": true, + "MSStreamReader": true, + "ReadableStream": true, + "WritableStream": true, + "XDomainRequest": true, + "XMLHttpRequest": true, "clearTimeout": true, - "console.error": true, - "console.warn": true, - "define": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.maxTouchPoints": true, - "navigator.msMaxTouchPoints": true, - "navigator.userAgent": true, - "performance": true, - "requestAnimationFrame": true, + "fetch": true, + "location.protocol.search": true, "setTimeout": true }, "packages": { - "react": true, - "react-dom": true, - "react-tippy>popper.js": true + "browserify>buffer": true, + "stream-http>builtin-status-codes": true, + "pumpify>inherits": true, + "process": true, + "readable-stream": true, + "browserify>url": true, + "watchify>xtend": true } }, - "react-tippy>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.userAgent": true, - "requestAnimationFrame": true, - "setTimeout": true + "@metamask/snaps-controllers>tar-stream>streamx": { + "packages": { + "webpack>events": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true } }, - "react-toggle-button": { - "globals": { - "clearTimeout": true, - "console.warn": true, - "define": true, - "performance": true, - "setTimeout": true - }, + "browserify>string_decoder": { "packages": { - "react": true + "koa>content-disposition>safe-buffer": true } }, - "readable-stream": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": { "packages": { - "browserify>browser-resolve": true, - "browserify>buffer": true, - "browserify>string_decoder": true, - "process": true, - "pumpify>inherits": true, - "readable-stream>util-deprecate": true, - "webpack>events": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true } }, - "readable-stream>util-deprecate": { - "globals": { - "console.trace": true, - "console.warn": true, - "localStorage": true + "react-markdown>style-to-object": { + "packages": { + "react-markdown>style-to-object>inline-style-parser": true } }, - "redux": { - "globals": { - "console": true - }, + "@metamask/snaps-controllers>tar-stream": { "packages": { - "@babel/runtime": true + "@metamask/snaps-controllers>tar-stream>b4a": true, + "browserify>browser-resolve": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx": true } }, - "reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true + "debounce-stream>through": { + "packages": { + "process": true, + "stream-browserify": true } }, - "semver": { + "browserify>timers-browserify": { "globals": { - "console.error": true + "clearInterval": true, + "clearTimeout": true, + "setInterval": true, + "setTimeout": true }, "packages": { "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true + "react-router-dom>tiny-warning": { + "globals": { + "console": true } }, - "stream-browserify": { - "packages": { - "pumpify>inherits": true, - "readable-stream": true, - "webpack>events": true + "copy-to-clipboard>toggle-selection": { + "globals": { + "document.activeElement": true, + "document.getSelection": true + } + }, + "tslib": { + "globals": { + "SuppressedError": true, + "define": true } }, - "stream-http": { + "@metamask/eth-sig-util>tweetnacl": { "globals": { - "AbortController": true, - "Blob": true, - "MSStreamReader": true, - "ReadableStream": true, - "WritableStream": true, - "XDomainRequest": true, - "XMLHttpRequest": true, - "clearTimeout": true, - "fetch": true, - "location.protocol.search": true, - "setTimeout": true + "crypto": true, + "msCrypto": true, + "nacl": "write" }, "packages": { - "browserify>buffer": true, - "browserify>url": true, - "process": true, - "pumpify>inherits": true, - "readable-stream": true, - "stream-http>builtin-status-codes": true, - "watchify>xtend": true + "browserify>browser-resolve": true } }, - "string.prototype.matchall>call-bind": { - "packages": { - "browserify>has>function-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>call-bind>set-function-length": true, - "string.prototype.matchall>get-intrinsic": true + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>call-bind>es-define-property": { + "@ensdomains/content-hash>cids>uint8arrays": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>cids>multibase": true } }, - "string.prototype.matchall>call-bind>set-function-length": { + "@ensdomains/content-hash>multicodec>uint8arrays": { + "globals": { + "Buffer": true, + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "string.prototype.matchall>define-properties": { + "react-markdown>unified": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "react-markdown>unified>bail": true, + "react-markdown>unified>extend": true, + "react-markdown>unified>is-buffer": true, + "mocha>yargs-unparser>is-plain-obj": true, + "react-markdown>unified>trough": true, + "react-markdown>vfile": true } }, - "string.prototype.matchall>define-properties>define-data-property": { + "react-markdown>unist-util-visit>unist-util-visit-parents": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "react-markdown>unist-util-visit>unist-util-is": true } }, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "react-markdown>unist-util-visit": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true + "react-markdown>unist-util-visit>unist-util-visit-parents": true } }, - "string.prototype.matchall>es-abstract>available-typed-arrays": { - "packages": { - "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true + "uri-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "browserify>url": { "packages": { - "string.prototype.matchall>has-symbols": true + "browserify>punycode": true, + "@storybook/addon-knobs>qs": true } }, - "string.prototype.matchall>es-abstract>gopd": { + "react-focus-lock>use-callback-ref": { "packages": { - "string.prototype.matchall>get-intrinsic": true + "react": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "react-beautiful-dnd>use-memo-one": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true + "react": true } }, - "string.prototype.matchall>es-abstract>is-array-buffer": { + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "react-focus-lock>use-sidecar>detect-node-es": true, + "react": true, + "tslib": true } }, - "string.prototype.matchall>es-abstract>is-callable": { + "readable-stream>util-deprecate": { "globals": { - "document": true + "console.trace": true, + "console.warn": true, + "localStorage": true } }, - "string.prototype.matchall>es-abstract>is-regex": { + "browserify>assert>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true, + "process": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "browserify>assert>util>inherits": true, + "process": true } }, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": { + "browserify>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true + }, "packages": { - "string.prototype.matchall>call-bind": true + "pumpify>inherits": true, + "browserify>util>is-arguments": true, + "koa>is-generator-function": true, + "browserify>util>is-typed-array": true, + "process": true, + "browserify>util>which-typed-array": true } }, - "string.prototype.matchall>es-abstract>object-inspect": { + "uuid": { "globals": { - "HTMLElement": true, - "WeakRef": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "msCrypto": true } }, - "string.prototype.matchall>get-intrinsic": { + "@metamask/eth-snap-keyring>uuid": { "globals": { - "AggregateError": true, - "FinalizationRegistry": true, - "WeakRef": true - }, - "packages": { - "browserify>has>function-bind": true, - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true + "crypto": true } }, - "string.prototype.matchall>internal-slot": { - "packages": { - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>side-channel": true + "@metamask/keyring-snap-client>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eth-lattice-keyring>gridplus-sdk>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "web3-stream-provider>uuid": { + "globals": { + "crypto": true + } + }, + "@metamask/snaps-utils>validate-npm-package-name": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "@metamask/snaps-utils>validate-npm-package-name>builtins": true } }, - "string.prototype.matchall>side-channel": { + "react-markdown>vfile>vfile-message": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>get-intrinsic": true + "react-markdown>vfile>unist-util-stringify-position": true } }, - "terser>source-map-support>buffer-from": { + "react-markdown>vfile": { "packages": { - "browserify>buffer": true + "react-markdown>vfile>is-buffer": true, + "path-browserify": true, + "process": true, + "react-markdown>vfile>replace-ext": true, + "react-markdown>vfile>vfile-message": true } }, - "uri-js": { + "browserify>vm-browserify": { "globals": { - "define": true + "document.body.appendChild": true, + "document.body.removeChild": true, + "document.createElement": true } }, - "uuid": { + "react-popper>warning": { "globals": { - "crypto": true, - "msCrypto": true + "console": true } }, - "wait-on>rxjs": { + "@ensdomains/content-hash>multihashes>web-encoding": { "globals": { - "cancelAnimationFrame": true, - "clearInterval": true, - "clearTimeout": true, - "performance": true, - "requestAnimationFrame": true, - "setInterval.apply": true, - "setTimeout.apply": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>util": true } }, "web3": { @@ -5447,14 +5700,14 @@ "setTimeout": true }, "packages": { - "browserify>util": true, "readable-stream": true, + "browserify>util": true, "web3-stream-provider>uuid": true } }, - "web3-stream-provider>uuid": { + "@metamask/controllers>web3": { "globals": { - "crypto": true + "XMLHttpRequest": true } }, "webextension-polyfill": { @@ -5466,9 +5719,30 @@ "define": true } }, - "webpack>events": { - "globals": { - "console": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, + "eslint-plugin-react>array-includes>is-string": true, + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-collection": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + } + }, + "browserify>util>which-typed-array": { + "packages": { + "string.prototype.matchall>es-abstract>available-typed-arrays": true, + "string.prototype.matchall>call-bind": true, + "browserify>util>which-typed-array>for-each": true, + "string.prototype.matchall>es-abstract>gopd": true, + "koa>is-generator-function>has-tostringtag": true } } } diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 548555137202..6068b745de6d 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -5,144 +5,124 @@ "regeneratorRuntime": "write" } }, - "@ensdomains/content-hash": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { "globals": { - "console.warn": true + "WeakRef": true }, "packages": { - "@ensdomains/content-hash>cids": true, - "@ensdomains/content-hash>js-base64": true, - "@ensdomains/content-hash>multicodec": true, - "@ensdomains/content-hash>multihashes": true, - "browserify>buffer": true + "browserify": true } }, - "@ensdomains/content-hash>cids": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes": true, - "@ensdomains/content-hash>cids>uint8arrays": true, - "@ensdomains/content-hash>multicodec": true + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, + "browserify": true, + "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true } }, - "@ensdomains/content-hash>cids>multibase": { + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "SuppressedError": true + } + }, + "@ensdomains/content-hash": { + "globals": { + "console.warn": true }, "packages": { - "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true + "browserify>buffer": true, + "@ensdomains/content-hash>cids": true, + "@ensdomains/content-hash>js-base64": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>multihashes": true } }, - "@ensdomains/content-hash>cids>multihashes": { + "@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true, - "@ensdomains/content-hash>cids>multihashes>varint": true, - "@ensdomains/content-hash>cids>uint8arrays": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>cids>uint8arrays": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>cids>multibase": true + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "webpack>events": true } }, - "@ensdomains/content-hash>js-base64": { - "globals": { - "Base64": "write", - "TextDecoder": true, - "TextEncoder": true, - "atob": true, - "btoa": true, - "define": true - }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { "packages": { - "browserify>buffer": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays": true, - "sass-embedded>varint": true + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "webpack>events": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays": { + "@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "Buffer": true, - "TextDecoder": true, "TextEncoder": true - }, - "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "console.warn": true, - "crypto.subtle.digest": true - } - }, - "@ensdomains/content-hash>multihashes": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase": true, - "@ensdomains/content-hash>multihashes>varint": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase": { - "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true, - "@ensdomains/content-hash>multihashes>web-encoding": true, - "browserify>buffer": true + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { + "globals": { + "TextEncoder": true } }, - "@ensdomains/content-hash>multihashes>multibase>base-x": { + "@ethereumjs/tx": { "packages": { - "koa>content-disposition>safe-buffer": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, - "@ensdomains/content-hash>multihashes>web-encoding": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/smart-transactions-controller>@ethereumjs/tx": { "packages": { - "browserify>util": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@ethereumjs/tx": { + "eth-lattice-keyring>@ethereumjs/tx": { "packages": { + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, "@ethereumjs/tx>@ethereumjs/common": true, "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, + "@ethersproject/providers": true, "browserify>buffer": true, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true, "browserify>insert-module-globals>is-buffer": true } }, - "@ethereumjs/tx>@ethereumjs/common": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, + "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx>@ethereumjs/rlp": true, "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/providers": true, "browserify>buffer": true, - "webpack>events": true - } - }, - "@ethereumjs/tx>@ethereumjs/common>crc-32": { - "globals": { - "DO_NOT_EXPORT_CRC": true, - "define": true - } - }, - "@ethereumjs/tx>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true } }, "@ethereumjs/tx>@ethereumjs/util": { @@ -151,78 +131,83 @@ }, "packages": { "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true, - "@ethereumjs/tx>ethereum-cryptography": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true, "browserify>insert-module-globals>is-buffer": true, - "webpack>events": true + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true } }, - "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { + "@metamask/smart-transactions-controller>@ethereumjs/util": { "globals": { - "Headers": true, - "TextDecoder": true, - "URL": true, - "btoa": true, + "console.warn": true, "fetch": true }, "packages": { - "browserify>browserify-zlib": true, - "browserify>buffer": true, - "browserify>url": true, - "browserify>util": true, - "https-browserify": true, - "process": true, - "stream-http": true + "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack>events": true } }, - "@ethereumjs/tx>ethereum-cryptography": { + "@ethersproject/abi": { "globals": { - "TextDecoder": true, - "crypto": true + "console.log": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true, - "@noble/hashes": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { - "globals": { - "TextEncoder": true - }, + "ethers>@ethersproject/abstract-provider": { "packages": { - "@noble/hashes": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "ethers>@ethersproject/abstract-signer": { "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true } }, - "@ethersproject/abi": { - "globals": { - "console.log": true - }, + "ethers>@ethersproject/address": { "packages": { "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/rlp": true + } + }, + "ethers>@ethersproject/base64": { + "globals": { + "atob": true, + "btoa": true + }, + "packages": { + "@ethersproject/bytes": true + } + }, + "ethers>@ethersproject/basex": { + "packages": { + "@ethersproject/bytes": true, + "ethers>@ethersproject/properties": true } }, "@ethersproject/bignumber": { "packages": { "@ethersproject/bytes": true, - "bn.js": true, - "ethers>@ethersproject/logger": true + "ethers>@ethersproject/logger": true, + "bn.js": true } }, "@ethersproject/bytes": { @@ -230,17 +215,22 @@ "ethers>@ethersproject/logger": true } }, + "ethers>@ethersproject/constants": { + "packages": { + "@ethersproject/bignumber": true + } + }, "@ethersproject/contracts": { "globals": { "setTimeout": true }, "packages": { "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/abstract-provider": true, "ethers>@ethersproject/abstract-signer": true, "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/transactions": true @@ -248,10 +238,10 @@ }, "@ethersproject/hash": { "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, "ethers>@ethersproject/address": true, "ethers>@ethersproject/base64": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/properties": true, @@ -260,9 +250,9 @@ }, "@ethersproject/hdnode": { "packages": { + "ethers>@ethersproject/basex": true, "@ethersproject/bignumber": true, "@ethersproject/bytes": true, - "ethers>@ethersproject/basex": true, "ethers>@ethersproject/logger": true, "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, @@ -273,1784 +263,1328 @@ "ethers>@ethersproject/wordlists": true } }, - "@ethersproject/providers": { - "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true - }, + "ethers>@ethersproject/json-wallets": { "packages": { - "@ethersproject/bignumber": true, + "ethers>@ethersproject/address": true, "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/providers>bech32": true, - "@metamask/test-bundler>@ethersproject/networks": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/keccak256": true, "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/pbkdf2": true, "ethers>@ethersproject/properties": true, "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "@ethersproject/providers>@ethersproject/random": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/json-wallets>aes-js": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true } }, - "@ethersproject/wallet": { + "ethers>@ethersproject/keccak256": { "packages": { "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/transactions": true + "eth-ens-namehash>js-sha3": true } }, - "@keystonehq/bc-ur-registry-eth": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "uuid": true + "ethers>@ethersproject/logger": { + "globals": { + "console": true } }, - "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { - "globals": { - "define": true - }, + "ethers>@ethersproject/providers>@ethersproject/networks": { "packages": { - "@ngraveio/bc-ur": true, - "@swc/helpers>tslib": true, - "browserify>buffer": true, - "buffer": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring": { + "@metamask/test-bundler>@ethersproject/networks": { "packages": { - "@ethereumjs/tx": true, - "@keystonehq/bc-ur-registry-eth": true, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, - "@keystonehq/metamask-airgapped-keyring>rlp": true, - "@metamask/obs-store": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "ethers>@ethersproject/logger": true } }, - "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { + "ethers>@ethersproject/pbkdf2": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@keystonehq/bc-ur-registry-eth": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "eth-lattice-keyring>rlp": true, - "uuid": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/sha2": true } }, - "@keystonehq/metamask-airgapped-keyring>rlp": { + "ethers>@ethersproject/properties": { "packages": { - "bn.js": true, - "browserify>buffer": true + "ethers>@ethersproject/logger": true } }, - "@lavamoat/lavadome-react": { + "@ethersproject/providers": { "globals": { - "Document.prototype": true, - "DocumentFragment.prototype": true, - "Element.prototype": true, - "Node.prototype": true, + "WebSocket": true, + "clearInterval": true, + "clearTimeout": true, + "console.log": true, "console.warn": true, - "document": true + "setInterval": true, + "setTimeout": true }, "packages": { - "react": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "@metamask/test-bundler>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "@ethersproject/providers>@ethersproject/web": true, + "@ethersproject/providers>bech32": true } }, - "@material-ui/core": { + "ethers>@ethersproject/providers": { "globals": { - "Image": true, - "_formatMuiErrorMessage": true, - "addEventListener": true, + "WebSocket": true, "clearInterval": true, "clearTimeout": true, - "console.error": true, + "console.log": true, "console.warn": true, - "document": true, - "getComputedStyle": true, - "getSelection": true, - "innerHeight": true, - "innerWidth": true, - "matchMedia": true, - "navigator": true, - "performance.now": true, - "removeEventListener": true, - "requestAnimationFrame": true, "setInterval": true, "setTimeout": true }, "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles": true, - "@material-ui/core>@material-ui/system": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "@material-ui/core>popper.js": true, - "@material-ui/core>react-transition-group": true, - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/providers>@ethersproject/networks": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/providers>@ethersproject/web": true, + "ethers>@ethersproject/providers>bech32": true } }, - "@material-ui/core>@material-ui/styles": { + "@ethersproject/providers>@ethersproject/random": { "globals": { - "console.error": true, - "console.warn": true, - "document.createComment": true, - "document.head": true - }, - "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, - "@material-ui/core>@material-ui/styles>jss-plugin-global": true, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, - "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, - "@material-ui/core>@material-ui/utils": true, - "@material-ui/core>clsx": true, - "prop-types": true, - "react": true, - "react-redux>hoist-non-react-statics": true + "crypto.getRandomValues": true } }, - "@material-ui/core>@material-ui/styles>jss": { - "globals": { - "CSS": true, - "document.createElement": true, - "document.querySelector": true - }, + "ethers>@ethersproject/random": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { + "ethers>@ethersproject/rlp": { "packages": { - "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { - "globals": { - "CSS": true - }, + "ethers>@ethersproject/sha2": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2>hash.js": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-global": { + "ethers>@ethersproject/signing-key": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/signing-key>elliptic": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-nested": { + "ethers>@ethersproject/solidity": { "packages": { - "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { + "ethers>@ethersproject/strings": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { + "ethers>@ethersproject/transactions": { "packages": { - "@material-ui/core>@material-ui/styles>jss": true, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/signing-key": true } }, - "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { - "globals": { - "document.createElement": true, - "document.documentElement": true, - "getComputedStyle": true - }, + "ethers>@ethersproject/units": { "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": true + "@ethersproject/bignumber": true, + "ethers>@ethersproject/logger": true } }, - "@material-ui/core>@material-ui/styles>jss>is-in-browser": { - "globals": { - "document": true + "@ethersproject/wallet": { + "packages": { + "ethers>@ethersproject/abstract-provider": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/transactions": true } }, - "@material-ui/core>@material-ui/system": { + "@ethersproject/providers>@ethersproject/web": { "globals": { - "console.error": true + "clearTimeout": true, + "fetch": true, + "setTimeout": true }, "packages": { - "@babel/runtime": true, - "@material-ui/core>@material-ui/utils": true, - "prop-types": true - } - }, - "@material-ui/core>@material-ui/utils": { - "packages": { - "@babel/runtime": true, - "prop-types": true, - "prop-types>react-is": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>popper.js": { + "ethers>@ethersproject/providers>@ethersproject/web": { "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator": true, - "requestAnimationFrame": true, + "clearTimeout": true, + "fetch": true, "setTimeout": true + }, + "packages": { + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@material-ui/core>react-transition-group": { + "ethers>@ethersproject/web": { "globals": { - "Element": true, + "clearTimeout": true, + "fetch": true, "setTimeout": true }, "packages": { - "@material-ui/core>react-transition-group>dom-helpers": true, - "prop-types": true, - "react": true, - "react-dom": true - } - }, - "@material-ui/core>react-transition-group>dom-helpers": { - "packages": { - "@babel/runtime": true + "ethers>@ethersproject/base64": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask-institutional/custody-controller": { + "ethers>@ethersproject/wordlists": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask-institutional/custody-keyring": true, - "@metamask/obs-store": true + "@ethersproject/bytes": true, + "@ethersproject/hash": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/strings": true } }, - "@metamask-institutional/custody-keyring": { + "@metamask/notification-services-controller>firebase>@firebase/app": { "globals": { - "console.error": true, - "console.log": true, + "FinalizationRegistry": true, "console.warn": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask-institutional/custody-keyring>@metamask-institutional/configuration-client": true, - "@metamask-institutional/sdk": true, - "@metamask-institutional/types": true, - "@metamask/obs-store": true, - "crypto-browserify": true, - "gulp-sass>lodash.clonedeep": true, - "webpack>events": true - } - }, - "@metamask-institutional/custody-keyring>@metamask-institutional/configuration-client": { - "globals": { - "console.log": true, - "fetch": true - } - }, - "@metamask-institutional/extension": { - "globals": { - "console.log": true - }, - "packages": { - "@metamask-institutional/custody-controller": true, - "@metamask-institutional/sdk": true, - "@metamask-institutional/types": true, - "gulp-sass>lodash.clonedeep": true + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask-institutional/institutional-features": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { "packages": { - "@metamask-institutional/custody-keyring": true, - "@metamask/obs-store": true - } - }, - "@metamask-institutional/rpc-allowlist": { - "globals": { - "URL": true + "@metamask/notification-services-controller>firebase>@firebase/util": true } }, - "@metamask-institutional/sdk": { + "@metamask/notification-services-controller>firebase>@firebase/installations": { "globals": { - "URLSearchParams": true, - "console.debug": true, + "BroadcastChannel": true, + "Headers": true, + "btoa": true, "console.error": true, - "console.log": true, - "fetch": true + "crypto": true, + "fetch": true, + "msCrypto": true, + "navigator.onLine": true, + "setTimeout": true }, "packages": { - "@metamask-institutional/sdk>@metamask-institutional/simplecache": true, - "crypto-browserify": true, - "webpack>events": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true } }, - "@metamask-institutional/transaction-update": { + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { "globals": { - "clearInterval": true, - "console.info": true, - "console.log": true, - "setInterval": true + "console": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask-institutional/sdk": true, - "@metamask-institutional/transaction-update>@metamask-institutional/websocket-client": true, - "@metamask/obs-store": true, - "webpack>events": true + "tslib": true } }, - "@metamask-institutional/transaction-update>@metamask-institutional/websocket-client": { + "@metamask/notification-services-controller>firebase>@firebase/messaging": { "globals": { - "WebSocket": true, - "clearTimeout": true, - "console.log": true, + "Headers": true, + "Notification.maxActions": true, + "Notification.permission": true, + "Notification.requestPermission": true, + "PushSubscription.prototype.hasOwnProperty": true, + "ServiceWorkerRegistration": true, + "URL": true, + "addEventListener": true, + "atob": true, + "btoa": true, + "clients.matchAll": true, + "clients.openWindow": true, + "console.warn": true, + "document": true, + "fetch": true, + "indexedDB": true, + "location.href": true, + "location.origin": true, + "navigator": true, + "origin.replace": true, + "registration.showNotification": true, "setTimeout": true }, "packages": { - "webpack>events": true - } - }, - "@metamask/abi-utils": { - "packages": { - "@metamask/abi-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, + "@metamask/notification-services-controller>firebase>@firebase/installations": true, + "@metamask/notification-services-controller>firebase>@firebase/util": true, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, + "tslib": true } }, - "@metamask/abi-utils>@metamask/utils": { + "@metamask/notification-services-controller>firebase>@firebase/util": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "atob": true, + "browser": true, + "btoa": true, + "chrome": true, + "console": true, + "document": true, + "indexedDB": true, + "navigator": true, + "process": true, + "self": true, + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "process": true } }, - "@metamask/accounts-controller": { + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": { "packages": { + "@ethereumjs/tx": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/base-controller": true, - "@metamask/eth-snap-keyring": true, - "@metamask/keyring-api": true, - "@metamask/keyring-controller": true, - "@metamask/utils": true, + "@keystonehq/bc-ur-registry-eth": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "eth-lattice-keyring>rlp": true, "uuid": true } }, - "@metamask/address-book-controller": { + "@keystonehq/bc-ur-registry-eth": { "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": true, + "browserify>buffer": true, + "@metamask/eth-trezor-keyring>hdkey": true, + "uuid": true } }, - "@metamask/announcement-controller": { - "packages": { - "@metamask/announcement-controller>@metamask/base-controller": true - } - }, - "@metamask/announcement-controller>@metamask/base-controller": { + "@keystonehq/bc-ur-registry-eth>@keystonehq/bc-ur-registry": { "globals": { - "setTimeout": true + "define": true }, "packages": { - "immer": true + "@ngraveio/bc-ur": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "buffer": true, + "browserify>buffer": true, + "tslib": true } }, - "@metamask/approval-controller": { - "globals": { - "console.info": true - }, + "@keystonehq/metamask-airgapped-keyring": { "packages": { - "@metamask/base-controller": true, - "@metamask/rpc-errors": true, - "nanoid": true + "@ethereumjs/tx": true, + "@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring": true, + "@keystonehq/bc-ur-registry-eth": true, + "@metamask/obs-store": true, + "browserify>buffer": true, + "webpack>events": true, + "@keystonehq/metamask-airgapped-keyring>rlp": true, + "uuid": true } }, - "@metamask/approval-controller>nanoid": { + "chart.js>@kurkle/color": { "globals": { - "crypto.getRandomValues": true + "define": true } }, - "@metamask/assets-controllers": { + "@lavamoat/lavadome-react": { "globals": { - "AbortController": true, - "Headers": true, - "URL": true, - "URLSearchParams": true, - "clearInterval": true, - "clearTimeout": true, - "console.error": true, - "console.log": true, - "setInterval": true, - "setTimeout": true + "Document.prototype": true, + "DocumentFragment.prototype": true, + "Element.prototype": true, + "Node.prototype": true, + "console.warn": true, + "document": true }, "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/bignumber": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/abi-utils": true, - "@metamask/base-controller": true, - "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "bn.js": true, - "cockatiel": true, - "ethers>@ethersproject/address": true, - "lodash": true, - "single-call-balance-checker-abi": true, - "uuid": true + "react": true } }, - "@metamask/base-controller": { - "globals": { - "setTimeout": true - }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { "packages": { - "immer": true + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true } }, - "@metamask/browser-passworder": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { "globals": { - "CryptoKey": true, - "btoa": true, - "crypto.getRandomValues": true, - "crypto.subtle.decrypt": true, - "crypto.subtle.deriveKey": true, - "crypto.subtle.encrypt": true, - "crypto.subtle.exportKey": true, - "crypto.subtle.importKey": true - }, + "console.warn": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { "packages": { - "@metamask/browser-passworder>@metamask/utils": true, - "browserify>buffer": true + "ethers>@ethersproject/constants": true, + "@ethersproject/hash": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, + "@metamask/ppom-validator>crypto-js": true } }, - "@metamask/browser-passworder>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "console.warn": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@ethersproject/abi": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/transactions": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, "browserify>buffer": true, - "nock>debug": true, "semver": true } }, - "@metamask/controller-utils": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { "globals": { - "URL": true, - "console.error": true, - "fetch": true, - "setTimeout": true + "console.warn": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/controller-utils>@spruceid/siwe-parser": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/utils": true, - "bn.js": true, - "browserify>buffer": true, - "eslint>fast-deep-equal": true, - "eth-ens-namehash": true + "wait-on>rxjs": true } }, - "@metamask/controller-utils>@spruceid/siwe-parser": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { + "globals": { + "__ledgerLogsListen": "write", + "console.error": true + } + }, + "@material-ui/core": { "globals": { + "Image": true, + "_formatMuiErrorMessage": true, + "addEventListener": true, + "clearInterval": true, + "clearTimeout": true, "console.error": true, - "console.log": true + "console.warn": true, + "document": true, + "getComputedStyle": true, + "getSelection": true, + "innerHeight": true, + "innerWidth": true, + "matchMedia": true, + "navigator": true, + "performance.now": true, + "removeEventListener": true, + "requestAnimationFrame": true, + "setInterval": true, + "setTimeout": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles": true, + "@material-ui/core>@material-ui/system": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>popper.js": true, + "prop-types": true, + "react": true, + "react-dom": true, + "prop-types>react-is": true, + "@material-ui/core>react-transition-group": true } }, - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { + "@material-ui/core>@material-ui/styles": { + "globals": { + "console.error": true, + "console.warn": true, + "document.createComment": true, + "document.head": true + }, "packages": { - "browserify>buffer": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "@material-ui/core>clsx": true, + "react-redux>hoist-non-react-statics": true, + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": true, + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": true, + "@material-ui/core>@material-ui/styles>jss-plugin-global": true, + "@material-ui/core>@material-ui/styles>jss-plugin-nested": true, + "@material-ui/core>@material-ui/styles>jss-plugin-props-sort": true, + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": true, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": true, + "@material-ui/core>@material-ui/styles>jss": true, + "prop-types": true, + "react": true } }, - "@metamask/controllers>web3": { + "@material-ui/core>@material-ui/system": { "globals": { - "XMLHttpRequest": true + "console.error": true + }, + "packages": { + "@babel/runtime": true, + "@material-ui/core>@material-ui/utils": true, + "prop-types": true } }, - "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { - "globals": { - "fetch": true + "@material-ui/core>@material-ui/utils": { + "packages": { + "@babel/runtime": true, + "prop-types": true, + "prop-types>react-is": true } }, - "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { + "@metamask-institutional/custody-keyring>@metamask-institutional/configuration-client": { "globals": { + "console.log": true, "fetch": true } }, - "@metamask/ens-controller": { + "@metamask-institutional/custody-controller": { "packages": { - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "punycode": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask-institutional/custody-keyring": true, + "@metamask/obs-store": true } }, - "@metamask/eth-json-rpc-filters": { + "@metamask-institutional/custody-keyring": { "globals": { - "console.error": true + "console.error": true, + "console.log": true, + "console.warn": true }, "packages": { - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/safe-event-emitter": true, - "pify": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask-institutional/custody-keyring>@metamask-institutional/configuration-client": true, + "@metamask-institutional/sdk": true, + "@metamask-institutional/types": true, + "@metamask/obs-store": true, + "crypto-browserify": true, + "webpack>events": true, + "gulp-sass>lodash.clonedeep": true } }, - "@metamask/eth-json-rpc-middleware": { + "@metamask-institutional/extension": { "globals": { - "URL": true, - "console.error": true, - "setTimeout": true + "console.log": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, - "@metamask/eth-json-rpc-middleware>klona": true, - "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-sig-util": true, - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true - } - }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-json-rpc-provider": { - "packages": { - "@metamask/json-rpc-engine": true, - "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true, - "uuid": true + "@metamask-institutional/custody-controller": true, + "@metamask-institutional/sdk": true, + "@metamask-institutional/types": true, + "gulp-sass>lodash.clonedeep": true } }, - "@metamask/eth-ledger-bridge-keyring": { - "globals": { - "addEventListener": true, - "console.error": true, - "document.createElement": true, - "document.head.appendChild": true, - "fetch": true, - "removeEventListener": true - }, + "@metamask-institutional/institutional-features": { "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, - "@metamask/eth-sig-util": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "browserify>buffer": true, - "webpack>events": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": { - "globals": { - "TextEncoder": true + "@metamask-institutional/custody-keyring": true, + "@metamask/obs-store": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": { + "@metamask-institutional/rpc-allowlist": { "globals": { - "console.warn": true - }, - "packages": { - "@ethersproject/abi": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": true, - "browserify>buffer": true, - "ethers>@ethersproject/rlp": true, - "semver": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service": { - "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": true + "URL": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { + "@metamask-institutional/sdk": { "globals": { - "Blob": true, - "FormData": true, "URLSearchParams": true, - "XMLHttpRequest": true, - "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, - "setTimeout": true + "console.debug": true, + "console.error": true, + "console.log": true, + "fetch": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/errors": { - "globals": { - "console.warn": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools": { - "packages": { - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/cryptoassets-evm-signatures": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": true, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": true, - "@metamask/ppom-validator>crypto-js": true + "@metamask-institutional/sdk>@metamask-institutional/simplecache": true, + "crypto-browserify": true, + "webpack>events": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>@ledgerhq/live-env": { + "@metamask-institutional/transaction-update": { "globals": { - "console.warn": true + "clearInterval": true, + "console.info": true, + "console.log": true, + "setInterval": true }, "packages": { - "wait-on>rxjs": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask-institutional/sdk": true, + "@metamask-institutional/transaction-update>@metamask-institutional/websocket-client": true, + "@metamask/obs-store": true, + "webpack>events": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { + "@metamask-institutional/transaction-update>@metamask-institutional/websocket-client": { "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, - "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, + "WebSocket": true, + "clearTimeout": true, + "console.log": true, "setTimeout": true }, "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true + "webpack>events": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>ethers": { + "@metamask/abi-utils": { "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/providers": true, - "@ethersproject/providers>@ethersproject/web": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/wordlists": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/logs": { - "globals": { - "__ledgerLogsListen": "write", - "console.error": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { - "globals": { - "Blob": true, - "FormData": true, - "URLSearchParams": true, - "XMLHttpRequest": true, - "btoa": true, - "console.warn": true, - "document": true, - "location.href": true, - "navigator": true, - "setTimeout": true - }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "axios>form-data": true, - "browserify>buffer": true, - "process": true - } - }, - "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true } }, - "@metamask/eth-query": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "watchify>xtend": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-sig-util": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>@metamask/utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-sig-util>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true } }, - "@metamask/eth-sig-util>tweetnacl": { - "globals": { - "crypto": true, - "msCrypto": true, - "nacl": "write" - }, + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "browserify>browser-resolve": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-controller>@metamask/utils": true } }, - "@metamask/eth-snap-keyring": { - "globals": { - "URL": true, - "console.error": true - }, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": { "packages": { - "@ethereumjs/tx": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/eth-snap-keyring>uuid": true, - "@metamask/keyring-api": true, "@metamask/utils>@metamask/superstruct": true, - "webpack>events": true + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true } }, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { + "@metamask/accounts-controller": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/base-controller": true, + "@metamask/eth-snap-keyring": true, + "@metamask/keyring-api": true, + "@metamask/keyring-controller": true, + "@metamask/utils": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "uuid": true } }, - "@metamask/eth-snap-keyring>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/address-book-controller": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true } }, - "@metamask/eth-snap-keyring>uuid": { - "globals": { - "crypto": true + "@metamask/announcement-controller": { + "packages": { + "@metamask/announcement-controller>@metamask/base-controller": true } }, - "@metamask/eth-token-tracker": { + "@metamask/approval-controller": { "globals": { - "console.warn": true + "console.info": true }, "packages": { - "@babel/runtime": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, - "@metamask/eth-token-tracker>deep-equal": true, - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/safe-event-emitter": true, - "bn.js": true, - "human-standard-token-abi": true + "@metamask/base-controller": true, + "@metamask/rpc-errors": true, + "nanoid": true } }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { + "@metamask/assets-controllers": { "globals": { + "AbortController": true, + "Headers": true, + "URL": true, + "URLSearchParams": true, + "clearInterval": true, "clearTimeout": true, "console.error": true, + "console.log": true, + "setInterval": true, "setTimeout": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true, - "pify": true - } - }, - "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/eth-token-tracker>deep-equal": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, - "@metamask/eth-token-tracker>deep-equal>is-date-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, - "@metamask/eth-token-tracker>deep-equal>which-collection": true, - "@ngraveio/bc-ur>assert>object-is": true, - "browserify>util>is-arguments": true, - "browserify>util>which-typed-array": true, - "gulp>vinyl-fs>object.assign": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>regexp.prototype.flags": true, - "string.prototype.matchall>side-channel": true - } - }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true, - "browserify>util>is-arguments": true, - "eslint-plugin-react>array-includes>is-string": true, - "process": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>has-symbols": true - } - }, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { - "globals": { - "StopIteration": true - }, - "packages": { - "string.prototype.matchall>internal-slot": true - } - }, - "@metamask/eth-token-tracker>deep-equal>is-date-object": { - "packages": { - "koa>is-generator-function>has-tostringtag": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { - "packages": { - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { - "packages": { - "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { - "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { - "packages": { - "koa>is-generator-function>has-tostringtag": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-collection": { - "packages": { - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, - "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true - } - }, - "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true - } - }, - "@metamask/eth-trezor-keyring": { - "globals": { - "setTimeout": true - }, - "packages": { - "@ethereumjs/tx": true, "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, - "@metamask/eth-trezor-keyring>hdkey": true, - "@trezor/connect-web": true, - "browserify>buffer": true, - "webpack>events": true - } - }, - "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { - "packages": { - "@metamask/eth-sig-util": true, - "@swc/helpers>tslib": true - } - }, - "@metamask/eth-trezor-keyring>hdkey": { - "packages": { - "browserify>assert": true, - "crypto-browserify": true, - "ethereumjs-util>create-hash>ripemd160": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true - } - }, - "@metamask/etherscan-link": { - "globals": { - "URL": true - } - }, - "@metamask/ethjs": { - "globals": { - "clearInterval": true, - "setInterval": true - }, - "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-provider-http": true, - "@metamask/ethjs>@metamask/ethjs-unit": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/number-to-bn": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, + "ethers>@ethersproject/address": true, + "@ethersproject/bignumber": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/abi-utils": true, + "@metamask/base-controller": true, + "@metamask/contract-metadata": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/metamask-eth-abis": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, "bn.js": true, - "browserify>buffer": true - } - }, - "@metamask/ethjs-contract": { - "packages": { - "@babel/runtime": true, - "@metamask/ethjs>@metamask/ethjs-filter": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>ethjs-abi": true, - "@metamask/ethjs>js-sha3": true, - "promise-to-callback": true + "cockatiel": true, + "lodash": true, + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, + "single-call-balance-checker-abi": true, + "uuid": true } }, - "@metamask/ethjs-query": { + "@metamask/base-controller": { "globals": { - "console": true + "setTimeout": true }, "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format": true, - "@metamask/ethjs-query>@metamask/ethjs-rpc": true, - "promise-to-callback": true - } - }, - "@metamask/ethjs-query>@metamask/ethjs-format": { - "packages": { - "@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, - "@metamask/ethjs>@metamask/ethjs-util": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "@metamask/ethjs>@metamask/number-to-bn": true + "immer": true } }, - "@metamask/ethjs-query>@metamask/ethjs-rpc": { + "@metamask/announcement-controller>@metamask/base-controller": { + "globals": { + "setTimeout": true + }, "packages": { - "promise-to-callback": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-filter": { + "@metamask/name-controller>@metamask/base-controller": { "globals": { - "clearInterval": true, - "setInterval": true - } - }, - "@metamask/ethjs>@metamask/ethjs-provider-http": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-provider-http>xhr2": { + "@metamask/rate-limit-controller>@metamask/base-controller": { "globals": { - "XMLHttpRequest": true - } - }, - "@metamask/ethjs>@metamask/ethjs-unit": { + "setTimeout": true + }, "packages": { - "@metamask/ethjs>@metamask/number-to-bn": true, - "bn.js": true + "immer": true } }, - "@metamask/ethjs>@metamask/ethjs-util": { + "@metamask/browser-passworder": { + "globals": { + "CryptoKey": true, + "btoa": true, + "crypto.getRandomValues": true, + "crypto.subtle.decrypt": true, + "crypto.subtle.deriveKey": true, + "crypto.subtle.encrypt": true, + "crypto.subtle.exportKey": true, + "crypto.subtle.importKey": true + }, "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, + "@metamask/browser-passworder>@metamask/utils": true, "browserify>buffer": true } }, - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>is-hex-prefixed": true - } - }, - "@metamask/ethjs>@metamask/number-to-bn": { - "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "eth-keyring-controller>@metamask/browser-passworder": { + "globals": { + "crypto": true } }, - "@metamask/ethjs>ethjs-abi": { + "@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/ethjs>ethjs-abi>number-to-bn": true, - "@metamask/ethjs>js-sha3": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/controller-utils>@metamask/ethjs-unit": true, + "@metamask/controller-utils>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, "bn.js": true, - "browserify>buffer": true + "browserify>buffer": true, + "eth-ens-namehash": true, + "eslint>fast-deep-equal": true } }, - "@metamask/ethjs>ethjs-abi>number-to-bn": { + "@metamask/ens-controller": { "packages": { - "@metamask/ethjs>@metamask/ethjs-util>strip-hex-prefix": true, - "bn.js": true + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "punycode": true } }, - "@metamask/ethjs>js-sha3": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": { "globals": { - "define": true + "clearTimeout": true, + "console.error": true, + "setTimeout": true }, "packages": { - "process": true + "@metamask/safe-event-emitter": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true, + "pify": true } }, - "@metamask/gas-fee-controller": { + "@metamask/network-controller>@metamask/eth-block-tracker": { "globals": { - "clearInterval": true, + "clearTimeout": true, "console.error": true, - "setInterval": true + "setTimeout": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "bn.js": true, - "uuid": true + "@metamask/safe-event-emitter": true, + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, - "@metamask/jazzicon": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring": { "globals": { - "document.createElement": true, - "document.createElementNS": true + "TextEncoder": true }, "packages": { - "@metamask/jazzicon>color": true, - "@metamask/jazzicon>mersenne-twister": true - } - }, - "@metamask/jazzicon>color": { - "packages": { - "@metamask/jazzicon>color>clone": true, - "@metamask/jazzicon>color>color-convert": true, - "@metamask/jazzicon>color>color-string": true - } - }, - "@metamask/jazzicon>color>clone": { - "packages": { - "browserify>buffer": true - } - }, - "@metamask/jazzicon>color>color-convert": { - "packages": { - "@metamask/jazzicon>color>color-convert>color-name": true + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-sig-util": true, + "@metamask/scure-bip39": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true } }, - "@metamask/jazzicon>color>color-string": { + "@metamask/eth-json-rpc-filters": { + "globals": { + "console.error": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/safe-event-emitter": true, + "@metamask/name-controller>async-mutex": true, + "pify": true } }, - "@metamask/json-rpc-engine": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "globals": { + "fetch": true, + "setTimeout": true + }, "packages": { - "@metamask/json-rpc-engine>@metamask/utils": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/safe-event-emitter": true + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true } }, - "@metamask/json-rpc-engine>@metamask/utils": { + "@metamask/eth-json-rpc-middleware": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true, + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>klona": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true } }, - "@metamask/json-rpc-middleware-stream": { - "globals": { - "console.warn": true, - "setTimeout": true - }, + "@metamask/eth-json-rpc-provider": { "packages": { - "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, "@metamask/safe-event-emitter": true, - "readable-stream": true + "uuid": true } }, - "@metamask/json-rpc-middleware-stream>@metamask/utils": { + "@metamask/eth-ledger-bridge-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "addEventListener": true, + "console.error": true, + "document.createElement": true, + "document.head.appendChild": true, + "fetch": true, + "removeEventListener": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, + "@metamask/eth-ledger-bridge-keyring>@ethereumjs/rlp": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-api": { - "globals": { - "URL": true - }, + "@metamask/controller-utils>@metamask/eth-query": { "packages": { - "@metamask/keyring-api>@metamask/utils": true, - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-api>uuid": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/ppom-validator>json-rpc-random-id": true, + "watchify>xtend": true } }, - "@metamask/keyring-api>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/abi-utils": true, + "@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-api>uuid": { - "globals": { - "crypto": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/base-controller": true, - "@metamask/browser-passworder": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>ethereumjs-wallet": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/utils": true + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring": { - "globals": { - "TextEncoder": true - }, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": true, - "@metamask/scure-bip39": true, - "browserify>buffer": true + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/keyring-controller>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, - "@metamask/keyring-controller>@metamask/eth-sig-util>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/signature-controller>@metamask/eth-sig-util": { "packages": { - "@metamask/utils>@metamask/superstruct": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/eth-sig-util>tweetnacl": true } }, "@metamask/keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/eth-sig-util": true, "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": true, "browserify>buffer": true, + "@ethereumjs/tx>ethereum-cryptography": true, "crypto-browserify>randombytes": true } }, - "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "@metamask/eth-snap-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "URL": true, + "console.error": true }, "packages": { + "@ethereumjs/tx": true, + "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/keyring-api": true, + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/eth-snap-keyring>@metamask/utils": true, + "webpack>events": true, + "@metamask/eth-snap-keyring>uuid": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": { + "@metamask/eth-token-tracker": { "globals": { - "URL": true + "console.warn": true }, "packages": { - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@babel/runtime": true, + "@metamask/eth-token-tracker>@metamask/eth-block-tracker": true, + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true, + "@metamask/safe-event-emitter": true, + "bn.js": true, + "@metamask/eth-token-tracker>deep-equal": true, + "human-standard-token-abi": true } }, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { + "@metamask/eth-trezor-keyring": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "setTimeout": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, - "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, - "browserify>buffer": true, - "crypto-browserify": true, - "crypto-browserify>randombytes": true, - "eth-lattice-keyring>gridplus-sdk>aes-js": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "uuid": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { - "packages": { - "browserify>assert": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethers>@ethersproject/sha2>hash.js": true, - "ganache>secp256k1": true, - "koa>content-disposition>safe-buffer": true - } - }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { - "packages": { - "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true, - "bn.js": true, - "browserify>assert": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": true, + "@trezor/connect-web": true, "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true + "webpack>events": true, + "@metamask/eth-trezor-keyring>hdkey": true } }, - "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "@metamask/etherscan-link": { + "globals": { + "URL": true } }, - "@metamask/logging-controller": { + "eth-method-registry>@metamask/ethjs-contract": { "packages": { - "@metamask/base-controller": true, - "uuid": true + "@babel/runtime": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": true, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": true, + "eth-ens-namehash>js-sha3": true, + "promise-to-callback": true } }, - "@metamask/logo": { + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-filter": { "globals": { - "addEventListener": true, - "document.body.appendChild": true, - "document.createElementNS": true, - "innerHeight": true, - "innerWidth": true, - "requestAnimationFrame": true - }, - "packages": { - "@metamask/logo>gl-mat4": true, - "@metamask/logo>gl-vec3": true - } - }, - "@metamask/message-manager": { - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/utils": true, - "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "clearInterval": true, + "setInterval": true } }, - "@metamask/message-manager>jsonschema": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": { "packages": { - "browserify>url": true + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": true, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>ethjs-schema": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/name-controller": { + "eth-method-registry>@metamask/ethjs-query": { "globals": { - "fetch": true + "console": true }, "packages": { - "@metamask/controller-utils": true, - "@metamask/name-controller>@metamask/base-controller": true, - "@metamask/name-controller>@metamask/utils": true, - "@metamask/name-controller>async-mutex": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": true, + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/base-controller": { - "globals": { - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-rpc": { "packages": { - "immer": true + "promise-to-callback": true } }, - "@metamask/name-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": true, + "bn.js": true } }, - "@metamask/name-controller>async-mutex": { - "globals": { - "clearTimeout": true, - "setTimeout": true - }, + "eth-method-registry>@metamask/ethjs-contract>@metamask/ethjs-util": { "packages": { - "@swc/helpers>tslib": true + "browserify>buffer": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, - "@metamask/network-controller": { + "@metamask/gas-fee-controller": { "globals": { - "btoa": true, - "fetch": true, - "setTimeout": true + "clearInterval": true, + "console.error": true, + "setInterval": true }, "packages": { - "@metamask/base-controller": true, "@metamask/controller-utils": true, - "@metamask/eth-json-rpc-middleware": true, - "@metamask/eth-json-rpc-provider": true, - "@metamask/eth-query": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-block-tracker": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true, - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "eslint>fast-deep-equal": true, - "reselect": true, - "uri-js": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "bn.js": true, "uuid": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker": { + "@metamask/jazzicon": { "globals": { - "clearTimeout": true, - "console.error": true, - "setTimeout": true + "document.createElement": true, + "document.createElementNS": true }, "packages": { - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": true, - "@metamask/safe-event-emitter": true + "@metamask/jazzicon>color": true, + "@metamask/jazzicon>mersenne-twister": true } }, - "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/json-rpc-engine": { "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/rpc-errors": true, + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-engine>@metamask/utils": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura": { + "@metamask/json-rpc-middleware-stream": { "globals": { - "fetch": true, + "console.warn": true, "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-provider": true, - "@metamask/json-rpc-engine": true, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true, - "@metamask/rpc-errors": true + "@metamask/safe-event-emitter": true, + "@metamask/json-rpc-middleware-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { + "@metamask/snaps-sdk>@metamask/key-tree": { "globals": { - "TextDecoder": true, - "TextEncoder": true + "crypto.subtle": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, + "@metamask/scure-bip39": true, + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/utils>@scure/base": true } }, - "@metamask/notification-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/keyring-api": { + "packages": { + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller": { - "globals": { - "Intl.NumberFormat": true, - "addEventListener": true, - "fetch": true, - "registration": true, - "removeEventListener": true - }, + "@metamask/profile-sync-controller>@metamask/keyring-api": { "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, - "@metamask/notification-services-controller>bignumber.js": true, - "@metamask/notification-services-controller>firebase": true, - "@metamask/profile-sync-controller": true, - "@metamask/utils": true, - "loglevel": true, - "uuid": true + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, + "@metamask/keyring-api>bech32": true } }, - "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": { - "globals": { - "SuppressedError": true + "@metamask/keyring-controller": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/base-controller": true, + "@metamask/browser-passworder": true, + "@metamask/keyring-controller>@metamask/eth-hd-keyring": true, + "@metamask/keyring-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, + "@metamask/keyring-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "@metamask/keyring-controller>ethereumjs-wallet": true } }, - "@metamask/notification-services-controller>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { + "packages": { + "@metamask/keyring-snap-client": true } }, - "@metamask/notification-services-controller>firebase": { + "@metamask/keyring-snap-client": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/messaging": true + "@metamask/keyring-api": true, + "@metamask/keyring-api>@metamask/keyring-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-snap-client>uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app": { + "@metamask/keyring-api>@metamask/keyring-utils": { "globals": { - "FinalizationRegistry": true, - "console.warn": true + "URL": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": { + "@metamask/logging-controller": { "packages": { - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": { + "@metamask/logo": { "globals": { - "console": true + "addEventListener": true, + "document.body.appendChild": true, + "document.createElementNS": true, + "innerHeight": true, + "innerWidth": true, + "requestAnimationFrame": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/logo>gl-mat4": true, + "@metamask/logo>gl-vec3": true } }, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": { + "@metamask/message-manager": { + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "uuid": true + } + }, + "@metamask/name-controller": { "globals": { - "DOMException": true, - "IDBCursor": true, - "IDBDatabase": true, - "IDBIndex": true, - "IDBObjectStore": true, - "IDBRequest": true, - "IDBTransaction": true, - "indexedDB.deleteDatabase": true, - "indexedDB.open": true + "fetch": true + }, + "packages": { + "@metamask/name-controller>@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/name-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true } }, - "@metamask/notification-services-controller>firebase>@firebase/installations": { + "@metamask/network-controller": { "globals": { - "BroadcastChannel": true, - "Headers": true, "btoa": true, - "console.error": true, - "crypto": true, "fetch": true, - "msCrypto": true, - "navigator.onLine": true, "setTimeout": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/network-controller>@metamask/eth-block-tracker": true, + "@metamask/network-controller>@metamask/eth-json-rpc-infura": true, + "@metamask/eth-json-rpc-middleware": true, + "@metamask/eth-json-rpc-provider": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true, + "@metamask/utils": true, + "eslint>fast-deep-equal": true, + "reselect": true, + "uri-js": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/messaging": { + "@metamask/transaction-controller>@metamask/nonce-tracker": { + "packages": { + "@ethersproject/providers": true, + "browserify>assert": true, + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true + } + }, + "@metamask/notification-services-controller": { "globals": { - "Headers": true, - "Notification.maxActions": true, - "Notification.permission": true, - "Notification.requestPermission": true, - "PushSubscription.prototype.hasOwnProperty": true, - "ServiceWorkerRegistration": true, - "URL": true, + "Intl.NumberFormat": true, "addEventListener": true, - "atob": true, - "btoa": true, - "clients.matchAll": true, - "clients.openWindow": true, - "console.warn": true, - "document": true, "fetch": true, - "indexedDB": true, - "location.href": true, - "location.origin": true, - "navigator": true, - "origin.replace": true, - "registration.showNotification": true, - "setTimeout": true + "registration": true, + "removeEventListener": true }, "packages": { - "@metamask/notification-services-controller>firebase>@firebase/app": true, - "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true, - "@metamask/notification-services-controller>firebase>@firebase/app>idb": true, - "@metamask/notification-services-controller>firebase>@firebase/installations": true, - "@metamask/notification-services-controller>firebase>@firebase/util": true, - "@swc/helpers>tslib": true + "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/profile-sync-controller": true, + "@metamask/utils": true, + "@metamask/notification-services-controller>bignumber.js": true, + "@metamask/notification-services-controller>firebase": true, + "loglevel": true, + "uuid": true } }, - "@metamask/notification-services-controller>firebase>@firebase/util": { - "globals": { - "atob": true, - "browser": true, - "btoa": true, - "chrome": true, - "console": true, - "document": true, - "indexedDB": true, - "navigator": true, - "process": true, - "self": true, - "setTimeout": true - }, + "@metamask/controller-utils>@metamask/ethjs-unit>@metamask/number-to-bn": { "packages": { - "process": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true } }, "@metamask/object-multiplex": { @@ -2062,11 +1596,6 @@ "readable-stream": true } }, - "@metamask/object-multiplex>once": { - "packages": { - "@metamask/object-multiplex>once>wrappy": true - } - }, "@metamask/obs-store": { "packages": { "@metamask/safe-event-emitter": true, @@ -2082,38 +1611,18 @@ "@metamask/controller-utils": true, "@metamask/json-rpc-engine": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, + "@metamask/permission-controller>@metamask/utils": true, "deep-freeze-strict": true, "immer": true, "nanoid": true } }, - "@metamask/permission-controller>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, "@metamask/permission-log-controller": { "packages": { "@metamask/base-controller": true, "@metamask/permission-log-controller>@metamask/utils": true } }, - "@metamask/permission-log-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, "@metamask/phishing-controller": { "globals": { "TextEncoder": true, @@ -2122,12 +1631,12 @@ "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, "@metamask/base-controller": true, "@metamask/controller-utils": true, "@noble/hashes": true, - "punycode": true, - "webpack-cli>fastest-levenshtein": true + "@ethereumjs/tx>ethereum-cryptography": true, + "webpack-cli>fastest-levenshtein": true, + "punycode": true } }, "@metamask/polling-controller": { @@ -2146,84 +1655,32 @@ "globals": { "MessageEvent.prototype": true, "WorkerGlobalScope": true, - "addEventListener": true, - "browser": true, - "chrome": true, - "location.origin": true, - "postMessage": true, - "removeEventListener": true - }, - "packages": { - "@metamask/post-message-stream>@metamask/utils": true, - "readable-stream": true - } - }, - "@metamask/post-message-stream>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true - } - }, - "@metamask/ppom-validator": { - "globals": { - "URL": true, - "console.error": true, - "crypto": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query>json-rpc-random-id": true, - "@metamask/ppom-validator>crypto-js": true, - "@metamask/ppom-validator>elliptic": true, - "await-semaphore": true, - "browserify>buffer": true - } - }, - "@metamask/ppom-validator>crypto-js": { - "globals": { - "crypto": true, - "define": true, - "msCrypto": true - }, - "packages": { - "browserify>browser-resolve": true - } - }, - "@metamask/ppom-validator>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true - } - }, - "@metamask/ppom-validator>elliptic>brorand": { - "globals": { - "crypto": true, - "msCrypto": true + "addEventListener": true, + "browser": true, + "chrome": true, + "location.origin": true, + "postMessage": true, + "removeEventListener": true }, "packages": { - "browserify>browser-resolve": true + "@metamask/post-message-stream>@metamask/utils": true, + "readable-stream": true } }, - "@metamask/ppom-validator>elliptic>hmac-drbg": { + "@metamask/ppom-validator": { + "globals": { + "URL": true, + "console.error": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "ethers>@ethersproject/sha2>hash.js": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "await-semaphore": true, + "browserify>buffer": true, + "@metamask/ppom-validator>crypto-js": true, + "@metamask/ppom-validator>elliptic": true, + "@metamask/ppom-validator>json-rpc-random-id": true } }, "@metamask/preferences-controller": { @@ -2249,668 +1706,933 @@ }, "packages": { "@metamask/base-controller": true, + "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/keyring-controller": true, "@metamask/network-controller": true, - "@metamask/profile-sync-controller>@metamask/keyring-api": true, "@metamask/profile-sync-controller>@noble/ciphers": true, - "@metamask/profile-sync-controller>siwe": true, "@noble/hashes": true, "browserify>buffer": true, - "loglevel": true + "loglevel": true, + "@metamask/profile-sync-controller>siwe": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api": { + "@metamask/queued-request-controller": { "packages": { - "@metamask/keyring-api>bech32": true, - "@metamask/keyring-controller>@metamask/keyring-api>@metamask/keyring-utils": true, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/rpc-errors": true, + "@metamask/selected-network-controller": true, + "@metamask/utils": true } }, - "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { + "@metamask/rate-limit-controller": { + "globals": { + "setTimeout": true + }, + "packages": { + "@metamask/rate-limit-controller>@metamask/base-controller": true, + "@metamask/rate-limit-controller>@metamask/rpc-errors": true, + "@metamask/rate-limit-controller>@metamask/utils": true + } + }, + "@metamask/remote-feature-flag-controller": { + "packages": { + "@metamask/base-controller": true, + "cockatiel": true, + "uuid": true + } + }, + "@metamask/rpc-errors": { + "packages": { + "@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/rate-limit-controller>@metamask/rpc-errors": { + "packages": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "@metamask/safe-event-emitter": { + "globals": { + "setTimeout": true + }, + "packages": { + "webpack>events": true + } + }, + "@metamask/scure-bip39": { "globals": { - "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, - "@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true + "@metamask/scure-bip39>@noble/hashes": true, + "@metamask/utils>@scure/base": true } }, - "@metamask/profile-sync-controller>@noble/ciphers": { + "@metamask/selected-network-controller": { + "packages": { + "@metamask/base-controller": true, + "@metamask/network-controller>@metamask/swappable-obj-proxy": true + } + }, + "@metamask/signature-controller": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "crypto": true + "fetch": true + }, + "packages": { + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/signature-controller>@metamask/eth-sig-util": true, + "@metamask/keyring-controller": true, + "@metamask/logging-controller": true, + "@metamask/utils": true, + "browserify>buffer": true, + "webpack>events": true, + "@metamask/message-manager>jsonschema": true, + "uuid": true } }, - "@metamask/profile-sync-controller>siwe": { + "@metamask/smart-transactions-controller": { "globals": { + "URLSearchParams": true, + "clearInterval": true, "console.error": true, - "console.warn": true + "console.log": true, + "fetch": true, + "setInterval": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random": true, - "ethers": true + "@metamask/smart-transactions-controller>@ethereumjs/tx": true, + "@metamask/smart-transactions-controller>@ethereumjs/util": true, + "@ethersproject/bytes": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/polling-controller": true, + "@metamask/transaction-controller": true, + "@metamask/smart-transactions-controller>bignumber.js": true, + "browserify>buffer": true, + "fast-json-patch": true, + "lodash": true } }, - "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "@metamask/snaps-controllers": { "globals": { - "console.error": true, - "console.log": true + "DecompressionStream": true, + "URL": true, + "clearTimeout": true, + "document.getElementById": true, + "fetch.bind": true, + "setTimeout": true }, "packages": { - "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true, - "@noble/hashes": true + "@metamask/base-controller": true, + "@metamask/json-rpc-engine": true, + "@metamask/json-rpc-middleware-stream": true, + "@metamask/object-multiplex": true, + "@metamask/permission-controller": true, + "@metamask/post-message-stream": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/snaps-registry": true, + "@metamask/snaps-rpc-methods": true, + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/snaps-controllers>@metamask/utils": true, + "@metamask/snaps-controllers>@xstate/fsm": true, + "@metamask/name-controller>async-mutex": true, + "browserify>browserify-zlib": true, + "@metamask/snaps-controllers>concat-stream": true, + "eslint>fast-deep-equal": true, + "@metamask/snaps-controllers>get-npm-tarball-url": true, + "immer": true, + "luxon": true, + "nanoid": true, + "readable-stream": true, + "@metamask/snaps-controllers>readable-web-to-node-stream": true, + "semver": true, + "@metamask/snaps-controllers>tar-stream": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random": { + "@metamask/snaps-execution-environments": { "globals": { - "crypto": true, - "msCrypto": true + "document.getElementById": true }, "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, - "browserify>browser-resolve": true + "@metamask/post-message-stream": true, + "@metamask/snaps-utils": true, + "@metamask/utils": true, + "@metamask/snaps-execution-environments>@metamask/utils": true } }, - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "@metamask/snaps-utils>@metamask/snaps-registry": { "packages": { - "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@noble/hashes": true } }, - "@metamask/queued-request-controller": { + "@metamask/snaps-rpc-methods": { "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, "@metamask/rpc-errors": true, - "@metamask/selected-network-controller": true, - "@metamask/utils": true + "@metamask/snaps-sdk": true, + "@metamask/snaps-utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-rpc-methods>@metamask/utils": true, + "@noble/hashes": true, + "luxon": true } }, - "@metamask/rate-limit-controller": { + "@metamask/snaps-sdk": { "globals": { + "fetch": true + }, + "packages": { + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-sdk>@metamask/utils": true + } + }, + "@metamask/snaps-utils": { + "globals": { + "File": true, + "FileReader": true, + "TextDecoder": true, + "TextEncoder": true, + "URL": true, + "console.error": true, + "console.log": true, + "console.warn": true, + "crypto": true, + "document.body.appendChild": true, + "document.createElement": true, + "fetch": true + }, + "packages": { + "@metamask/snaps-sdk>@metamask/key-tree": true, + "@metamask/permission-controller": true, + "@metamask/rpc-errors": true, + "@metamask/snaps-utils>@metamask/slip44": true, + "@metamask/snaps-sdk": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/snaps-utils>@metamask/utils": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "chalk": true, + "@metamask/snaps-utils>cron-parser": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "@metamask/snaps-utils>fast-xml-parser": true, + "@metamask/snaps-utils>marked": true, + "@metamask/snaps-utils>rfdc": true, + "semver": true, + "@metamask/snaps-utils>validate-npm-package-name": true + } + }, + "@metamask/transaction-controller": { + "globals": { + "clearTimeout": true, + "console.error": true, + "fetch": true, "setTimeout": true }, "packages": { - "@metamask/rate-limit-controller>@metamask/base-controller": true, - "@metamask/rate-limit-controller>@metamask/rpc-errors": true, - "@metamask/rate-limit-controller>@metamask/utils": true + "@ethereumjs/tx>@ethereumjs/common": true, + "@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, + "@ethersproject/abi": true, + "@ethersproject/contracts": true, + "@ethersproject/providers": true, + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/metamask-eth-abis": true, + "@metamask/network-controller": true, + "@metamask/transaction-controller>@metamask/nonce-tracker": true, + "@metamask/rpc-errors": true, + "@metamask/transaction-controller>@metamask/utils": true, + "@metamask/name-controller>async-mutex": true, + "bn.js": true, + "browserify>buffer": true, + "eth-method-registry": true, + "webpack>events": true, + "fast-json-patch": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/base-controller": { + "@metamask/user-operation-controller": { "globals": { - "setTimeout": true + "fetch": true }, "packages": { - "immer": true - } - }, - "@metamask/rate-limit-controller>@metamask/rpc-errors": { - "packages": { - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true + "@metamask/base-controller": true, + "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, + "@metamask/gas-fee-controller": true, + "@metamask/polling-controller": true, + "@metamask/rpc-errors": true, + "@metamask/utils>@metamask/superstruct": true, + "@metamask/transaction-controller": true, + "@metamask/utils": true, + "bn.js": true, + "webpack>events": true, + "lodash": true, + "uuid": true } }, - "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rate-limit-controller>@metamask/utils": { + "@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/remote-feature-flag-controller": { - "packages": { - "@metamask/base-controller": true, - "cockatiel": true - } - }, - "@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>@metamask/utils": true, - "@metamask/rpc-errors>fast-safe-stringify": true - } - }, - "@metamask/rpc-errors>@metamask/utils": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/rpc-methods-flask>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/rpc-methods>nanoid": { - "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/safe-event-emitter": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { "globals": { - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39": { + "@metamask/browser-passworder>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true }, "packages": { - "@metamask/scure-bip39>@noble/hashes": true, - "@metamask/utils>@scure/base": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/scure-bip39>@noble/hashes": { + "@metamask/controller-utils>@metamask/utils": { "globals": { - "TextEncoder": true, - "crypto": true - } - }, - "@metamask/selected-network-controller": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/base-controller": true, - "@metamask/network-controller>@metamask/swappable-obj-proxy": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller": { + "@metamask/eth-token-tracker>@metamask/eth-block-tracker>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/keyring-controller": true, - "@metamask/logging-controller": true, - "@metamask/message-manager>jsonschema": true, - "@metamask/signature-controller>@metamask/eth-sig-util": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util": { + "@metamask/network-controller>@metamask/eth-block-tracker>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/abi-utils": true, - "@metamask/eth-sig-util>tweetnacl": true, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "browserify>buffer": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "@metamask/keyring-controller>@metamask/eth-hd-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/smart-transactions-controller": { + "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": { "globals": { - "URLSearchParams": true, - "clearInterval": true, - "console.error": true, - "console.log": true, - "fetch": true, - "setInterval": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bytes": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/polling-controller": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/transaction-controller": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "fast-json-patch": true, - "lodash": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx": { - "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "@metamask/smart-transactions-controller>@ethereumjs/util": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/common": { - "packages": { - "@metamask/smart-transactions-controller>@ethereumjs/util": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": { + "@metamask/eth-json-rpc-middleware>@metamask/utils": { "globals": { + "TextDecoder": true, "TextEncoder": true - } - }, - "@metamask/smart-transactions-controller>@ethereumjs/util": { - "globals": { - "console.warn": true, - "fetch": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/smart-transactions-controller>@ethereumjs/tx>@ethereumjs/rlp": true, - "webpack>events": true - } - }, - "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { - "globals": { - "crypto.getRandomValues": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/smart-transactions-controller>bignumber.js": { + "@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers": { + "@metamask/eth-ledger-bridge-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "DecompressionStream": true, - "URL": true, - "clearTimeout": true, - "document.getElementById": true, - "fetch.bind": true, - "setTimeout": true - }, - "packages": { - "@metamask/base-controller": true, - "@metamask/json-rpc-engine": true, - "@metamask/json-rpc-middleware-stream": true, - "@metamask/object-multiplex": true, - "@metamask/permission-controller": true, - "@metamask/post-message-stream": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-controllers>@xstate/fsm": true, - "@metamask/snaps-controllers>concat-stream": true, - "@metamask/snaps-controllers>get-npm-tarball-url": true, - "@metamask/snaps-controllers>readable-web-to-node-stream": true, - "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-rpc-methods": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-utils": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, - "@metamask/utils": true, - "browserify>browserify-zlib": true, - "eslint>fast-deep-equal": true, - "immer": true, - "nanoid": true, - "readable-stream": true, + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-controllers-flask>nanoid": { + "@metamask/eth-snap-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true - } - }, - "@metamask/snaps-controllers>concat-stream": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "readable-stream": true, - "terser>source-map-support>buffer-from": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>nanoid": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util>@metamask/utils": { "globals": { - "crypto.getRandomValues": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>readable-web-to-node-stream": { + "@metamask/signature-controller>@metamask/eth-sig-util>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "readable-stream": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream": { + "@metamask/keyring-controller>@metamask/eth-simple-keyring>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>b4a": true, - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx": true, - "browserify>browser-resolve": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>b4a": { + "@metamask/eth-snap-keyring>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx": { + "@metamask/json-rpc-engine>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-controllers>tar-stream>fast-fifo": true, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true, - "webpack>events": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { + "@metamask/json-rpc-middleware-stream>@metamask/utils": { "globals": { - "queueMicrotask": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-execution-environments": { + "@metamask/snaps-sdk>@metamask/key-tree>@metamask/utils": { "globals": { - "document.getElementById": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/post-message-stream": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-rpc-methods": { + "@metamask/keyring-api>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk": { + "@metamask/profile-sync-controller>@metamask/keyring-api>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/rpc-errors": true, - "@metamask/utils": true, - "@metamask/utils>@metamask/superstruct": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-sdk>@metamask/key-tree": { + "@metamask/keyring-controller>@metamask/utils": { "globals": { - "crypto.subtle": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/scure-bip39": true, - "@metamask/utils": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, "@metamask/utils>@scure/base": true, - "@noble/hashes": true + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils": { + "@metamask/keyring-api>@metamask/keyring-utils>@metamask/utils": { "globals": { - "File": true, - "FileReader": true, "TextDecoder": true, - "TextEncoder": true, - "URL": true, - "console.error": true, - "console.log": true, - "console.warn": true, - "crypto": true, - "document.body.appendChild": true, - "document.createElement": true, - "fetch": true + "TextEncoder": true }, "packages": { - "@metamask/permission-controller": true, - "@metamask/rpc-errors": true, - "@metamask/snaps-sdk": true, - "@metamask/snaps-sdk>@metamask/key-tree": true, - "@metamask/snaps-utils>@metamask/slip44": true, - "@metamask/snaps-utils>cron-parser": true, - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "@metamask/snaps-utils>fast-xml-parser": true, - "@metamask/snaps-utils>marked": true, - "@metamask/snaps-utils>rfdc": true, - "@metamask/snaps-utils>validate-npm-package-name": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, "@noble/hashes": true, - "chalk": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "@noble/hashes": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>cron-parser": { + "@metamask/permission-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>browser-resolve": true, - "luxon": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>fast-xml-parser": { + "@metamask/permission-log-controller>@metamask/utils": { "globals": { - "entityName": true, - "val": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/snaps-utils>fast-xml-parser>strnum": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>marked": { + "@metamask/post-message-stream>@metamask/utils": { "globals": { - "console.error": true, - "console.warn": true, - "define": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>rfdc": { + "@metamask/rate-limit-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "browserify>buffer": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name": { + "@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/snaps-utils>validate-npm-package-name>builtins": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/snaps-utils>validate-npm-package-name>builtins": { + "@metamask/rate-limit-controller>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "process": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/test-bundler>@ethersproject/networks": { + "@metamask/snaps-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "ethers>@ethersproject/logger": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller": { + "@metamask/snaps-execution-environments>@metamask/utils": { "globals": { - "clearTimeout": true, - "console.error": true, - "fetch": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethereumjs/tx": true, - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/abi": true, - "@ethersproject/contracts": true, - "@ethersproject/providers": true, - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/metamask-eth-abis": true, - "@metamask/name-controller>async-mutex": true, - "@metamask/network-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller>@metamask/nonce-tracker": true, - "@metamask/utils": true, - "bn.js": true, + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, - "eth-method-registry": true, - "fast-json-patch": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker": { + "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@ethersproject/providers": true, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true, - "browserify>assert": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { + "@metamask/snaps-rpc-methods>@metamask/utils": { "globals": { - "clearTimeout": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@swc/helpers>tslib": true + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/user-operation-controller": { + "@metamask/snaps-sdk>@metamask/utils": { "globals": { - "fetch": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@metamask/base-controller": true, - "@metamask/controller-utils": true, - "@metamask/eth-query": true, - "@metamask/gas-fee-controller": true, - "@metamask/polling-controller": true, - "@metamask/rpc-errors": true, - "@metamask/transaction-controller": true, - "@metamask/utils": true, "@metamask/utils>@metamask/superstruct": true, - "bn.js": true, - "lodash": true, - "uuid": true, - "webpack>events": true + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, - "@metamask/utils": { + "@metamask/snaps-utils>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "browserify>buffer": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/utils>@scure/base": { + "@metamask/transaction-controller>@metamask/utils": { "globals": { "TextDecoder": true, "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@noble/hashes": true, + "@metamask/utils>@scure/base": true, + "browserify>buffer": true, + "nock>debug": true, + "@metamask/utils>pony-cause": true, + "semver": true } }, "@ngraveio/bc-ur": { "packages": { "@ngraveio/bc-ur>@keystonehq/alias-sampling": true, + "browserify>assert": true, "@ngraveio/bc-ur>bignumber.js": true, + "browserify>buffer": true, "@ngraveio/bc-ur>cbor-sync": true, "@ngraveio/bc-ur>crc": true, "@ngraveio/bc-ur>jsbi": true, - "addons-linter>sha.js": true, - "browserify>assert": true, - "browserify>buffer": true + "addons-linter>sha.js": true } }, - "@ngraveio/bc-ur>assert>object-is": { + "@metamask/profile-sync-controller>@noble/ciphers": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "crypto": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": { + "globals": { + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true } }, - "@ngraveio/bc-ur>bignumber.js": { + "@noble/hashes": { "globals": { - "crypto": true, - "define": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>cbor-sync": { + "@metamask/scure-bip39>@noble/hashes": { "globals": { - "define": true - }, - "packages": { - "browserify>buffer": true + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>crc": { - "packages": { - "browserify>buffer": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, - "@ngraveio/bc-ur>jsbi": { + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": { "globals": { - "define": true + "TextEncoder": true, + "crypto": true } }, - "@noble/hashes": { + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true + } + }, + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { "globals": { "TextEncoder": true, "crypto": true @@ -2927,6 +2649,20 @@ "navigator.userAgent": true } }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "globals": { + "console.log": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "globals": { + "XMLHttpRequest": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + } + }, "@reduxjs/toolkit": { "globals": { "AbortController": true, @@ -2938,42 +2674,46 @@ "setTimeout": true }, "packages": { - "@reduxjs/toolkit>reselect": true, "immer": true, "process": true, "redux": true, - "redux-thunk": true - } - }, - "@segment/loosely-validate-event": { - "packages": { - "@segment/loosely-validate-event>component-type": true, - "@segment/loosely-validate-event>join-component": true, - "browserify>assert": true, - "browserify>buffer": true + "redux-thunk": true, + "@reduxjs/toolkit>reselect": true } }, - "@sentry/browser": { + "react-router-dom-v5-compat>@remix-run/router": { "globals": { - "PerformanceObserver.supportedEntryTypes": true, + "AbortController": true, + "DOMException": true, + "FormData": true, + "Headers": true, "Request": true, + "Response": true, "URL": true, - "XMLHttpRequest.prototype": true, - "__SENTRY_DEBUG__": true, - "__SENTRY_RELEASE__": true, - "addEventListener": true, - "console.error": true, - "indexedDB.open": true, - "performance.timeOrigin": true, - "setTimeout": true - }, + "URLSearchParams": true, + "console": true, + "document.defaultView": true + } + }, + "@metamask/utils>@scure/base": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + } + }, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": { + "packages": { + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true, + "@metamask/utils>@scure/base": true + } + }, + "@segment/loosely-validate-event": { "packages": { - "@sentry/browser>@sentry-internal/browser-utils": true, - "@sentry/browser>@sentry-internal/feedback": true, - "@sentry/browser>@sentry-internal/replay": true, - "@sentry/browser>@sentry-internal/replay-canvas": true, - "@sentry/browser>@sentry/core": true, - "@sentry/utils": true + "browserify>assert": true, + "browserify>buffer": true, + "@segment/loosely-validate-event>component-type": true, + "@segment/loosely-validate-event>join-component": true } }, "@sentry/browser>@sentry-internal/browser-utils": { @@ -3012,6 +2752,25 @@ "@sentry/utils": true } }, + "@sentry/browser>@sentry-internal/replay-canvas": { + "globals": { + "Blob": true, + "HTMLCanvasElement": true, + "HTMLImageElement": true, + "ImageData": true, + "URL.createObjectURL": true, + "WeakRef": true, + "Worker": true, + "cancelAnimationFrame": true, + "console.error": true, + "createImageBitmap": true, + "document": true + }, + "packages": { + "@sentry/browser>@sentry/core": true, + "@sentry/utils": true + } + }, "@sentry/browser>@sentry-internal/replay": { "globals": { "Blob": true, @@ -3061,21 +2820,25 @@ "@sentry/utils": true } }, - "@sentry/browser>@sentry-internal/replay-canvas": { + "@sentry/browser": { "globals": { - "Blob": true, - "HTMLCanvasElement": true, - "HTMLImageElement": true, - "ImageData": true, - "URL.createObjectURL": true, - "WeakRef": true, - "Worker": true, - "cancelAnimationFrame": true, + "PerformanceObserver.supportedEntryTypes": true, + "Request": true, + "URL": true, + "XMLHttpRequest.prototype": true, + "__SENTRY_DEBUG__": true, + "__SENTRY_RELEASE__": true, + "addEventListener": true, "console.error": true, - "createImageBitmap": true, - "document": true + "indexedDB.open": true, + "performance.timeOrigin": true, + "setTimeout": true }, "packages": { + "@sentry/browser>@sentry-internal/browser-utils": true, + "@sentry/browser>@sentry-internal/feedback": true, + "@sentry/browser>@sentry-internal/replay-canvas": true, + "@sentry/browser>@sentry-internal/replay": true, "@sentry/browser>@sentry/core": true, "@sentry/utils": true } @@ -3171,20 +2934,61 @@ "btoa": true } }, - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { + "@metamask/controller-utils>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "react-markdown>unist-util-visit": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true } }, - "@storybook/addon-knobs>qs": { + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": { + "globals": { + "console.error": true, + "console.log": true + }, "packages": { - "string.prototype.matchall>side-channel": true + "@noble/hashes": true, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": true + } + }, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": { + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary>@stablelib/int": true } }, - "@swc/helpers>tslib": { + "@metamask/profile-sync-controller>siwe>@stablelib/random": { "globals": { - "SuppressedError": true, - "define": true + "crypto": true, + "msCrypto": true + }, + "packages": { + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/binary": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random>@stablelib/wipe": true, + "browserify>browser-resolve": true + } + }, + "@trezor/connect-web>@trezor/connect-common": { + "globals": { + "console.warn": true, + "localStorage.getItem": true, + "localStorage.setItem": true, + "navigator": true, + "setTimeout": true, + "window": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, + "@trezor/connect-web>@trezor/utils": true, + "tslib": true + } + }, + "@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": { + "packages": { + "@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true, + "tslib": true } }, "@trezor/connect-web": { @@ -3211,35 +3015,20 @@ "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/connect-common": true, + "@trezor/connect-web>@trezor/connect": true, "@trezor/connect-web>@trezor/utils": true, - "webpack>events": true + "webpack>events": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect": { "packages": { - "@swc/helpers>tslib": true, "@trezor/connect-web>@trezor/connect>@trezor/protobuf": true, "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, "@trezor/connect-web>@trezor/connect>@trezor/transport": true, - "@trezor/connect-web>@trezor/utils": true - } - }, - "@trezor/connect-web>@trezor/connect-common": { - "globals": { - "console.warn": true, - "localStorage.getItem": true, - "localStorage.setItem": true, - "navigator": true, - "setTimeout": true, - "window": true - }, - "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": true, - "@trezor/connect-web>@trezor/utils": true + "@trezor/connect-web>@trezor/utils": true, + "tslib": true } }, "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils": { @@ -3255,157 +3044,248 @@ "screen.width": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true, - "process": true + "process": true, + "tslib": true, + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": true } }, - "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, + "browserify>buffer": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, + "tslib": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { "globals": { - "define": true + "console.warn": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, + "browserify>buffer": true, + "ts-mixer": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf": { + "@trezor/connect-web>@trezor/utils": { + "globals": { + "AbortController": true, + "Intl.NumberFormat": true, + "clearInterval": true, + "clearTimeout": true, + "console.error": true, + "console.info": true, + "console.log": true, + "console.warn": true, + "setInterval": true, + "setTimeout": true + }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true, - "browserify>buffer": true + "@trezor/connect-web>@trezor/utils>bignumber.js": true, + "browserify>buffer": true, + "webpack>events": true, + "tslib": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { + "@welldone-software/why-did-you-render": { "globals": { - "process": true, + "Element": true, + "console.group": true, + "console.groupCollapsed": true, + "console.groupEnd": true, + "console.log": true, + "console.warn": true, + "define": true, "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true + "lodash": true, + "react": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": { + "@zxing/browser": { "globals": { - "console.log": true + "HTMLElement": true, + "HTMLImageElement": true, + "HTMLVideoElement": true, + "clearTimeout": true, + "console.error": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library": true + } + }, + "@zxing/library": { + "globals": { + "HTMLImageElement": true, + "HTMLVideoElement": true, + "TextDecoder": true, + "TextEncoder": true, + "URL.createObjectURL": true, + "btoa": true, + "console.log": true, + "console.warn": true, + "document": true, + "navigator": true, + "setTimeout": true + }, + "packages": { + "@zxing/library>ts-custom-error": true + } + }, + "@lavamoat/lavapack>readable-stream>abort-controller": { + "globals": { + "AbortController": true + } + }, + "currency-formatter>accounting": { + "globals": { + "define": true + } + }, + "ethers>@ethersproject/json-wallets>aes-js": { + "globals": { + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>aes-js": { + "globals": { + "define": true + } + }, + "chalk>ansi-styles": { + "packages": { + "chalk>ansi-styles>color-convert": true + } + }, + "@metamask/controller-utils>@spruceid/siwe-parser>apg-js": { + "packages": { + "browserify>buffer": true + } + }, + "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true + } + }, + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "browserify>vm-browserify": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": { + "browserify>assert": { "globals": { - "XMLHttpRequest": true + "Buffer": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, - "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true + "react>object-assign": true, + "browserify>assert>util": true } }, - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils": { + "@metamask/name-controller>async-mutex": { "globals": { - "console.warn": true + "clearTimeout": true, + "setTimeout": true }, "packages": { - "@trezor/connect-web>@trezor/connect>@trezor/schema-utils>@sinclair/typebox": true, - "browserify>buffer": true, - "ts-mixer": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils": { + "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": { "globals": { - "AbortController": true, - "Intl.NumberFormat": true, - "clearInterval": true, "clearTimeout": true, - "console.error": true, - "console.info": true, - "console.log": true, - "console.warn": true, - "setInterval": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true, - "@trezor/connect-web>@trezor/utils>bignumber.js": true, - "browserify>buffer": true, - "webpack>events": true + "tslib": true } }, - "@trezor/connect-web>@trezor/utils>bignumber.js": { - "globals": { - "crypto": true, - "define": true + "string.prototype.matchall>es-abstract>available-typed-arrays": { + "packages": { + "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true } }, - "@welldone-software/why-did-you-render": { + "await-semaphore": { + "packages": { + "process": true, + "browserify>timers-browserify": true + } + }, + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>axios": { "globals": { - "Element": true, - "console.group": true, - "console.groupCollapsed": true, - "console.groupEnd": true, - "console.log": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, - "define": true, + "document": true, + "location.href": true, + "navigator": true, "setTimeout": true }, "packages": { - "lodash": true, - "react": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/browser": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>@ledgerhq/evm-tools>axios": { "globals": { - "HTMLElement": true, - "HTMLImageElement": true, - "HTMLVideoElement": true, - "clearTimeout": true, - "console.error": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, + "btoa": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "@zxing/library": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>axios": { "globals": { - "HTMLImageElement": true, - "HTMLVideoElement": true, - "TextDecoder": true, - "TextEncoder": true, - "URL.createObjectURL": true, + "Blob": true, + "FormData": true, + "URLSearchParams": true, + "XMLHttpRequest": true, "btoa": true, - "console.log": true, "console.warn": true, "document": true, + "location.href": true, "navigator": true, "setTimeout": true }, "packages": { - "@zxing/library>ts-custom-error": true + "browserify>buffer": true, + "axios>form-data": true, + "process": true } }, - "addons-linter>sha.js": { - "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@metamask/snaps-controllers>tar-stream>b4a": { + "globals": { + "TextDecoder": true, + "TextEncoder": true } }, - "await-semaphore": { + "@ensdomains/content-hash>multihashes>multibase>base-x": { "packages": { - "browserify>timers-browserify": true, - "process": true - } - }, - "axios>form-data": { - "globals": { - "FormData": true + "koa>content-disposition>safe-buffer": true } }, "base32-encode": { @@ -3419,139 +3299,178 @@ "define": true } }, - "blo": { + "@metamask/eth-ledger-bridge-keyring>@ledgerhq/hw-app-eth>bignumber.js": { "globals": { - "btoa": true + "crypto": true, + "define": true } }, - "bn.js": { + "@metamask/notification-services-controller>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "define": true } }, - "bowser": { + "@metamask/smart-transactions-controller>bignumber.js": { "globals": { + "crypto": true, "define": true } }, - "browserify>assert": { + "@ngraveio/bc-ur>bignumber.js": { "globals": { - "Buffer": true - }, - "packages": { - "browserify>assert>util": true, - "react>object-assign": true + "crypto": true, + "define": true } }, - "browserify>assert>util": { + "@trezor/connect-web>@trezor/utils>bignumber.js": { "globals": { - "console.error": true, - "console.log": true, - "console.trace": true, - "process": true - }, + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "globals": { + "crypto": true, + "define": true + } + }, + "eth-lattice-keyring>gridplus-sdk>bitwise": { "packages": { - "browserify>assert>util>inherits": true, - "process": true + "browserify>buffer": true } }, - "browserify>browserify-zlib": { + "blo": { + "globals": { + "btoa": true + } + }, + "bn.js": { + "globals": { + "Buffer": true + }, "packages": { - "browserify>assert": true, - "browserify>browserify-zlib>pako": true, - "browserify>buffer": true, - "browserify>util": true, - "process": true, - "stream-browserify": true + "browserify>browser-resolve": true } }, - "browserify>buffer": { + "eth-lattice-keyring>gridplus-sdk>borc": { "globals": { "console": true }, "packages": { - "base64-js": true, - "buffer>ieee754": true + "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, + "browserify>buffer": true, + "buffer>ieee754": true, + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true } }, - "browserify>punycode": { + "bowser": { "globals": { "define": true } }, - "browserify>string_decoder": { + "@metamask/ppom-validator>elliptic>brorand": { + "globals": { + "crypto": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "ethereumjs-util>ethereum-cryptography>browserify-aes": { "packages": { + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "pumpify>inherits": true, "koa>content-disposition>safe-buffer": true } }, - "browserify>timers-browserify": { - "globals": { - "clearInterval": true, - "clearTimeout": true, - "setInterval": true, - "setTimeout": true - }, + "crypto-browserify>browserify-cipher": { "packages": { - "process": true + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "crypto-browserify>browserify-cipher>browserify-des": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true } }, - "browserify>url": { + "crypto-browserify>browserify-cipher>browserify-des": { "packages": { - "@storybook/addon-knobs>qs": true, - "browserify>punycode": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>cipher-base": true, + "crypto-browserify>browserify-cipher>browserify-des>des.js": true, + "pumpify>inherits": true } }, - "browserify>util": { - "globals": { - "console.error": true, - "console.log": true, - "console.trace": true - }, + "crypto-browserify>public-encrypt>browserify-rsa": { "packages": { - "browserify>util>is-arguments": true, - "browserify>util>is-typed-array": true, - "browserify>util>which-typed-array": true, - "koa>is-generator-function": true, + "bn.js": true, + "browserify>buffer": true, + "crypto-browserify>randombytes": true + } + }, + "crypto-browserify>browserify-sign": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>create-hmac": true, + "@metamask/ppom-validator>elliptic": true, + "pumpify>inherits": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "stream-browserify": true + } + }, + "browserify>browserify-zlib": { + "packages": { + "browserify>assert": true, + "browserify>buffer": true, + "browserify>browserify-zlib>pako": true, "process": true, - "pumpify>inherits": true + "stream-browserify": true, + "browserify>util": true } }, - "browserify>util>is-arguments": { + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true } }, - "browserify>util>is-typed-array": { + "ethereumjs-util>ethereum-cryptography>bs58check": { "packages": { - "browserify>util>which-typed-array": true + "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, + "ethereumjs-util>create-hash": true, + "koa>content-disposition>safe-buffer": true } }, - "browserify>util>which-typed-array": { + "buffer": { + "globals": { + "console": true + }, "packages": { - "browserify>util>which-typed-array>for-each": true, - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>available-typed-arrays": true, - "string.prototype.matchall>es-abstract>gopd": true + "base64-js": true, + "buffer>ieee754": true } }, - "browserify>util>which-typed-array>for-each": { + "terser>source-map-support>buffer-from": { "packages": { - "string.prototype.matchall>es-abstract>is-callable": true + "browserify>buffer": true } }, - "browserify>vm-browserify": { - "globals": { - "document.body.appendChild": true, - "document.body.removeChild": true, - "document.createElement": true + "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "packages": { + "browserify>buffer": true } }, - "buffer": { + "browserify>buffer": { "globals": { "console": true }, @@ -3560,20 +3479,33 @@ "buffer>ieee754": true } }, - "chalk": { + "@metamask/snaps-utils>validate-npm-package-name>builtins": { "packages": { - "chalk>ansi-styles": true, - "chalk>supports-color": true + "process": true, + "semver": true } }, - "chalk>ansi-styles": { + "string.prototype.matchall>call-bind": { "packages": { - "chalk>ansi-styles>color-convert": true + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>call-bind>set-function-length": true } }, - "chalk>ansi-styles>color-convert": { + "@ngraveio/bc-ur>cbor-sync": { + "globals": { + "define": true + }, "packages": { - "jest-canvas-mock>moo-color>color-name": true + "browserify>buffer": true + } + }, + "chalk": { + "packages": { + "chalk>ansi-styles": true, + "chalk>supports-color": true } }, "chart.js": { @@ -3597,9 +3529,20 @@ "chart.js>@kurkle/color": true } }, - "chart.js>@kurkle/color": { - "globals": { - "define": true + "@ensdomains/content-hash>cids": { + "packages": { + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>multicodec": true, + "@ensdomains/content-hash>cids>multihashes": true, + "@ensdomains/content-hash>cids>uint8arrays": true + } + }, + "ethereumjs-util>create-hash>cipher-base": { + "packages": { + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true, + "stream-browserify": true, + "browserify>string_decoder": true } }, "classnames": { @@ -3608,6 +3551,11 @@ "define": true } }, + "@metamask/jazzicon>color>clone": { + "packages": { + "browserify>buffer": true + } + }, "cockatiel": { "globals": { "AbortController": true, @@ -3621,6 +3569,37 @@ "process": true } }, + "chalk>ansi-styles>color-convert": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color>color-convert": { + "packages": { + "@metamask/jazzicon>color>color-convert>color-name": true + } + }, + "@metamask/jazzicon>color>color-string": { + "packages": { + "jest-canvas-mock>moo-color>color-name": true + } + }, + "@metamask/jazzicon>color": { + "packages": { + "@metamask/jazzicon>color>clone": true, + "@metamask/jazzicon>color>color-convert": true, + "@metamask/jazzicon>color>color-string": true + } + }, + "@metamask/snaps-controllers>concat-stream": { + "packages": { + "terser>source-map-support>buffer-from": true, + "browserify>buffer": true, + "pumpify>inherits": true, + "readable-stream": true, + "browserify>concat-stream>typedarray": true + } + }, "copy-to-clipboard": { "globals": { "clipboardData": true, @@ -3639,10 +3618,47 @@ "copy-to-clipboard>toggle-selection": true } }, - "copy-to-clipboard>toggle-selection": { + "@ethereumjs/tx>@ethereumjs/common>crc-32": { "globals": { - "document.activeElement": true, - "document.getSelection": true + "DO_NOT_EXPORT_CRC": true, + "define": true + } + }, + "@ngraveio/bc-ur>crc": { + "packages": { + "browserify>buffer": true + } + }, + "crypto-browserify>create-ecdh": { + "packages": { + "bn.js": true, + "browserify>buffer": true, + "@metamask/ppom-validator>elliptic": true + } + }, + "ethereumjs-util>create-hash": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>md5.js": true, + "ethereumjs-util>create-hash>ripemd160": true, + "addons-linter>sha.js": true + } + }, + "crypto-browserify>create-hmac": { + "packages": { + "ethereumjs-util>create-hash>cipher-base": true, + "ethereumjs-util>create-hash": true, + "pumpify>inherits": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true + } + }, + "@metamask/snaps-utils>cron-parser": { + "packages": { + "browserify>browser-resolve": true, + "luxon": true } }, "crypto-browserify": { @@ -3650,303 +3666,453 @@ "crypto-browserify>browserify-cipher": true, "crypto-browserify>browserify-sign": true, "crypto-browserify>create-ecdh": true, + "ethereumjs-util>create-hash": true, "crypto-browserify>create-hmac": true, "crypto-browserify>diffie-hellman": true, "crypto-browserify>pbkdf2": true, "crypto-browserify>public-encrypt": true, "crypto-browserify>randombytes": true, - "crypto-browserify>randomfill": true, - "ethereumjs-util>create-hash": true + "crypto-browserify>randomfill": true } }, - "crypto-browserify>browserify-cipher": { + "@metamask/ppom-validator>crypto-js": { + "globals": { + "crypto": true, + "define": true, + "msCrypto": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "react-beautiful-dnd>css-box-model": { + "globals": { + "getComputedStyle": true, + "pageXOffset": true, + "pageYOffset": true + }, + "packages": { + "react-router-dom>tiny-invariant": true + } + }, + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { + "globals": { + "document.createElement": true, + "document.documentElement": true, + "getComputedStyle": true + }, + "packages": { + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true + } + }, + "currency-formatter": { + "packages": { + "currency-formatter>accounting": true, + "currency-formatter>locale-currency": true, + "react>object-assign": true + } + }, + "debounce-stream": { + "packages": { + "debounce-stream>debounce": true, + "debounce-stream>duplexer": true, + "debounce-stream>through": true + } + }, + "debounce-stream>debounce": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "nock>debug": { + "globals": { + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true + }, + "packages": { + "nock>debug>ms": true, + "process": true + } + }, + "@metamask/eth-token-tracker>deep-equal": { + "packages": { + "string.prototype.matchall>es-abstract>array-buffer-byte-length": true, + "string.prototype.matchall>call-bind": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": true, + "string.prototype.matchall>get-intrinsic": true, + "browserify>util>is-arguments": true, + "string.prototype.matchall>es-abstract>is-array-buffer": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "string.prototype.matchall>es-abstract>is-regex": true, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "@ngraveio/bc-ur>assert>object-is": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true, + "gulp>vinyl-fs>object.assign": true, + "string.prototype.matchall>regexp.prototype.flags": true, + "string.prototype.matchall>side-channel": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": true, + "@metamask/eth-token-tracker>deep-equal>which-collection": true, + "browserify>util>which-typed-array": true + } + }, + "string.prototype.matchall>define-properties>define-data-property": { + "packages": { + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>gopd": true + } + }, + "string.prototype.matchall>define-properties": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true + } + }, + "crypto-browserify>browserify-cipher>browserify-des>des.js": { "packages": { - "crypto-browserify>browserify-cipher>browserify-des": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true } }, - "crypto-browserify>browserify-cipher>browserify-des": { + "crypto-browserify>diffie-hellman": { "packages": { + "bn.js": true, "browserify>buffer": true, - "crypto-browserify>browserify-cipher>browserify-des>des.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "pumpify>inherits": true + "crypto-browserify>diffie-hellman>miller-rabin": true, + "crypto-browserify>randombytes": true } }, - "crypto-browserify>browserify-cipher>browserify-des>des.js": { + "@material-ui/core>react-transition-group>dom-helpers": { "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "@babel/runtime": true } }, - "crypto-browserify>browserify-cipher>evp_bytestokey": { + "debounce-stream>duplexer": { "packages": { - "ethereumjs-util>create-hash>md5.js": true, - "koa>content-disposition>safe-buffer": true + "stream-browserify": true } }, - "crypto-browserify>browserify-sign": { + "ethers>@ethersproject/signing-key>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>create-hmac": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "ethereumjs-util>create-hash": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, "pumpify>inherits": true, - "stream-browserify": true + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-ecdh": { + "@metamask/ppom-validator>elliptic": { "packages": { - "@metamask/ppom-validator>elliptic": true, "bn.js": true, - "browserify>buffer": true + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>create-hmac": { + "eth-lattice-keyring>gridplus-sdk>elliptic": { "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true, + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>hmac-drbg": true, + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true } }, - "crypto-browserify>diffie-hellman": { + "string.prototype.matchall>call-bind>es-define-property": { "packages": { - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify>diffie-hellman>miller-rabin": true, - "crypto-browserify>randombytes": true + "string.prototype.matchall>get-intrinsic": true } }, - "crypto-browserify>diffie-hellman>miller-rabin": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "bn.js": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>has-symbols": true, + "browserify>util>is-arguments": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "eslint-plugin-react>array-includes>is-string": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "process": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": true } }, - "crypto-browserify>pbkdf2": { + "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { "globals": { - "crypto": true, - "process": true, - "queueMicrotask": true, - "setImmediate": true, - "setTimeout": true + "intToBuffer": true }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>create-hash>ripemd160": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "bn.js": true, + "buffer": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt": { + "eth-ens-namehash": { + "globals": { + "name": "write" + }, "packages": { - "bn.js": true, "browserify>buffer": true, - "crypto-browserify>public-encrypt>browserify-rsa": true, - "crypto-browserify>public-encrypt>parse-asn1": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>create-hash": true + "eth-ens-namehash>idna-uts46-hx": true, + "eth-ens-namehash>js-sha3": true } }, - "crypto-browserify>public-encrypt>browserify-rsa": { + "eth-lattice-keyring": { + "globals": { + "addEventListener": true, + "browser": true, + "clearInterval": true, + "fetch": true, + "open": true, + "setInterval": true + }, "packages": { + "eth-lattice-keyring>@ethereumjs/tx": true, + "@ethereumjs/tx>@ethereumjs/util": true, "bn.js": true, "browserify>buffer": true, - "crypto-browserify>randombytes": true + "crypto-browserify": true, + "webpack>events": true, + "eth-lattice-keyring>gridplus-sdk": true, + "eth-lattice-keyring>rlp": true } }, - "crypto-browserify>public-encrypt>parse-asn1": { + "eth-method-registry": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "crypto-browserify>pbkdf2": true, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes": true + "eth-method-registry>@metamask/ethjs-contract": true, + "eth-method-registry>@metamask/ethjs-query": true } }, - "crypto-browserify>public-encrypt>parse-asn1>asn1.js": { + "@ethereumjs/tx>ethereum-cryptography": { + "globals": { + "TextDecoder": true, + "crypto": true + }, "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "bn.js": true, - "browserify>buffer": true, - "browserify>vm-browserify": true, - "pumpify>inherits": true + "@ethereumjs/tx>ethereum-cryptography>@noble/curves": true, + "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true, + "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "crypto-browserify>randombytes": { + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "crypto-browserify>randomfill": { + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { "globals": { - "crypto": true, - "msCrypto": true + "TextDecoder": true, + "crypto": true }, "packages": { - "crypto-browserify>randombytes": true, - "koa>content-disposition>safe-buffer": true, - "process": true + "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true } }, - "currency-formatter": { + "ethereumjs-util>ethereum-cryptography": { "packages": { - "currency-formatter>accounting": true, - "currency-formatter>locale-currency": true, - "react>object-assign": true - } - }, - "currency-formatter>accounting": { - "globals": { - "define": true - } - }, - "currency-formatter>locale-currency": { - "globals": { - "countryCode": true + "browserify>buffer": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "ganache>secp256k1": true } }, - "debounce-stream": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": { "packages": { - "debounce-stream>debounce": true, - "debounce-stream>duplexer": true, - "debounce-stream>through": true + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify>create-hmac": true, + "ethers>@ethersproject/sha2>hash.js": true, + "ethereumjs-util>ethereum-cryptography>keccak": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true } }, - "debounce-stream>debounce": { - "globals": { - "clearTimeout": true, - "setTimeout": true + "ethereumjs-util": { + "packages": { + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "ethereumjs-util>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "ethereumjs-util>rlp": true } }, - "debounce-stream>duplexer": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": { "packages": { - "stream-browserify": true + "browserify>assert": true, + "bn.js": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "browserify>insert-module-globals>is-buffer": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": true } }, - "debounce-stream>through": { + "@metamask/keyring-controller>ethereumjs-wallet": { "packages": { - "process": true, - "stream-browserify": true + "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "crypto-browserify": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography": true, + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util": true, + "crypto-browserify>randombytes": true, + "ethers>@ethersproject/json-wallets>scrypt-js": true, + "@metamask/keyring-controller>ethereumjs-wallet>utf8": true, + "uuid": true } }, - "depcheck>@vue/compiler-sfc>postcss>nanoid": { - "globals": { - "crypto.getRandomValues": true + "ethers": { + "packages": { + "@ethersproject/abi": true, + "ethers>@ethersproject/abstract-signer": true, + "ethers>@ethersproject/address": true, + "ethers>@ethersproject/base64": true, + "ethers>@ethersproject/basex": true, + "@ethersproject/bignumber": true, + "@ethersproject/bytes": true, + "ethers>@ethersproject/constants": true, + "@ethersproject/contracts": true, + "@ethersproject/hash": true, + "@ethersproject/hdnode": true, + "ethers>@ethersproject/json-wallets": true, + "ethers>@ethersproject/keccak256": true, + "ethers>@ethersproject/logger": true, + "ethers>@ethersproject/properties": true, + "ethers>@ethersproject/providers": true, + "ethers>@ethersproject/random": true, + "ethers>@ethersproject/rlp": true, + "ethers>@ethersproject/sha2": true, + "ethers>@ethersproject/signing-key": true, + "ethers>@ethersproject/solidity": true, + "ethers>@ethersproject/strings": true, + "ethers>@ethersproject/transactions": true, + "ethers>@ethersproject/units": true, + "@ethersproject/wallet": true, + "ethers>@ethersproject/web": true, + "ethers>@ethersproject/wordlists": true } }, - "depcheck>is-core-module>hasown": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi": { "packages": { - "browserify>has>function-bind": true + "bn.js": true, + "browserify>buffer": true, + "eth-ens-namehash>js-sha3": true, + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": true } }, - "dependency-tree>precinct>detective-postcss>postcss>nanoid": { + "webpack>events": { "globals": { - "crypto.getRandomValues": true + "console": true } }, - "eslint-plugin-react>array-includes>is-string": { + "crypto-browserify>browserify-cipher>evp_bytestokey": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash>md5.js": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-ens-namehash": { - "globals": { - "name": "write" - }, + "extension-port-stream": { "packages": { - "@metamask/ethjs>js-sha3": true, "browserify>buffer": true, - "eth-ens-namehash>idna-uts46-hx": true + "extension-port-stream>readable-stream": true } }, - "eth-ens-namehash>idna-uts46-hx": { + "fast-json-patch": { "globals": { - "define": true + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, + "@metamask/snaps-utils>fast-xml-parser": { + "globals": { + "entityName": true, + "val": true }, "packages": { - "browserify>punycode": true + "@metamask/snaps-utils>fast-xml-parser>strnum": true } }, - "eth-keyring-controller>@metamask/browser-passworder": { - "globals": { - "crypto": true + "@metamask/notification-services-controller>firebase": { + "packages": { + "@metamask/notification-services-controller>firebase>@firebase/app": true, + "@metamask/notification-services-controller>firebase>@firebase/messaging": true } }, - "eth-lattice-keyring": { + "react-focus-lock>focus-lock": { "globals": { - "addEventListener": true, - "browser": true, - "clearInterval": true, - "fetch": true, - "open": true, - "setInterval": true + "HTMLIFrameElement": true, + "Node.DOCUMENT_FRAGMENT_NODE": true, + "Node.DOCUMENT_NODE": true, + "Node.DOCUMENT_POSITION_CONTAINED_BY": true, + "Node.DOCUMENT_POSITION_CONTAINS": true, + "Node.ELEMENT_NODE": true, + "console.error": true, + "console.warn": true, + "document": true, + "getComputedStyle": true, + "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "bn.js": true, - "browserify>buffer": true, - "crypto-browserify": true, - "eth-lattice-keyring>@ethereumjs/tx": true, - "eth-lattice-keyring>gridplus-sdk": true, - "eth-lattice-keyring>rlp": true, - "webpack>events": true + "tslib": true } }, - "eth-lattice-keyring>@ethereumjs/tx": { + "browserify>util>which-typed-array>for-each": { "packages": { - "@ethereumjs/tx>@ethereumjs/common": true, - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>es-abstract>is-callable": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": { - "packages": { - "browserify": true, - "browserify>buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>case": true + "axios>form-data": { + "globals": { + "FormData": true } }, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz>@chainsafe/persistent-merkle-tree": { + "fuse.js": { "globals": { - "WeakRef": true - }, - "packages": { - "browserify": true + "console": true, + "define": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography": { + "string.prototype.matchall>get-intrinsic": { "globals": { - "TextDecoder": true, - "crypto": true + "AggregateError": true, + "FinalizationRegistry": true, + "WeakRef": true }, "packages": { - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true } }, - "eth-lattice-keyring>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true + "string.prototype.matchall>es-abstract>gopd": { + "packages": { + "string.prototype.matchall>get-intrinsic": true } }, "eth-lattice-keyring>gridplus-sdk": { @@ -3964,230 +4130,307 @@ "setTimeout": true }, "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethersproject/abi": true, - "@metamask/ethjs>js-sha3": true, - "@metamask/keyring-api>bech32": true, - "bn.js": true, - "browserify>buffer": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": true, "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": true, + "@ethersproject/abi": true, "eth-lattice-keyring>gridplus-sdk>aes-js": true, + "@metamask/keyring-api>bech32": true, "eth-lattice-keyring>gridplus-sdk>bignumber.js": true, "eth-lattice-keyring>gridplus-sdk>bitwise": true, + "bn.js": true, "eth-lattice-keyring>gridplus-sdk>borc": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "browserify>buffer": true, + "@ethereumjs/tx>@ethereumjs/common>crc-32": true, "eth-lattice-keyring>gridplus-sdk>elliptic": true, "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": true, - "eth-lattice-keyring>gridplus-sdk>uuid": true, - "eth-lattice-keyring>rlp": true, - "ethereumjs-util>ethereum-cryptography>bs58check": true, "ethers>@ethersproject/sha2>hash.js": true, + "eth-ens-namehash>js-sha3": true, + "lodash": true, + "eth-lattice-keyring>rlp": true, "ganache>secp256k1": true, - "lodash": true + "eth-lattice-keyring>gridplus-sdk>uuid": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/common": { + "string.prototype.matchall>es-abstract>has-property-descriptors": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "string.prototype.matchall>call-bind>es-define-property": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx": { + "koa>is-generator-function>has-tostringtag": { "packages": { - "@ethereumjs/tx>@ethereumjs/rlp": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethersproject/providers": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "eth-lattice-keyring>@ethereumjs/tx>@chainsafe/ssz": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": true, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": true + "string.prototype.matchall>has-symbols": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>@ethereumjs/common": { + "ethereumjs-util>create-hash>md5.js>hash-base": { "packages": { - "@ethereumjs/tx>@ethereumjs/common>crc-32": true, - "@ethereumjs/tx>@ethereumjs/util": true, - "browserify>buffer": true, - "webpack>events": true + "pumpify>inherits": true, + "readable-stream": true, + "koa>content-disposition>safe-buffer": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography": { + "ethers>@ethersproject/sha2>hash.js": { + "packages": { + "pumpify>inherits": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true + } + }, + "depcheck>is-core-module>hasown": { + "packages": { + "browserify>has>function-bind": true + } + }, + "@metamask/eth-trezor-keyring>hdkey": { + "packages": { + "browserify>assert": true, + "ethereumjs-util>ethereum-cryptography>bs58check": true, + "crypto-browserify": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "ganache>secp256k1": true + } + }, + "he": { "globals": { - "TextDecoder": true, - "crypto": true + "define": true + } + }, + "history": { + "globals": { + "console": true, + "define": true, + "document.defaultView": true, + "document.querySelector": true + } + }, + "react-router-dom>history": { + "globals": { + "addEventListener": true, + "confirm": true, + "document": true, + "history": true, + "location": true, + "navigator.userAgent": true, + "removeEventListener": true }, "packages": { - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true + "react-router-dom>history>resolve-pathname": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true, + "react-router-dom>history>value-equal": true } }, - "eth-lattice-keyring>gridplus-sdk>@ethereumjs/tx>ethereum-cryptography>@noble/hashes": { + "@metamask/ppom-validator>elliptic>hmac-drbg": { + "packages": { + "ethers>@ethersproject/sha2>hash.js": true, + "@metamask/ppom-validator>elliptic>minimalistic-assert": true, + "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true + } + }, + "react-redux>hoist-non-react-statics": { + "packages": { + "prop-types>react-is": true + } + }, + "https-browserify": { + "packages": { + "stream-http": true, + "browserify>url": true + } + }, + "@metamask/notification-services-controller>firebase>@firebase/app>idb": { "globals": { - "TextEncoder": true, - "crypto": true + "DOMException": true, + "IDBCursor": true, + "IDBDatabase": true, + "IDBIndex": true, + "IDBObjectStore": true, + "IDBRequest": true, + "IDBTransaction": true, + "indexedDB.deleteDatabase": true, + "indexedDB.open": true } }, - "eth-lattice-keyring>gridplus-sdk>aes-js": { + "eth-ens-namehash>idna-uts46-hx": { "globals": { "define": true + }, + "packages": { + "browserify>punycode": true + } + }, + "string.prototype.matchall>internal-slot": { + "packages": { + "string.prototype.matchall>call-bind>es-errors": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>side-channel": true + } + }, + "browserify>util>is-arguments": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true + } + }, + "string.prototype.matchall>es-abstract>is-array-buffer": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": { + "packages": { + "string.prototype.matchall>es-abstract>unbox-primitive>has-bigints": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": { + "packages": { + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>bignumber.js": { + "string.prototype.matchall>es-abstract>is-callable": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>bitwise": { + "@metamask/eth-token-tracker>deep-equal>is-date-object": { "packages": { - "browserify>buffer": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc": { - "globals": { - "console": true - }, + "koa>is-generator-function": { "packages": { - "browserify>buffer": true, - "buffer>ieee754": true, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": true, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": true + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>bignumber.js": { + "@material-ui/core>@material-ui/styles>jss>is-in-browser": { "globals": { - "crypto": true, - "define": true + "document": true } }, - "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { - "globals": { - "URL": true, - "URLSearchParams": true, - "location": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>elliptic": { + "string.prototype.matchall>es-abstract>is-regex": { "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>gridplus-sdk>eth-eip712-util-browser": { - "globals": { - "intToBuffer": true - }, + "string.prototype.matchall>es-abstract>is-shared-array-buffer": { "packages": { - "@metamask/ethjs>js-sha3": true, - "bn.js": true, - "buffer": true + "string.prototype.matchall>call-bind": true } }, - "eth-lattice-keyring>gridplus-sdk>uuid": { - "globals": { - "crypto": true + "eslint-plugin-react>array-includes>is-string": { + "packages": { + "koa>is-generator-function>has-tostringtag": true } }, - "eth-lattice-keyring>rlp": { - "globals": { - "TextEncoder": true + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "packages": { + "string.prototype.matchall>has-symbols": true } }, - "eth-method-registry": { + "browserify>util>is-typed-array": { "packages": { - "@metamask/ethjs-contract": true, - "@metamask/ethjs-query": true + "browserify>util>which-typed-array": true } }, - "ethereumjs-util": { + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": { "packages": { - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "browserify>insert-module-globals>is-buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography": true, - "ethereumjs-util>rlp": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true } }, - "ethereumjs-util>create-hash": { + "eth-lattice-keyring>gridplus-sdk>borc>iso-url": { + "globals": { + "URL": true, + "URLSearchParams": true, + "location": true + } + }, + "@ensdomains/content-hash>js-base64": { + "globals": { + "Base64": "write", + "TextDecoder": true, + "TextEncoder": true, + "atob": true, + "btoa": true, + "define": true + }, "packages": { - "addons-linter>sha.js": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>create-hash>md5.js": true, - "ethereumjs-util>create-hash>ripemd160": true, - "pumpify>inherits": true + "browserify>buffer": true } }, - "ethereumjs-util>create-hash>cipher-base": { + "eth-ens-namehash>js-sha3": { + "globals": { + "define": true + }, "packages": { - "browserify>string_decoder": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "stream-browserify": true + "process": true } }, - "ethereumjs-util>create-hash>md5.js": { + "@ngraveio/bc-ur>jsbi": { + "globals": { + "define": true + } + }, + "@metamask/message-manager>jsonschema": { "packages": { - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "browserify>url": true } }, - "ethereumjs-util>create-hash>md5.js>hash-base": { + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case": { "packages": { - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true, - "readable-stream": true + "@material-ui/core>@material-ui/styles>jss-plugin-camel-case>hyphenate-style-name": true } }, - "ethereumjs-util>create-hash>ripemd160": { + "@material-ui/core>@material-ui/styles>jss-plugin-default-unit": { + "globals": { + "CSS": true + }, "packages": { - "browserify>buffer": true, - "ethereumjs-util>create-hash>md5.js>hash-base": true, - "pumpify>inherits": true + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography": { + "@material-ui/core>@material-ui/styles>jss-plugin-global": { "packages": { - "browserify>buffer": true, - "crypto-browserify>randombytes": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ganache>secp256k1": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes": { + "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { - "browserify>buffer": true, - "crypto-browserify>browserify-cipher>evp_bytestokey": true, - "ethereumjs-util>create-hash>cipher-base": true, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": true, - "koa>content-disposition>safe-buffer": true, - "pumpify>inherits": true + "@babel/runtime": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>browserify-aes>buffer-xor": { + "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { - "browserify>buffer": true + "@material-ui/core>@material-ui/styles>jss": true, + "react-router-dom>tiny-warning": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check": { + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { "packages": { - "ethereumjs-util>create-hash": true, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": true, - "koa>content-disposition>safe-buffer": true + "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": true, + "@material-ui/core>@material-ui/styles>jss": true } }, - "ethereumjs-util>ethereum-cryptography>bs58check>bs58": { + "@material-ui/core>@material-ui/styles>jss": { + "globals": { + "CSS": true, + "document.createElement": true, + "document.querySelector": true + }, "packages": { - "@ensdomains/content-hash>multihashes>multibase>base-x": true + "@babel/runtime": true, + "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, + "react-router-dom>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4196,536 +4439,496 @@ "readable-stream": true } }, - "ethereumjs-util>rlp": { - "packages": { - "bn.js": true, - "browserify>buffer": true + "currency-formatter>locale-currency": { + "globals": { + "countryCode": true } }, - "ethereumjs-wallet>randombytes": { + "localforage": { "globals": { - "crypto.getRandomValues": true + "Blob": true, + "BlobBuilder": true, + "FileReader": true, + "IDBKeyRange": true, + "MSBlobBuilder": true, + "MozBlobBuilder": true, + "OIndexedDB": true, + "WebKitBlobBuilder": true, + "atob": true, + "btoa": true, + "console.error": true, + "console.info": true, + "console.warn": true, + "define": true, + "fetch": true, + "indexedDB": true, + "localStorage": true, + "mozIndexedDB": true, + "msIndexedDB": true, + "navigator.platform": true, + "navigator.userAgent": true, + "openDatabase": true, + "setTimeout": true, + "webkitIndexedDB": true } }, - "ethers": { - "packages": { - "@ethersproject/abi": true, - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/contracts": true, - "@ethersproject/hash": true, - "@ethersproject/hdnode": true, - "@ethersproject/wallet": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/json-wallets": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/signing-key": true, - "ethers>@ethersproject/solidity": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true, - "ethers>@ethersproject/units": true, - "ethers>@ethersproject/web": true, - "ethers>@ethersproject/wordlists": true + "lodash": { + "globals": { + "clearTimeout": true, + "define": true, + "setTimeout": true } }, - "ethers>@ethersproject/abstract-provider": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "loglevel": { + "globals": { + "console": true, + "define": true, + "document.cookie": true, + "localStorage": true, + "log": "write", + "navigator": true } }, - "ethers>@ethersproject/abstract-signer": { - "packages": { - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true + "lottie-web": { + "globals": { + "Blob": true, + "Howl": true, + "OffscreenCanvas": true, + "URL.createObjectURL": true, + "Worker": true, + "XMLHttpRequest": true, + "bodymovin": "write", + "clearInterval": true, + "console": true, + "define": true, + "document.body": true, + "document.createElement": true, + "document.createElementNS": true, + "document.getElementsByClassName": true, + "document.getElementsByTagName": true, + "document.querySelectorAll": true, + "document.readyState": true, + "location.origin": true, + "location.pathname": true, + "navigator": true, + "requestAnimationFrame": true, + "setInterval": true, + "setTimeout": true } }, - "ethers>@ethersproject/address": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/rlp": true + "luxon": { + "globals": { + "Intl": true } }, - "ethers>@ethersproject/base64": { + "@metamask/snaps-utils>marked": { "globals": { - "atob": true, - "btoa": true - }, - "packages": { - "@ethersproject/bytes": true + "console.error": true, + "console.warn": true, + "define": true } }, - "ethers>@ethersproject/basex": { + "ethereumjs-util>create-hash>md5.js": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/properties": true + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "ethers>@ethersproject/constants": { + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": { "packages": { - "@ethersproject/bignumber": true + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/json-wallets": { + "react-markdown>remark-parse>mdast-util-from-markdown": { "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hdnode": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/json-wallets>aes-js": true, - "ethers>@ethersproject/json-wallets>scrypt-js": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/pbkdf2": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true - } - }, - "ethers>@ethersproject/json-wallets>aes-js": { - "globals": { - "define": true + "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true } }, - "ethers>@ethersproject/json-wallets>scrypt-js": { + "react-markdown>remark-rehype>mdast-util-to-hast": { "globals": { - "define": true, - "setTimeout": true + "console.warn": true }, "packages": { - "browserify>timers-browserify": true - } - }, - "ethers>@ethersproject/keccak256": { - "packages": { - "@ethersproject/bytes": true, - "@metamask/ethjs>js-sha3": true + "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, + "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, + "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, + "react-markdown>unist-util-visit": true } }, - "ethers>@ethersproject/logger": { + "@ethereumjs/tx>@ethereumjs/util>micro-ftch": { "globals": { - "console": true + "Headers": true, + "TextDecoder": true, + "URL": true, + "btoa": true, + "fetch": true + }, + "packages": { + "browserify>browserify-zlib": true, + "browserify>buffer": true, + "https-browserify": true, + "process": true, + "stream-http": true, + "browserify>url": true, + "browserify>util": true } }, - "ethers>@ethersproject/pbkdf2": { + "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/sha2": true + "react-syntax-highlighter>refractor>parse-entities": true } }, - "ethers>@ethersproject/properties": { + "crypto-browserify>diffie-hellman>miller-rabin": { "packages": { - "ethers>@ethersproject/logger": true + "bn.js": true, + "@metamask/ppom-validator>elliptic>brorand": true } }, - "ethers>@ethersproject/providers": { + "@ensdomains/content-hash>cids>multibase": { "globals": { - "WebSocket": true, - "clearInterval": true, - "clearTimeout": true, - "console.log": true, - "console.warn": true, - "setInterval": true, - "setTimeout": true + "TextDecoder": true, + "TextEncoder": true }, "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/abstract-provider": true, - "ethers>@ethersproject/abstract-signer": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/basex": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/providers>@ethersproject/networks": true, - "ethers>@ethersproject/providers>@ethersproject/web": true, - "ethers>@ethersproject/providers>bech32": true, - "ethers>@ethersproject/random": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true, - "ethers>@ethersproject/transactions": true + "@ensdomains/content-hash>cids>multibase>@multiformats/base-x": true } }, - "ethers>@ethersproject/providers>@ethersproject/networks": { + "@ensdomains/content-hash>multihashes>multibase": { "packages": { - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multihashes>multibase>base-x": true, + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/providers>@ethersproject/web": { - "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, + "@ensdomains/content-hash>multicodec": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@ensdomains/content-hash>multicodec>uint8arrays": true, + "sass-embedded>varint": true } }, - "ethers>@ethersproject/random": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "console.warn": true, + "crypto.subtle.digest": true } }, - "ethers>@ethersproject/rlp": { + "@ensdomains/content-hash>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true + "browserify>buffer": true, + "@ensdomains/content-hash>multihashes>multibase": true, + "@ensdomains/content-hash>multihashes>varint": true, + "@ensdomains/content-hash>multihashes>web-encoding": true } }, - "ethers>@ethersproject/sha2": { + "@ensdomains/content-hash>cids>multihashes": { "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2>hash.js": true + "@ensdomains/content-hash>cids>multibase": true, + "@ensdomains/content-hash>cids>uint8arrays": true, + "@ensdomains/content-hash>cids>multihashes>varint": true } }, - "ethers>@ethersproject/sha2>hash.js": { - "packages": { - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "pumpify>inherits": true + "nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/signing-key>elliptic": true + "@metamask/approval-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/signing-key>elliptic": { - "packages": { - "@metamask/ppom-validator>elliptic>brorand": true, - "@metamask/ppom-validator>elliptic>hmac-drbg": true, - "@metamask/ppom-validator>elliptic>minimalistic-assert": true, - "@metamask/ppom-validator>elliptic>minimalistic-crypto-utils": true, - "bn.js": true, - "ethers>@ethersproject/sha2>hash.js": true, - "pumpify>inherits": true + "@metamask/smart-transactions-controller>@metamask/controllers>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/solidity": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/sha2": true, - "ethers>@ethersproject/strings": true + "@metamask/notification-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/strings": { - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/logger": true + "@metamask/permission-controller>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/transactions": { - "packages": { - "@ethersproject/bignumber": true, - "@ethersproject/bytes": true, - "ethers>@ethersproject/address": true, - "ethers>@ethersproject/constants": true, - "ethers>@ethersproject/keccak256": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/rlp": true, - "ethers>@ethersproject/signing-key": true + "@metamask/rpc-methods>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/units": { - "packages": { - "@ethersproject/bignumber": true, - "ethers>@ethersproject/logger": true + "@metamask/rpc-methods-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/web": { + "@metamask/snaps-controllers>nanoid": { "globals": { - "clearTimeout": true, - "fetch": true, - "setTimeout": true - }, - "packages": { - "@ethersproject/bytes": true, - "ethers>@ethersproject/base64": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "crypto.getRandomValues": true } }, - "ethers>@ethersproject/wordlists": { - "packages": { - "@ethersproject/bytes": true, - "@ethersproject/hash": true, - "ethers>@ethersproject/logger": true, - "ethers>@ethersproject/properties": true, - "ethers>@ethersproject/strings": true + "@metamask/snaps-controllers-flask>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream": { - "packages": { - "browserify>buffer": true, - "extension-port-stream>readable-stream": true + "depcheck>@vue/compiler-sfc>postcss>nanoid": { + "globals": { + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream": { + "dependency-tree>precinct>detective-postcss>postcss>nanoid": { "globals": { - "AbortController": true, - "AggregateError": true, - "Blob": true - }, - "packages": { - "browserify>buffer": true, - "browserify>string_decoder": true, - "extension-port-stream>readable-stream>abort-controller": true, - "process": true, - "webpack>events": true + "crypto.getRandomValues": true } }, - "extension-port-stream>readable-stream>abort-controller": { + "node-fetch": { "globals": { - "AbortController": true + "Headers": true, + "Request": true, + "Response": true, + "fetch": true } }, - "fast-json-patch": { + "@metamask/controllers>web3-provider-engine>cross-fetch>node-fetch": { "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true + "fetch": true } }, - "fuse.js": { + "@metamask/controllers>web3-provider-engine>eth-json-rpc-middleware>node-fetch": { "globals": { - "console": true, - "define": true + "fetch": true } }, - "ganache>secp256k1": { + "eth-method-registry>@metamask/ethjs-contract>ethjs-abi>number-to-bn": { "packages": { - "@metamask/ppom-validator>elliptic": true + "bn.js": true, + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": true + } + }, + "string.prototype.matchall>es-abstract>object-inspect": { + "globals": { + "HTMLElement": true, + "WeakRef": true + }, + "packages": { + "browserify>browser-resolve": true + } + }, + "@ngraveio/bc-ur>assert>object-is": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true } }, "gulp>vinyl-fs>object.assign": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, "string.prototype.matchall>call-bind": true, "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>has-symbols": true + "string.prototype.matchall>has-symbols": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "he": { - "globals": { - "define": true + "@metamask/object-multiplex>once": { + "packages": { + "@metamask/object-multiplex>once>wrappy": true } }, - "history": { + "crypto-browserify>public-encrypt>parse-asn1": { + "packages": { + "crypto-browserify>public-encrypt>parse-asn1>asn1.js": true, + "ethereumjs-util>ethereum-cryptography>browserify-aes": true, + "browserify>buffer": true, + "crypto-browserify>browserify-cipher>evp_bytestokey": true, + "crypto-browserify>pbkdf2": true + } + }, + "react-syntax-highlighter>refractor>parse-entities": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true + "document.createElement": true } }, - "https-browserify": { + "path-browserify": { "packages": { - "browserify>url": true, - "stream-http": true + "process": true } }, - "koa>content-disposition>safe-buffer": { + "serve-handler>path-to-regexp": { "packages": { - "browserify>buffer": true + "serve-handler>path-to-regexp>isarray": true } }, - "koa>is-generator-function": { + "crypto-browserify>pbkdf2": { + "globals": { + "crypto": true, + "process": true, + "queueMicrotask": true, + "setImmediate": true, + "setTimeout": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true + "ethereumjs-util>create-hash": true, + "process": true, + "ethereumjs-util>create-hash>ripemd160": true, + "koa>content-disposition>safe-buffer": true, + "addons-linter>sha.js": true } }, - "koa>is-generator-function>has-tostringtag": { - "packages": { - "string.prototype.matchall>has-symbols": true + "@material-ui/core>popper.js": { + "globals": { + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, + "console.warn": true, + "define": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator": true, + "requestAnimationFrame": true, + "setTimeout": true } }, - "localforage": { + "react-tippy>popper.js": { "globals": { - "Blob": true, - "BlobBuilder": true, - "FileReader": true, - "IDBKeyRange": true, - "MSBlobBuilder": true, - "MozBlobBuilder": true, - "OIndexedDB": true, - "WebKitBlobBuilder": true, - "atob": true, - "btoa": true, - "console.error": true, - "console.info": true, + "MSInputMethodContext": true, + "Node.DOCUMENT_POSITION_FOLLOWING": true, + "cancelAnimationFrame": true, "console.warn": true, "define": true, - "fetch": true, - "indexedDB": true, - "localStorage": true, - "mozIndexedDB": true, - "msIndexedDB": true, - "navigator.platform": true, + "devicePixelRatio": true, + "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, "navigator.userAgent": true, - "openDatabase": true, - "setTimeout": true, - "webkitIndexedDB": true + "requestAnimationFrame": true, + "setTimeout": true } }, - "lodash": { + "process": { "globals": { "clearTimeout": true, - "define": true, "setTimeout": true } }, - "loglevel": { + "promise-to-callback": { + "packages": { + "promise-to-callback>is-fn": true, + "promise-to-callback>set-immediate-shim": true + } + }, + "prop-types": { "globals": { - "console": true, - "define": true, - "document.cookie": true, - "localStorage": true, - "log": "write", - "navigator": true + "console": true + }, + "packages": { + "react>object-assign": true, + "prop-types>react-is": true } }, - "lottie-web": { + "react-markdown>property-information": { + "packages": { + "watchify>xtend": true + } + }, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": { "globals": { - "Blob": true, - "Howl": true, - "OffscreenCanvas": true, - "URL.createObjectURL": true, - "Worker": true, - "XMLHttpRequest": true, - "bodymovin": "write", - "clearInterval": true, - "console": true, - "define": true, - "document.body": true, - "document.createElement": true, - "document.createElementNS": true, - "document.getElementsByClassName": true, - "document.getElementsByTagName": true, - "document.querySelectorAll": true, - "document.readyState": true, - "location.origin": true, - "location.pathname": true, - "navigator": true, - "requestAnimationFrame": true, - "setInterval": true, + "process": true, "setTimeout": true + }, + "packages": { + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true, + "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true } }, - "luxon": { + "crypto-browserify>public-encrypt": { + "packages": { + "bn.js": true, + "crypto-browserify>public-encrypt>browserify-rsa": true, + "browserify>buffer": true, + "ethereumjs-util>create-hash": true, + "crypto-browserify>public-encrypt>parse-asn1": true, + "crypto-browserify>randombytes": true + } + }, + "browserify>punycode": { "globals": { - "Intl": true + "define": true } }, - "nanoid": { + "qrcode-generator": { "globals": { - "crypto.getRandomValues": true + "define": true } }, - "nock>debug": { + "qrcode.react": { "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "Path2D": true, + "devicePixelRatio": true }, "packages": { - "nock>debug>ms": true, - "process": true - } - }, - "node-fetch": { - "globals": { - "Headers": true, - "Request": true, - "Response": true, - "fetch": true + "react": true } }, - "path-browserify": { + "@storybook/addon-knobs>qs": { "packages": { - "process": true + "string.prototype.matchall>side-channel": true } }, - "process": { + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": { "globals": { - "clearTimeout": true, - "setTimeout": true - } - }, - "promise-to-callback": { - "packages": { - "promise-to-callback>is-fn": true, - "promise-to-callback>set-immediate-shim": true + "queueMicrotask": true } }, - "promise-to-callback>set-immediate-shim": { + "react-beautiful-dnd>raf-schd": { "globals": { - "setTimeout.apply": true - }, - "packages": { - "browserify>timers-browserify": true + "cancelAnimationFrame": true, + "requestAnimationFrame": true } }, - "prop-types": { + "crypto-browserify>randombytes": { "globals": { - "console": true + "crypto": true, + "msCrypto": true }, "packages": { - "prop-types>react-is": true, - "react>object-assign": true - } - }, - "prop-types>react-is": { - "globals": { - "console": true + "process": true, + "koa>content-disposition>safe-buffer": true } }, - "qrcode-generator": { + "ethereumjs-wallet>randombytes": { "globals": { - "define": true + "crypto.getRandomValues": true } }, - "qrcode.react": { + "crypto-browserify>randomfill": { "globals": { - "Path2D": true, - "devicePixelRatio": true + "crypto": true, + "msCrypto": true }, "packages": { - "react": true + "process": true, + "crypto-browserify>randombytes": true, + "koa>content-disposition>safe-buffer": true } }, "react": { @@ -4733,8 +4936,8 @@ "console": true }, "packages": { - "prop-types": true, - "react>object-assign": true + "react>object-assign": true, + "prop-types": true } }, "react-beautiful-dnd": { @@ -4756,43 +4959,28 @@ }, "packages": { "@babel/runtime": true, - "react": true, "react-beautiful-dnd>css-box-model": true, "react-beautiful-dnd>memoize-one": true, "react-beautiful-dnd>raf-schd": true, - "react-beautiful-dnd>use-memo-one": true, + "react": true, "react-dom": true, "react-redux": true, - "redux": true + "redux": true, + "react-beautiful-dnd>use-memo-one": true } }, - "react-beautiful-dnd>css-box-model": { + "react-chartjs-2": { "globals": { - "getComputedStyle": true, - "pageXOffset": true, - "pageYOffset": true + "setTimeout": true }, "packages": { - "react-router-dom>tiny-invariant": true - } - }, - "react-beautiful-dnd>raf-schd": { - "globals": { - "cancelAnimationFrame": true, - "requestAnimationFrame": true - } - }, - "react-beautiful-dnd>use-memo-one": { - "packages": { + "chart.js": true, "react": true } }, - "react-chartjs-2": { - "globals": { - "setTimeout": true - }, + "react-focus-lock>react-clientside-effect": { "packages": { - "chart.js": true, + "@babel/runtime": true, "react": true } }, @@ -4837,22 +5025,28 @@ "trustedTypes": true }, "packages": { + "react>object-assign": true, "prop-types": true, "react": true, - "react-dom>scheduler": true, - "react>object-assign": true + "react-dom>scheduler": true } }, - "react-dom>scheduler": { + "react-responsive-carousel>react-easy-swipe": { "globals": { - "MessageChannel": true, - "cancelAnimationFrame": true, - "clearTimeout": true, - "console": true, - "navigator": true, - "performance": true, - "requestAnimationFrame": true, - "setTimeout": true + "addEventListener": true, + "define": true, + "document.addEventListener": true, + "document.removeEventListener": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-popper>react-fast-compare": { + "globals": { + "Element": true, + "console.warn": true } }, "react-focus-lock": { @@ -4866,667 +5060,726 @@ }, "packages": { "@babel/runtime": true, + "react-focus-lock>focus-lock": true, "prop-types": true, "react": true, - "react-focus-lock>focus-lock": true, "react-focus-lock>react-clientside-effect": true, "react-focus-lock>use-callback-ref": true, "react-focus-lock>use-sidecar": true } }, - "react-focus-lock>focus-lock": { + "react-idle-timer": { "globals": { - "HTMLIFrameElement": true, - "Node.DOCUMENT_FRAGMENT_NODE": true, - "Node.DOCUMENT_NODE": true, - "Node.DOCUMENT_POSITION_CONTAINED_BY": true, - "Node.DOCUMENT_POSITION_CONTAINS": true, - "Node.ELEMENT_NODE": true, - "console.error": true, + "clearTimeout": true, + "document": true, + "setTimeout": true + }, + "packages": { + "prop-types": true, + "react": true + } + }, + "react-inspector": { + "globals": { + "Node": true, + "chromeDark": true, + "chromeLight": true + }, + "packages": { + "react": true + } + }, + "prop-types>react-is": { + "globals": { + "console": true + } + }, + "react-markdown>react-is": { + "globals": { + "console": true + } + }, + "react-redux>react-is": { + "globals": { + "console": true + } + }, + "react-markdown": { + "globals": { + "console.warn": true + }, + "packages": { + "react-markdown>comma-separated-tokens": true, + "prop-types": true, + "react-markdown>property-information": true, + "react": true, + "react-markdown>react-is": true, + "react-markdown>remark-parse": true, + "react-markdown>remark-rehype": true, + "react-markdown>space-separated-tokens": true, + "react-markdown>style-to-object": true, + "react-markdown>unified": true, + "react-markdown>unist-util-visit": true, + "react-markdown>vfile": true + } + }, + "react-popper": { + "globals": { + "document": true + }, + "packages": { + "@popperjs/core": true, + "react": true, + "react-popper>react-fast-compare": true, + "react-popper>warning": true + } + }, + "react-redux": { + "globals": { + "console": true, + "document": true + }, + "packages": { + "@babel/runtime": true, + "react-redux>hoist-non-react-statics": true, + "prop-types": true, + "react": true, + "react-dom": true, + "react-redux>react-is": true + } + }, + "react-responsive-carousel": { + "globals": { + "HTMLElement": true, + "addEventListener": true, + "clearTimeout": true, "console.warn": true, "document": true, - "getComputedStyle": true, + "getComputedStyle": true, + "removeEventListener": true, + "setTimeout": true + }, + "packages": { + "classnames": true, + "react": true, + "react-dom": true, + "react-responsive-carousel>react-easy-swipe": true + } + }, + "react-router-dom": { + "packages": { + "react-router-dom>history": true, + "prop-types": true, + "react": true, + "react-router-dom>react-router": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true + } + }, + "react-router-dom-v5-compat": { + "globals": { + "FormData": true, + "URL": true, + "URLSearchParams": true, + "__reactRouterVersion": "write", + "addEventListener": true, + "confirm": true, + "define": true, + "document": true, + "history.scrollRestoration": true, + "location.href": true, + "removeEventListener": true, + "scrollTo": true, + "scrollY": true, + "sessionStorage.getItem": true, + "sessionStorage.setItem": true, "setTimeout": true }, "packages": { - "@swc/helpers>tslib": true + "react-router-dom-v5-compat>@remix-run/router": true, + "history": true, + "react": true, + "react-dom": true, + "react-router-dom": true, + "react-router-dom-v5-compat>react-router": true } }, - "react-focus-lock>react-clientside-effect": { + "react-router-dom>react-router": { "packages": { - "@babel/runtime": true, - "react": true + "react-router-dom>history": true, + "react-redux>hoist-non-react-statics": true, + "serve-handler>path-to-regexp": true, + "prop-types": true, + "react": true, + "prop-types>react-is": true, + "react-router-dom>tiny-invariant": true, + "react-router-dom>tiny-warning": true } }, - "react-focus-lock>use-callback-ref": { + "react-router-dom-v5-compat>react-router": { + "globals": { + "console.error": true, + "define": true + }, "packages": { + "react-router-dom-v5-compat>@remix-run/router": true, "react": true } }, - "react-focus-lock>use-sidecar": { + "react-simple-file-input": { "globals": { - "console.error": true + "File": true, + "FileReader": true, + "console.warn": true }, "packages": { - "@swc/helpers>tslib": true, - "react": true, - "react-focus-lock>use-sidecar>detect-node-es": true + "prop-types": true, + "react": true } }, - "react-idle-timer": { + "react-tippy": { "globals": { + "Element": true, + "MSStream": true, + "MutationObserver": true, + "addEventListener": true, "clearTimeout": true, + "console.error": true, + "console.warn": true, + "define": true, "document": true, + "getComputedStyle": true, + "innerHeight": true, + "innerWidth": true, + "navigator.maxTouchPoints": true, + "navigator.msMaxTouchPoints": true, + "navigator.userAgent": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "react-tippy>popper.js": true, + "react": true, + "react-dom": true } }, - "react-inspector": { + "react-toggle-button": { "globals": { - "Node": true, - "chromeDark": true, - "chromeLight": true + "clearTimeout": true, + "console.warn": true, + "define": true, + "performance": true, + "setTimeout": true }, "packages": { "react": true } }, - "react-markdown": { + "@material-ui/core>react-transition-group": { "globals": { - "console.warn": true + "Element": true, + "setTimeout": true }, "packages": { + "@material-ui/core>react-transition-group>dom-helpers": true, "prop-types": true, "react": true, - "react-markdown>comma-separated-tokens": true, - "react-markdown>property-information": true, - "react-markdown>react-is": true, - "react-markdown>remark-parse": true, - "react-markdown>remark-rehype": true, - "react-markdown>space-separated-tokens": true, - "react-markdown>style-to-object": true, - "react-markdown>unified": true, - "react-markdown>unist-util-visit": true, - "react-markdown>vfile": true + "react-dom": true } }, - "react-markdown>property-information": { + "readable-stream": { "packages": { - "watchify>xtend": true + "browserify>browser-resolve": true, + "browserify>buffer": true, + "webpack>events": true, + "pumpify>inherits": true, + "process": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true } }, - "react-markdown>react-is": { + "extension-port-stream>readable-stream": { "globals": { - "console": true - } - }, - "react-markdown>remark-parse": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown": { - "packages": { - "react-markdown>remark-parse>mdast-util-from-markdown>mdast-util-to-string": true, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": true, - "react-markdown>remark-parse>mdast-util-from-markdown>unist-util-stringify-position": true, - "react-syntax-highlighter>refractor>parse-entities": true - } - }, - "react-markdown>remark-parse>mdast-util-from-markdown>micromark": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "queueMicrotask": true + }, "packages": { - "react-syntax-highlighter>refractor>parse-entities": true + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "browserify>buffer": true, + "webpack>events": true, + "process": true, + "browserify>string_decoder": true } }, - "react-markdown>remark-rehype": { + "@metamask/snaps-controllers>readable-web-to-node-stream": { "packages": { - "react-markdown>remark-rehype>mdast-util-to-hast": true + "readable-stream": true } }, - "react-markdown>remark-rehype>mdast-util-to-hast": { + "redux": { "globals": { - "console.warn": true + "console": true }, "packages": { - "@storybook/addon-docs>remark-external-links>mdast-util-definitions": true, - "react-markdown>remark-rehype>mdast-util-to-hast>mdurl": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-builder": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-generated": true, - "react-markdown>remark-rehype>mdast-util-to-hast>unist-util-position": true, - "react-markdown>unist-util-visit": true + "@babel/runtime": true } }, - "react-markdown>style-to-object": { + "string.prototype.matchall>regexp.prototype.flags": { "packages": { - "react-markdown>style-to-object>inline-style-parser": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": true } }, - "react-markdown>unified": { + "react-markdown>remark-parse": { "packages": { - "mocha>yargs-unparser>is-plain-obj": true, - "react-markdown>unified>bail": true, - "react-markdown>unified>extend": true, - "react-markdown>unified>is-buffer": true, - "react-markdown>unified>trough": true, - "react-markdown>vfile": true + "react-markdown>remark-parse>mdast-util-from-markdown": true } }, - "react-markdown>unist-util-visit": { + "react-markdown>remark-rehype": { "packages": { - "react-markdown>unist-util-visit>unist-util-visit-parents": true + "react-markdown>remark-rehype>mdast-util-to-hast": true } }, - "react-markdown>unist-util-visit>unist-util-visit-parents": { + "react-markdown>vfile>replace-ext": { "packages": { - "react-markdown>unist-util-visit>unist-util-is": true + "path-browserify": true } }, - "react-markdown>vfile": { - "packages": { - "path-browserify": true, - "process": true, - "react-markdown>vfile>is-buffer": true, - "react-markdown>vfile>replace-ext": true, - "react-markdown>vfile>vfile-message": true + "reselect": { + "globals": { + "WeakRef": true, + "console.warn": true, + "unstable_autotrackMemoize": true } }, - "react-markdown>vfile>replace-ext": { + "@metamask/snaps-utils>rfdc": { "packages": { - "path-browserify": true + "browserify>buffer": true } }, - "react-markdown>vfile>vfile-message": { + "ethereumjs-util>create-hash>ripemd160": { "packages": { - "react-markdown>vfile>unist-util-stringify-position": true + "browserify>buffer": true, + "ethereumjs-util>create-hash>md5.js>hash-base": true, + "pumpify>inherits": true } }, - "react-popper": { - "globals": { - "document": true - }, + "@keystonehq/metamask-airgapped-keyring>rlp": { "packages": { - "@popperjs/core": true, - "react": true, - "react-popper>react-fast-compare": true, - "react-popper>warning": true - } - }, - "react-popper>react-fast-compare": { - "globals": { - "Element": true, - "console.warn": true + "bn.js": true, + "browserify>buffer": true } }, - "react-popper>warning": { + "eth-lattice-keyring>rlp": { "globals": { - "console": true + "TextEncoder": true } }, - "react-redux": { - "globals": { - "console": true, - "document": true - }, + "ethereumjs-util>rlp": { "packages": { - "@babel/runtime": true, - "prop-types": true, - "react": true, - "react-dom": true, - "react-redux>hoist-non-react-statics": true, - "react-redux>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>hoist-non-react-statics": { + "@metamask/keyring-controller>ethereumjs-wallet>ethereumjs-util>rlp": { "packages": { - "prop-types>react-is": true + "bn.js": true, + "browserify>buffer": true } }, - "react-redux>react-is": { + "wait-on>rxjs": { "globals": { - "console": true + "cancelAnimationFrame": true, + "clearInterval": true, + "clearTimeout": true, + "performance": true, + "requestAnimationFrame": true, + "setInterval.apply": true, + "setTimeout.apply": true } }, - "react-responsive-carousel": { + "koa>content-disposition>safe-buffer": { + "packages": { + "browserify>buffer": true + } + }, + "react-dom>scheduler": { "globals": { - "HTMLElement": true, - "addEventListener": true, + "MessageChannel": true, + "cancelAnimationFrame": true, "clearTimeout": true, - "console.warn": true, - "document": true, - "getComputedStyle": true, - "removeEventListener": true, + "console": true, + "navigator": true, + "performance": true, + "requestAnimationFrame": true, "setTimeout": true - }, - "packages": { - "classnames": true, - "react": true, - "react-dom": true, - "react-responsive-carousel>react-easy-swipe": true } }, - "react-responsive-carousel>react-easy-swipe": { + "ethers>@ethersproject/json-wallets>scrypt-js": { "globals": { - "addEventListener": true, "define": true, - "document.addEventListener": true, - "document.removeEventListener": true + "setTimeout": true }, "packages": { - "prop-types": true, - "react": true + "browserify>timers-browserify": true } }, - "react-router-dom": { + "ganache>secp256k1": { "packages": { - "prop-types": true, - "react": true, - "react-router-dom>history": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "@metamask/ppom-validator>elliptic": true } }, - "react-router-dom-v5-compat": { + "semver": { "globals": { - "FormData": true, - "URL": true, - "URLSearchParams": true, - "__reactRouterVersion": "write", - "addEventListener": true, - "confirm": true, - "define": true, - "document": true, - "history.scrollRestoration": true, - "location.href": true, - "removeEventListener": true, - "scrollTo": true, - "scrollY": true, - "sessionStorage.getItem": true, - "sessionStorage.setItem": true, - "setTimeout": true + "console.error": true }, "packages": { - "history": true, - "react": true, - "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>@remix-run/router": true, - "react-router-dom-v5-compat>react-router": true + "process": true } }, - "react-router-dom-v5-compat>@remix-run/router": { - "globals": { - "AbortController": true, - "DOMException": true, - "FormData": true, - "Headers": true, - "Request": true, - "Response": true, - "URL": true, - "URLSearchParams": true, - "console": true, - "document.defaultView": true + "string.prototype.matchall>call-bind>set-function-length": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom-v5-compat>react-router": { - "globals": { - "console.error": true, - "define": true - }, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": { "packages": { - "react": true, - "react-router-dom-v5-compat>@remix-run/router": true + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true } }, - "react-router-dom>history": { + "promise-to-callback>set-immediate-shim": { "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true + "setTimeout.apply": true }, "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>history>value-equal": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true + "browserify>timers-browserify": true } }, - "react-router-dom>react-router": { + "addons-linter>sha.js": { "packages": { - "prop-types": true, - "prop-types>react-is": true, - "react": true, - "react-redux>hoist-non-react-statics": true, - "react-router-dom>history": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "serve-handler>path-to-regexp": true + "pumpify>inherits": true, + "koa>content-disposition>safe-buffer": true } }, - "react-router-dom>tiny-warning": { - "globals": { - "console": true + "string.prototype.matchall>side-channel": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>object-inspect": true } }, - "react-simple-file-input": { + "@metamask/profile-sync-controller>siwe": { "globals": { - "File": true, - "FileReader": true, + "console.error": true, "console.warn": true }, "packages": { - "prop-types": true, - "react": true + "@metamask/profile-sync-controller>siwe>@spruceid/siwe-parser": true, + "@metamask/profile-sync-controller>siwe>@stablelib/random": true, + "ethers": true, + "@metamask/controller-utils>@spruceid/siwe-parser>valid-url": true } }, - "react-syntax-highlighter>refractor>parse-entities": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>stop-iteration-iterator": { "globals": { - "document.createElement": true + "StopIteration": true + }, + "packages": { + "string.prototype.matchall>internal-slot": true } }, - "react-tippy": { + "stream-browserify": { + "packages": { + "webpack>events": true, + "pumpify>inherits": true, + "readable-stream": true + } + }, + "stream-http": { "globals": { - "Element": true, - "MSStream": true, - "MutationObserver": true, - "addEventListener": true, + "AbortController": true, + "Blob": true, + "MSStreamReader": true, + "ReadableStream": true, + "WritableStream": true, + "XDomainRequest": true, + "XMLHttpRequest": true, "clearTimeout": true, - "console.error": true, - "console.warn": true, - "define": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.maxTouchPoints": true, - "navigator.msMaxTouchPoints": true, - "navigator.userAgent": true, - "performance": true, - "requestAnimationFrame": true, + "fetch": true, + "location.protocol.search": true, "setTimeout": true }, "packages": { - "react": true, - "react-dom": true, - "react-tippy>popper.js": true + "browserify>buffer": true, + "stream-http>builtin-status-codes": true, + "pumpify>inherits": true, + "process": true, + "readable-stream": true, + "browserify>url": true, + "watchify>xtend": true } }, - "react-tippy>popper.js": { - "globals": { - "MSInputMethodContext": true, - "Node.DOCUMENT_POSITION_FOLLOWING": true, - "cancelAnimationFrame": true, - "console.warn": true, - "define": true, - "devicePixelRatio": true, - "document": true, - "getComputedStyle": true, - "innerHeight": true, - "innerWidth": true, - "navigator.userAgent": true, - "requestAnimationFrame": true, - "setTimeout": true + "@metamask/snaps-controllers>tar-stream>streamx": { + "packages": { + "webpack>events": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx>queue-tick": true } }, - "react-toggle-button": { - "globals": { - "clearTimeout": true, - "console.warn": true, - "define": true, - "performance": true, - "setTimeout": true - }, + "browserify>string_decoder": { "packages": { - "react": true + "koa>content-disposition>safe-buffer": true } }, - "readable-stream": { + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>strip-hex-prefix": { "packages": { - "browserify>browser-resolve": true, - "browserify>buffer": true, - "browserify>string_decoder": true, - "process": true, - "pumpify>inherits": true, - "readable-stream>util-deprecate": true, - "webpack>events": true + "eth-method-registry>@metamask/ethjs-query>@metamask/ethjs-format>is-hex-prefixed": true } }, - "readable-stream>util-deprecate": { - "globals": { - "console.trace": true, - "console.warn": true, - "localStorage": true + "react-markdown>style-to-object": { + "packages": { + "react-markdown>style-to-object>inline-style-parser": true } }, - "redux": { - "globals": { - "console": true - }, + "@metamask/snaps-controllers>tar-stream": { "packages": { - "@babel/runtime": true + "@metamask/snaps-controllers>tar-stream>b4a": true, + "browserify>browser-resolve": true, + "@metamask/snaps-controllers>tar-stream>fast-fifo": true, + "@metamask/snaps-controllers>tar-stream>streamx": true } }, - "reselect": { - "globals": { - "WeakRef": true, - "console.warn": true, - "unstable_autotrackMemoize": true + "debounce-stream>through": { + "packages": { + "process": true, + "stream-browserify": true } }, - "semver": { + "browserify>timers-browserify": { "globals": { - "console.error": true + "clearInterval": true, + "clearTimeout": true, + "setInterval": true, + "setTimeout": true }, "packages": { "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true + "react-router-dom>tiny-warning": { + "globals": { + "console": true } }, - "stream-browserify": { - "packages": { - "pumpify>inherits": true, - "readable-stream": true, - "webpack>events": true + "copy-to-clipboard>toggle-selection": { + "globals": { + "document.activeElement": true, + "document.getSelection": true + } + }, + "tslib": { + "globals": { + "SuppressedError": true, + "define": true } }, - "stream-http": { + "@metamask/eth-sig-util>tweetnacl": { "globals": { - "AbortController": true, - "Blob": true, - "MSStreamReader": true, - "ReadableStream": true, - "WritableStream": true, - "XDomainRequest": true, - "XMLHttpRequest": true, - "clearTimeout": true, - "fetch": true, - "location.protocol.search": true, - "setTimeout": true + "crypto": true, + "msCrypto": true, + "nacl": "write" }, "packages": { - "browserify>buffer": true, - "browserify>url": true, - "process": true, - "pumpify>inherits": true, - "readable-stream": true, - "stream-http>builtin-status-codes": true, - "watchify>xtend": true + "browserify>browser-resolve": true } }, - "string.prototype.matchall>call-bind": { - "packages": { - "browserify>has>function-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>call-bind>set-function-length": true, - "string.prototype.matchall>get-intrinsic": true + "@trezor/connect-web>@trezor/connect-common>@trezor/env-utils>ua-parser-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>call-bind>es-define-property": { + "@ensdomains/content-hash>cids>uint8arrays": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>cids>multibase": true } }, - "string.prototype.matchall>call-bind>set-function-length": { + "@ensdomains/content-hash>multicodec>uint8arrays": { + "globals": { + "Buffer": true, + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>get-intrinsic": true + "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, - "string.prototype.matchall>define-properties": { + "react-markdown>unified": { "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "react-markdown>unified>bail": true, + "react-markdown>unified>extend": true, + "react-markdown>unified>is-buffer": true, + "mocha>yargs-unparser>is-plain-obj": true, + "react-markdown>unified>trough": true, + "react-markdown>vfile": true } }, - "string.prototype.matchall>define-properties>define-data-property": { + "react-markdown>unist-util-visit>unist-util-visit-parents": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "react-markdown>unist-util-visit>unist-util-is": true } }, - "string.prototype.matchall>es-abstract>array-buffer-byte-length": { + "react-markdown>unist-util-visit": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>is-array-buffer": true + "react-markdown>unist-util-visit>unist-util-visit-parents": true } }, - "string.prototype.matchall>es-abstract>available-typed-arrays": { - "packages": { - "string.prototype.matchall>es-abstract>typed-array-length>possible-typed-array-names": true + "uri-js": { + "globals": { + "define": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "browserify>url": { "packages": { - "string.prototype.matchall>has-symbols": true + "browserify>punycode": true, + "@storybook/addon-knobs>qs": true } }, - "string.prototype.matchall>es-abstract>gopd": { + "react-focus-lock>use-callback-ref": { "packages": { - "string.prototype.matchall>get-intrinsic": true + "react": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { + "react-beautiful-dnd>use-memo-one": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true + "react": true } }, - "string.prototype.matchall>es-abstract>is-array-buffer": { + "react-focus-lock>use-sidecar": { + "globals": { + "console.error": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>get-intrinsic": true + "react-focus-lock>use-sidecar>detect-node-es": true, + "react": true, + "tslib": true } }, - "string.prototype.matchall>es-abstract>is-callable": { + "readable-stream>util-deprecate": { "globals": { - "document": true + "console.trace": true, + "console.warn": true, + "localStorage": true } }, - "string.prototype.matchall>es-abstract>is-regex": { + "browserify>assert>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true, + "process": true + }, "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "browserify>assert>util>inherits": true, + "process": true } }, - "string.prototype.matchall>es-abstract>is-shared-array-buffer": { + "browserify>util": { + "globals": { + "console.error": true, + "console.log": true, + "console.trace": true + }, "packages": { - "string.prototype.matchall>call-bind": true + "pumpify>inherits": true, + "browserify>util>is-arguments": true, + "koa>is-generator-function": true, + "browserify>util>is-typed-array": true, + "process": true, + "browserify>util>which-typed-array": true } }, - "string.prototype.matchall>es-abstract>object-inspect": { + "uuid": { "globals": { - "HTMLElement": true, - "WeakRef": true - }, - "packages": { - "browserify>browser-resolve": true + "crypto": true, + "msCrypto": true } }, - "string.prototype.matchall>get-intrinsic": { + "@metamask/eth-snap-keyring>uuid": { "globals": { - "AggregateError": true, - "FinalizationRegistry": true, - "WeakRef": true - }, - "packages": { - "browserify>has>function-bind": true, - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true + "crypto": true } }, - "string.prototype.matchall>internal-slot": { - "packages": { - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>side-channel": true + "@metamask/keyring-snap-client>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "eth-lattice-keyring>gridplus-sdk>uuid": { + "globals": { + "crypto": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "web3-stream-provider>uuid": { + "globals": { + "crypto": true + } + }, + "@metamask/snaps-utils>validate-npm-package-name": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "@metamask/snaps-utils>validate-npm-package-name>builtins": true } }, - "string.prototype.matchall>side-channel": { + "react-markdown>vfile>vfile-message": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>get-intrinsic": true + "react-markdown>vfile>unist-util-stringify-position": true } }, - "terser>source-map-support>buffer-from": { + "react-markdown>vfile": { "packages": { - "browserify>buffer": true + "react-markdown>vfile>is-buffer": true, + "path-browserify": true, + "process": true, + "react-markdown>vfile>replace-ext": true, + "react-markdown>vfile>vfile-message": true } }, - "uri-js": { + "browserify>vm-browserify": { "globals": { - "define": true + "document.body.appendChild": true, + "document.body.removeChild": true, + "document.createElement": true } }, - "uuid": { + "react-popper>warning": { "globals": { - "crypto": true, - "msCrypto": true + "console": true } }, - "wait-on>rxjs": { + "@ensdomains/content-hash>multihashes>web-encoding": { "globals": { - "cancelAnimationFrame": true, - "clearInterval": true, - "clearTimeout": true, - "performance": true, - "requestAnimationFrame": true, - "setInterval.apply": true, - "setTimeout.apply": true + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>util": true } }, "web3": { @@ -5539,14 +5792,14 @@ "setTimeout": true }, "packages": { - "browserify>util": true, "readable-stream": true, + "browserify>util": true, "web3-stream-provider>uuid": true } }, - "web3-stream-provider>uuid": { + "@metamask/controllers>web3": { "globals": { - "crypto": true + "XMLHttpRequest": true } }, "webextension-polyfill": { @@ -5558,9 +5811,30 @@ "define": true } }, - "webpack>events": { - "globals": { - "console": true + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-bigint": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-boolean-object": true, + "@metamask/eth-token-tracker>deep-equal>which-boxed-primitive>is-number-object": true, + "eslint-plugin-react>array-includes>is-string": true, + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true + } + }, + "@metamask/eth-token-tracker>deep-equal>which-collection": { + "packages": { + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-map": true, + "@metamask/eth-token-tracker>deep-equal>es-get-iterator>is-set": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakmap": true, + "@metamask/eth-token-tracker>deep-equal>which-collection>is-weakset": true + } + }, + "browserify>util>which-typed-array": { + "packages": { + "string.prototype.matchall>es-abstract>available-typed-arrays": true, + "string.prototype.matchall>call-bind": true, + "browserify>util>which-typed-array>for-each": true, + "string.prototype.matchall>es-abstract>gopd": true, + "koa>is-generator-function>has-tostringtag": true } } } diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index 59a807e7313f..545922814d1f 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -1,57 +1,25 @@ { "resources": { - "@babel/code-frame": { + "@babel/core>@ampproject/remapping": { "globals": { - "console.warn": true, - "process": true + "define": true }, "packages": { - "@babel/code-frame>@babel/highlight": true, - "postcss>picocolors": true + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true, + "terser-webpack-plugin>@jridgewell/trace-mapping": true } }, - "@babel/code-frame>@babel/highlight": { + "@babel/code-frame": { "globals": { + "console.warn": true, "process": true }, "packages": { - "@babel/code-frame>@babel/highlight>chalk": true, - "lavamoat>@babel/highlight>@babel/helper-validator-identifier": true, + "@babel/code-frame>@babel/helper-validator-identifier": true, "loose-envify>js-tokens": true, "postcss>picocolors": true } }, - "@babel/code-frame>@babel/highlight>chalk": { - "globals": { - "process.env.TERM": true, - "process.platform": true - }, - "packages": { - "@babel/code-frame>@babel/highlight>chalk>ansi-styles": true, - "@babel/code-frame>@babel/highlight>chalk>escape-string-regexp": true, - "@babel/code-frame>@babel/highlight>chalk>supports-color": true - } - }, - "@babel/code-frame>@babel/highlight>chalk>ansi-styles": { - "packages": { - "@metamask/jazzicon>color>color-convert": true - } - }, - "@babel/code-frame>@babel/highlight>chalk>supports-color": { - "builtin": { - "os.release": true - }, - "globals": { - "process.env": true, - "process.platform": true, - "process.stderr": true, - "process.stdout": true, - "process.versions.node.split": true - }, - "packages": { - "gulp-livereload>chalk>supports-color>has-flag": true - } - }, "@babel/core": { "builtin": { "assert": true, @@ -75,18 +43,13 @@ }, "packages": { "$root$": true, - "@babel/code-frame": true, "@babel/core>@ampproject/remapping": true, + "@babel/code-frame": true, "@babel/core>@babel/generator": true, "@babel/core>@babel/helper-compilation-targets": true, "@babel/core>@babel/helper-module-transforms": true, "@babel/core>@babel/helpers": true, "@babel/core>@babel/parser": true, - "@babel/core>@babel/template": true, - "@babel/core>@babel/types": true, - "@babel/core>convert-source-map": true, - "@babel/core>gensync": true, - "@babel/core>semver": true, "@babel/plugin-proposal-class-properties": true, "@babel/plugin-proposal-nullish-coalescing-operator": true, "@babel/plugin-proposal-object-rest-spread": true, @@ -96,18 +59,44 @@ "@babel/preset-env": true, "@babel/preset-react": true, "@babel/preset-typescript": true, + "@babel/core>@babel/template": true, "depcheck>@babel/traverse": true, + "@babel/core>@babel/types": true, + "@babel/core>convert-source-map": true, + "nock>debug": true, + "@babel/core>gensync": true, "depcheck>json5": true, - "nock>debug": true + "@babel/core>semver": true } }, - "@babel/core>@ampproject/remapping": { + "@babel/eslint-parser": { + "builtin": { + "module": true, + "path": true, + "worker_threads": true + }, "globals": { - "define": true + "__dirname": true, + "process.cwd": true, + "process.versions": true }, "packages": { - "terser-webpack-plugin>@jridgewell/trace-mapping": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true + "@babel/core": true, + "@babel/parser": true, + "@babel/core>@babel/parser": true, + "depcheck>@babel/parser": true, + "lavamoat>lavamoat-tofu>@babel/parser": true, + "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals": true, + "eslint": true, + "@babel/eslint-parser>eslint-scope": true, + "@babel/eslint-parser>eslint-visitor-keys": true, + "@babel/eslint-parser>semver": true + } + }, + "@babel/eslint-plugin": { + "packages": { + "eslint": true, + "@babel/eslint-plugin>eslint-rule-composer": true } }, "@babel/core>@babel/generator": { @@ -116,15 +105,20 @@ "console.warn": true }, "packages": { - "@babel/core>@babel/generator>jsesc": true, "@babel/core>@babel/types": true, + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true, "terser-webpack-plugin>@jridgewell/trace-mapping": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true + "@babel/core>@babel/generator>jsesc": true } }, - "@babel/core>@babel/generator>jsesc": { - "globals": { - "Buffer": true + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": { + "packages": { + "@babel/core>@babel/types": true + } + }, + "@babel/preset-env>@babel/plugin-transform-exponentiation-operator>@babel/helper-builder-binary-assignment-operator-visitor": { + "packages": { + "@babel/core>@babel/types": true } }, "@babel/core>@babel/helper-compilation-targets": { @@ -135,22 +129,66 @@ "process.versions.node": true }, "packages": { - "@babel/core>@babel/helper-compilation-targets>lru-cache": true, - "@babel/core>@babel/helper-compilation-targets>semver": true, "@babel/preset-env>@babel/compat-data": true, "@babel/preset-env>@babel/helper-validator-option": true, - "browserslist": true + "browserslist": true, + "@babel/core>@babel/helper-compilation-targets>lru-cache": true, + "@babel/core>@babel/helper-compilation-targets>semver": true } }, - "@babel/core>@babel/helper-compilation-targets>lru-cache": { + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": { + "globals": { + "console.warn": true + }, "packages": { - "@babel/core>@babel/helper-compilation-targets>lru-cache>yallist": true + "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers": true, + "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, + "depcheck>@babel/traverse": true, + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin>semver": true } }, - "@babel/core>@babel/helper-compilation-targets>semver": { + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>semver": true + } + }, + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": { + "builtin": { + "module": true, + "path": true + }, "globals": { - "console": true, - "process": true + "console.log": true, + "console.warn": true, + "process.exitCode": "write", + "process.versions.node": true + }, + "packages": { + "@babel/core": true, + "@babel/core>@babel/helper-compilation-targets": true, + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider>lodash.debounce": true, + "depcheck>resolve": true + } + }, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": { + "packages": { + "@babel/core>@babel/types": true + } + }, + "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": { + "builtin": { + "assert": true + }, + "packages": { + "@babel/core>@babel/types": true } }, "@babel/core>@babel/helper-module-transforms": { @@ -163,242 +201,112 @@ "@babel/core": true, "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": true, "@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access": true, - "depcheck>@babel/traverse": true, - "lavamoat>@babel/highlight>@babel/helper-validator-identifier": true + "@babel/code-frame>@babel/helper-validator-identifier": true, + "depcheck>@babel/traverse": true } }, - "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": { - "builtin": { - "assert": true - }, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": { "packages": { "@babel/core>@babel/types": true } }, + "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, + "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator>@babel/helper-wrap-function": true, + "depcheck>@babel/traverse": true + } + }, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": true, + "depcheck>@babel/traverse": true + } + }, "@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access": { "packages": { "@babel/core>@babel/types": true } }, - "@babel/core>@babel/helpers": { + "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": { + "packages": { + "@babel/core>@babel/types": true + } + }, + "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator>@babel/helper-wrap-function": { "packages": { "@babel/core>@babel/template": true, + "depcheck>@babel/traverse": true, "@babel/core>@babel/types": true } }, - "@babel/core>@babel/template": { + "@babel/core>@babel/helpers": { "packages": { - "@babel/code-frame": true, - "@babel/core>@babel/parser": true, + "@babel/core>@babel/template": true, "@babel/core>@babel/types": true } }, - "@babel/core>@babel/types": { - "globals": { - "console.warn": true, - "process.env": true - }, + "@babel/preset-env>@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "packages": { - "@babel/core>@babel/types>@babel/helper-string-parser": true, - "lavamoat>@babel/highlight>@babel/helper-validator-identifier": true + "@babel/preset-env>@babel/helper-plugin-utils": true, + "depcheck>@babel/traverse": true } }, - "@babel/core>convert-source-map": { - "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "value": true + "@babel/preset-env>@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/core>semver": { - "globals": { - "console": true, - "process": true + "@babel/preset-env>@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "packages": { + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/eslint-parser": { - "builtin": { - "module": true, - "path": true, - "worker_threads": true - }, - "globals": { - "__dirname": true, - "process.cwd": true, - "process.versions": true - }, + "@babel/preset-env>@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "packages": { "@babel/core": true, - "@babel/core>@babel/parser": true, - "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals": true, - "@babel/eslint-parser>eslint-scope": true, - "@babel/eslint-parser>eslint-visitor-keys": true, - "@babel/eslint-parser>semver": true, - "@babel/parser": true, - "depcheck>@babel/parser": true, - "eslint": true, - "lavamoat>lavamoat-tofu>@babel/parser": true + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, + "@babel/preset-env>@babel/plugin-transform-optional-chaining": true } }, - "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals": { + "@babel/preset-env>@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "packages": { - "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope": true + "@babel/core": true, + "@babel/preset-env>@babel/helper-plugin-utils": true, + "depcheck>@babel/traverse": true } }, - "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope": { - "builtin": { - "assert": true - }, + "@babel/preset-env>@babel/plugin-syntax-import-assertions": { "packages": { - "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope>estraverse": true, - "eslint>eslint-scope>esrecurse": true + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/eslint-parser>semver": { - "globals": { - "console": true, - "process": true + "@babel/preset-env>@babel/plugin-syntax-import-attributes": { + "packages": { + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/eslint-plugin": { + "@babel/preset-typescript>@babel/plugin-syntax-jsx": { "packages": { - "@babel/eslint-plugin>eslint-rule-composer": true, - "eslint": true + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/plugin-transform-logical-assignment-operators": { + "@babel/preset-typescript>@babel/plugin-transform-typescript>@babel/plugin-syntax-typescript": { "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-syntax-logical-assignment-operators": true + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env": { - "globals": { - "console.log": true, - "console.warn": true, - "process.cwd": true, - "process.env.BABEL_ENV": true - }, - "packages": { - "@babel/core>@babel/helper-compilation-targets": true, - "@babel/plugin-transform-logical-assignment-operators": true, - "@babel/preset-env>@babel/compat-data": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/helper-validator-option": true, - "@babel/preset-env>@babel/plugin-bugfix-firefox-class-in-computed-class-key": true, - "@babel/preset-env>@babel/plugin-bugfix-safari-class-field-initializer-scope": true, - "@babel/preset-env>@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": true, - "@babel/preset-env>@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": true, - "@babel/preset-env>@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": true, - "@babel/preset-env>@babel/plugin-syntax-import-assertions": true, - "@babel/preset-env>@babel/plugin-syntax-import-attributes": true, - "@babel/preset-env>@babel/plugin-syntax-unicode-sets-regex": true, - "@babel/preset-env>@babel/plugin-transform-arrow-functions": true, - "@babel/preset-env>@babel/plugin-transform-async-generator-functions": true, - "@babel/preset-env>@babel/plugin-transform-async-to-generator": true, - "@babel/preset-env>@babel/plugin-transform-block-scoped-functions": true, - "@babel/preset-env>@babel/plugin-transform-block-scoping": true, - "@babel/preset-env>@babel/plugin-transform-class-properties": true, - "@babel/preset-env>@babel/plugin-transform-class-static-block": true, - "@babel/preset-env>@babel/plugin-transform-classes": true, - "@babel/preset-env>@babel/plugin-transform-computed-properties": true, - "@babel/preset-env>@babel/plugin-transform-destructuring": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex": true, - "@babel/preset-env>@babel/plugin-transform-duplicate-keys": true, - "@babel/preset-env>@babel/plugin-transform-duplicate-named-capturing-groups-regex": true, - "@babel/preset-env>@babel/plugin-transform-dynamic-import": true, - "@babel/preset-env>@babel/plugin-transform-exponentiation-operator": true, - "@babel/preset-env>@babel/plugin-transform-export-namespace-from": true, - "@babel/preset-env>@babel/plugin-transform-for-of": true, - "@babel/preset-env>@babel/plugin-transform-function-name": true, - "@babel/preset-env>@babel/plugin-transform-json-strings": true, - "@babel/preset-env>@babel/plugin-transform-literals": true, - "@babel/preset-env>@babel/plugin-transform-member-expression-literals": true, - "@babel/preset-env>@babel/plugin-transform-modules-amd": true, - "@babel/preset-env>@babel/plugin-transform-modules-commonjs": true, - "@babel/preset-env>@babel/plugin-transform-modules-systemjs": true, - "@babel/preset-env>@babel/plugin-transform-modules-umd": true, - "@babel/preset-env>@babel/plugin-transform-named-capturing-groups-regex": true, - "@babel/preset-env>@babel/plugin-transform-new-target": true, - "@babel/preset-env>@babel/plugin-transform-nullish-coalescing-operator": true, - "@babel/preset-env>@babel/plugin-transform-numeric-separator": true, - "@babel/preset-env>@babel/plugin-transform-object-rest-spread": true, - "@babel/preset-env>@babel/plugin-transform-object-super": true, - "@babel/preset-env>@babel/plugin-transform-optional-catch-binding": true, - "@babel/preset-env>@babel/plugin-transform-optional-chaining": true, - "@babel/preset-env>@babel/plugin-transform-parameters": true, - "@babel/preset-env>@babel/plugin-transform-private-methods": true, - "@babel/preset-env>@babel/plugin-transform-private-property-in-object": true, - "@babel/preset-env>@babel/plugin-transform-property-literals": true, - "@babel/preset-env>@babel/plugin-transform-regenerator": true, - "@babel/preset-env>@babel/plugin-transform-reserved-words": true, - "@babel/preset-env>@babel/plugin-transform-shorthand-properties": true, - "@babel/preset-env>@babel/plugin-transform-spread": true, - "@babel/preset-env>@babel/plugin-transform-sticky-regex": true, - "@babel/preset-env>@babel/plugin-transform-template-literals": true, - "@babel/preset-env>@babel/plugin-transform-typeof-symbol": true, - "@babel/preset-env>@babel/plugin-transform-unicode-escapes": true, - "@babel/preset-env>@babel/plugin-transform-unicode-property-regex": true, - "@babel/preset-env>@babel/plugin-transform-unicode-regex": true, - "@babel/preset-env>@babel/plugin-transform-unicode-sets-regex": true, - "@babel/preset-env>@babel/preset-modules": true, - "@babel/preset-env>babel-plugin-polyfill-corejs2": true, - "@babel/preset-env>babel-plugin-polyfill-corejs3": true, - "@babel/preset-env>babel-plugin-polyfill-regenerator": true, - "@babel/preset-env>core-js-compat": true, - "@babel/preset-env>semver": true - } - }, - "@babel/preset-env>@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "depcheck>@babel/traverse": true - } - }, - "@babel/preset-env>@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true - } - }, - "@babel/preset-env>@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true - } - }, - "@babel/preset-env>@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, - "@babel/preset-env>@babel/plugin-transform-optional-chaining": true - } - }, - "@babel/preset-env>@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "depcheck>@babel/traverse": true - } - }, - "@babel/preset-env>@babel/plugin-syntax-import-assertions": { - "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true - } - }, - "@babel/preset-env>@babel/plugin-syntax-import-attributes": { + "@babel/preset-env>@babel/plugin-syntax-unicode-sets-regex": { "packages": { + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env>@babel/plugin-syntax-unicode-sets-regex": { - "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true - } - }, "@babel/preset-env>@babel/plugin-transform-arrow-functions": { "packages": { "@babel/preset-env>@babel/helper-plugin-utils": true @@ -420,21 +328,6 @@ "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator": true } }, - "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator>@babel/helper-wrap-function": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "depcheck>@babel/traverse": true - } - }, - "@babel/preset-env>@babel/plugin-transform-async-to-generator>@babel/helper-remap-async-to-generator>@babel/helper-wrap-function": { - "packages": { - "@babel/core>@babel/template": true, - "@babel/core>@babel/types": true, - "depcheck>@babel/traverse": true - } - }, "@babel/preset-env>@babel/plugin-transform-block-scoped-functions": { "packages": { "@babel/core": true, @@ -449,55 +342,32 @@ }, "@babel/preset-env>@babel/plugin-transform-class-properties": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-class-static-block": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-classes": { "packages": { "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, "@babel/core>@babel/helper-compilation-targets": true, "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers": true, - "@babel/preset-env>@babel/plugin-transform-classes>globals": true, - "depcheck>@babel/traverse": true - } - }, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": { - "packages": { - "@babel/core>@babel/types": true - } - }, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": true, - "depcheck>@babel/traverse": true - } - }, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": { - "packages": { - "@babel/core>@babel/types": true - } - }, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": { - "packages": { - "@babel/core>@babel/types": true + "depcheck>@babel/traverse": true, + "@babel/preset-env>@babel/plugin-transform-classes>globals": true } }, "@babel/preset-env>@babel/plugin-transform-computed-properties": { "packages": { "@babel/core": true, - "@babel/core>@babel/template": true, - "@babel/preset-env>@babel/helper-plugin-utils": true + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/core>@babel/template": true } }, "@babel/preset-env>@babel/plugin-transform-destructuring": { @@ -508,55 +378,8 @@ }, "@babel/preset-env>@babel/plugin-transform-dotall-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>semver": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core": { - "globals": { - "characterClassItem.kind": true - }, - "packages": { - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regenerate": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsgen": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsparser": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-value-ecmascript": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regenerate": { - "globals": { - "define": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsgen": { - "globals": { - "define": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsparser": { - "globals": { - "regjsparser": "write" - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript": { - "packages": { - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript>unicode-canonical-property-names-ecmascript": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript>unicode-property-aliases-ecmascript": true - } - }, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>semver": { - "globals": { - "console": true, - "process": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-duplicate-keys": { @@ -567,8 +390,8 @@ }, "@babel/preset-env>@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-dynamic-import": { @@ -579,13 +402,8 @@ "@babel/preset-env>@babel/plugin-transform-exponentiation-operator": { "packages": { "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-exponentiation-operator>@babel/helper-builder-binary-assignment-operator-visitor": true - } - }, - "@babel/preset-env>@babel/plugin-transform-exponentiation-operator>@babel/helper-builder-binary-assignment-operator-visitor": { - "packages": { - "@babel/core>@babel/types": true + "@babel/preset-env>@babel/plugin-transform-exponentiation-operator>@babel/helper-builder-binary-assignment-operator-visitor": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-export-namespace-from": { @@ -601,11 +419,6 @@ "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true } }, - "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": { - "packages": { - "@babel/core>@babel/types": true - } - }, "@babel/preset-env>@babel/plugin-transform-function-name": { "packages": { "@babel/core>@babel/helper-compilation-targets": true, @@ -623,6 +436,13 @@ "@babel/preset-env>@babel/helper-plugin-utils": true } }, + "@babel/plugin-transform-logical-assignment-operators": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/preset-env>@babel/plugin-syntax-logical-assignment-operators": true + } + }, "@babel/preset-env>@babel/plugin-transform-member-expression-literals": { "packages": { "@babel/core": true, @@ -640,8 +460,8 @@ "packages": { "@babel/core": true, "@babel/core>@babel/helper-module-transforms": true, - "@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access": true, - "@babel/preset-env>@babel/helper-plugin-utils": true + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access": true } }, "@babel/preset-env>@babel/plugin-transform-modules-systemjs": { @@ -652,8 +472,8 @@ "@babel/core": true, "@babel/core>@babel/helper-module-transforms": true, "@babel/preset-env>@babel/helper-plugin-utils": true, - "depcheck>@babel/traverse": true, - "lavamoat>@babel/highlight>@babel/helper-validator-identifier": true + "@babel/code-frame>@babel/helper-validator-identifier": true, + "depcheck>@babel/traverse": true } }, "@babel/preset-env>@babel/plugin-transform-modules-umd": { @@ -669,8 +489,8 @@ }, "@babel/preset-env>@babel/plugin-transform-named-capturing-groups-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-new-target": { @@ -725,41 +545,52 @@ }, "@babel/preset-env>@babel/plugin-transform-private-methods": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": { - "globals": { - "console.warn": true - }, + "@babel/preset-env>@babel/plugin-transform-private-property-in-object": { "packages": { - "@babel/core": true, "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-replace-supers>@babel/helper-optimise-call-expression": true, - "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin>semver": true, - "depcheck>@babel/traverse": true + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin>semver": { - "globals": { - "console": true, - "process": true + "@babel/preset-env>@babel/plugin-transform-property-literals": { + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env>@babel/plugin-transform-private-property-in-object": { + "@babel/preset-react>@babel/plugin-transform-react-display-name": { + "builtin": { + "path.basename": true, + "path.dirname": true, + "path.extname": true + }, "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/core": true, + "@babel/preset-env>@babel/helper-plugin-utils": true + } + }, + "@babel/preset-react>@babel/plugin-transform-react-jsx-development": { + "packages": { + "@babel/preset-react>@babel/plugin-transform-react-jsx": true + } + }, + "@babel/preset-react>@babel/plugin-transform-react-jsx": { + "packages": { + "@babel/core": true, "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true + "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": true, + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/preset-typescript>@babel/plugin-syntax-jsx": true } }, - "@babel/preset-env>@babel/plugin-transform-property-literals": { + "@babel/preset-react>@babel/plugin-transform-react-pure-annotations": { "packages": { "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, "@babel/preset-env>@babel/helper-plugin-utils": true } }, @@ -769,15 +600,6 @@ "@babel/preset-env>@babel/plugin-transform-regenerator>regenerator-transform": true } }, - "@babel/preset-env>@babel/plugin-transform-regenerator>regenerator-transform": { - "builtin": { - "assert": true, - "util.inherits": true - }, - "packages": { - "@babel/runtime": true - } - }, "@babel/preset-env>@babel/plugin-transform-reserved-words": { "packages": { "@babel/core": true, @@ -815,6 +637,22 @@ "@babel/preset-env>@babel/helper-plugin-utils": true } }, + "@babel/preset-typescript>@babel/plugin-transform-typescript": { + "builtin": { + "assert": true + }, + "globals": { + "console.warn": true + }, + "packages": { + "@babel/core": true, + "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true, + "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, + "@babel/preset-typescript>@babel/plugin-transform-typescript>@babel/plugin-syntax-typescript": true + } + }, "@babel/preset-env>@babel/plugin-transform-unicode-escapes": { "packages": { "@babel/core": true, @@ -823,77 +661,97 @@ }, "@babel/preset-env>@babel/plugin-transform-unicode-property-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-unicode-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, "@babel/preset-env>@babel/plugin-transform-unicode-sets-regex": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true - } - }, - "@babel/preset-env>babel-plugin-polyfill-corejs2": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/compat-data": true, - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true, - "@babel/preset-env>babel-plugin-polyfill-corejs2>semver": true + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin": true, + "@babel/preset-env>@babel/helper-plugin-utils": true } }, - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": { - "builtin": { - "module": true, - "path": true - }, + "@babel/preset-env": { "globals": { "console.log": true, "console.warn": true, - "process.exitCode": "write", - "process.versions.node": true + "process.cwd": true, + "process.env.BABEL_ENV": true }, "packages": { - "@babel/core": true, + "@babel/preset-env>@babel/compat-data": true, "@babel/core>@babel/helper-compilation-targets": true, "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider>lodash.debounce": true, - "depcheck>resolve": true - } - }, - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider>lodash.debounce": { - "globals": { - "clearTimeout": true, - "setTimeout": true - } - }, - "@babel/preset-env>babel-plugin-polyfill-corejs2>semver": { - "globals": { - "console": true, - "process": true - } - }, - "@babel/preset-env>babel-plugin-polyfill-corejs3": { - "packages": { - "@babel/core": true, - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true, - "@babel/preset-env>core-js-compat": true - } - }, - "@babel/preset-env>babel-plugin-polyfill-regenerator": { - "packages": { - "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true - } - }, - "@babel/preset-env>semver": { - "globals": { - "console": true, - "process": true + "@babel/preset-env>@babel/helper-validator-option": true, + "@babel/preset-env>@babel/plugin-bugfix-firefox-class-in-computed-class-key": true, + "@babel/preset-env>@babel/plugin-bugfix-safari-class-field-initializer-scope": true, + "@babel/preset-env>@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": true, + "@babel/preset-env>@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": true, + "@babel/preset-env>@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": true, + "@babel/preset-env>@babel/plugin-syntax-import-assertions": true, + "@babel/preset-env>@babel/plugin-syntax-import-attributes": true, + "@babel/preset-env>@babel/plugin-syntax-unicode-sets-regex": true, + "@babel/preset-env>@babel/plugin-transform-arrow-functions": true, + "@babel/preset-env>@babel/plugin-transform-async-generator-functions": true, + "@babel/preset-env>@babel/plugin-transform-async-to-generator": true, + "@babel/preset-env>@babel/plugin-transform-block-scoped-functions": true, + "@babel/preset-env>@babel/plugin-transform-block-scoping": true, + "@babel/preset-env>@babel/plugin-transform-class-properties": true, + "@babel/preset-env>@babel/plugin-transform-class-static-block": true, + "@babel/preset-env>@babel/plugin-transform-classes": true, + "@babel/preset-env>@babel/plugin-transform-computed-properties": true, + "@babel/preset-env>@babel/plugin-transform-destructuring": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex": true, + "@babel/preset-env>@babel/plugin-transform-duplicate-keys": true, + "@babel/preset-env>@babel/plugin-transform-duplicate-named-capturing-groups-regex": true, + "@babel/preset-env>@babel/plugin-transform-dynamic-import": true, + "@babel/preset-env>@babel/plugin-transform-exponentiation-operator": true, + "@babel/preset-env>@babel/plugin-transform-export-namespace-from": true, + "@babel/preset-env>@babel/plugin-transform-for-of": true, + "@babel/preset-env>@babel/plugin-transform-function-name": true, + "@babel/preset-env>@babel/plugin-transform-json-strings": true, + "@babel/preset-env>@babel/plugin-transform-literals": true, + "@babel/plugin-transform-logical-assignment-operators": true, + "@babel/preset-env>@babel/plugin-transform-member-expression-literals": true, + "@babel/preset-env>@babel/plugin-transform-modules-amd": true, + "@babel/preset-env>@babel/plugin-transform-modules-commonjs": true, + "@babel/preset-env>@babel/plugin-transform-modules-systemjs": true, + "@babel/preset-env>@babel/plugin-transform-modules-umd": true, + "@babel/preset-env>@babel/plugin-transform-named-capturing-groups-regex": true, + "@babel/preset-env>@babel/plugin-transform-new-target": true, + "@babel/preset-env>@babel/plugin-transform-nullish-coalescing-operator": true, + "@babel/preset-env>@babel/plugin-transform-numeric-separator": true, + "@babel/preset-env>@babel/plugin-transform-object-rest-spread": true, + "@babel/preset-env>@babel/plugin-transform-object-super": true, + "@babel/preset-env>@babel/plugin-transform-optional-catch-binding": true, + "@babel/preset-env>@babel/plugin-transform-optional-chaining": true, + "@babel/preset-env>@babel/plugin-transform-parameters": true, + "@babel/preset-env>@babel/plugin-transform-private-methods": true, + "@babel/preset-env>@babel/plugin-transform-private-property-in-object": true, + "@babel/preset-env>@babel/plugin-transform-property-literals": true, + "@babel/preset-env>@babel/plugin-transform-regenerator": true, + "@babel/preset-env>@babel/plugin-transform-reserved-words": true, + "@babel/preset-env>@babel/plugin-transform-shorthand-properties": true, + "@babel/preset-env>@babel/plugin-transform-spread": true, + "@babel/preset-env>@babel/plugin-transform-sticky-regex": true, + "@babel/preset-env>@babel/plugin-transform-template-literals": true, + "@babel/preset-env>@babel/plugin-transform-typeof-symbol": true, + "@babel/preset-env>@babel/plugin-transform-unicode-escapes": true, + "@babel/preset-env>@babel/plugin-transform-unicode-property-regex": true, + "@babel/preset-env>@babel/plugin-transform-unicode-regex": true, + "@babel/preset-env>@babel/plugin-transform-unicode-sets-regex": true, + "@babel/preset-env>@babel/preset-modules": true, + "@babel/preset-env>babel-plugin-polyfill-corejs2": true, + "@babel/preset-env>babel-plugin-polyfill-corejs3": true, + "@babel/preset-env>babel-plugin-polyfill-regenerator": true, + "@babel/preset-env>core-js-compat": true, + "@babel/preset-env>semver": true } }, "@babel/preset-react": { @@ -901,214 +759,252 @@ "@babel/preset-env>@babel/helper-plugin-utils": true, "@babel/preset-env>@babel/helper-validator-option": true, "@babel/preset-react>@babel/plugin-transform-react-display-name": true, - "@babel/preset-react>@babel/plugin-transform-react-jsx": true, "@babel/preset-react>@babel/plugin-transform-react-jsx-development": true, + "@babel/preset-react>@babel/plugin-transform-react-jsx": true, "@babel/preset-react>@babel/plugin-transform-react-pure-annotations": true } }, - "@babel/preset-react>@babel/plugin-transform-react-display-name": { - "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true - }, - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true - } - }, - "@babel/preset-react>@babel/plugin-transform-react-jsx": { - "packages": { - "@babel/core": true, - "@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "@babel/preset-typescript>@babel/plugin-syntax-jsx": true - } - }, - "@babel/preset-react>@babel/plugin-transform-react-jsx-development": { - "packages": { - "@babel/preset-react>@babel/plugin-transform-react-jsx": true - } - }, - "@babel/preset-react>@babel/plugin-transform-react-pure-annotations": { - "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true - } - }, "@babel/preset-typescript": { "packages": { "@babel/preset-env>@babel/helper-plugin-utils": true, "@babel/preset-env>@babel/helper-validator-option": true, - "@babel/preset-env>@babel/plugin-transform-modules-commonjs": true, "@babel/preset-typescript>@babel/plugin-syntax-jsx": true, + "@babel/preset-env>@babel/plugin-transform-modules-commonjs": true, "@babel/preset-typescript>@babel/plugin-transform-typescript": true } }, - "@babel/preset-typescript>@babel/plugin-syntax-jsx": { + "@babel/core>@babel/template": { "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true + "@babel/code-frame": true, + "@babel/core>@babel/parser": true, + "@babel/core>@babel/types": true } }, - "@babel/preset-typescript>@babel/plugin-transform-typescript": { - "builtin": { - "assert": true - }, + "depcheck>@babel/traverse": { "globals": { - "console.warn": true + "console.log": true }, "packages": { - "@babel/core": true, - "@babel/preset-env>@babel/helper-plugin-utils": true, - "@babel/preset-env>@babel/plugin-transform-classes>@babel/helper-annotate-as-pure": true, - "@babel/preset-env>@babel/plugin-transform-for-of>@babel/helper-skip-transparent-expression-wrappers": true, - "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin": true, - "@babel/preset-typescript>@babel/plugin-transform-typescript>@babel/plugin-syntax-typescript": true - } - }, - "@babel/preset-typescript>@babel/plugin-transform-typescript>@babel/plugin-syntax-typescript": { - "packages": { - "@babel/preset-env>@babel/helper-plugin-utils": true + "@babel/code-frame": true, + "@babel/core>@babel/generator": true, + "@babel/core>@babel/parser": true, + "@babel/core>@babel/template": true, + "@babel/core>@babel/types": true, + "babel/preset-env>b@babel/types": true, + "nock>debug": true, + "depcheck>@babel/traverse>globals": true } }, - "@babel/register>clone-deep>is-plain-object": { + "@babel/core>@babel/types": { + "globals": { + "console.warn": true, + "process.env": true + }, "packages": { - "gulp>gulp-cli>isobject": true + "@babel/core>@babel/types>@babel/helper-string-parser": true, + "@babel/code-frame>@babel/helper-validator-identifier": true } }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog": { + "sass-embedded>@bufbuild/protobuf": { + "globals": { + "TextDecoder": true, + "TextEncoder": true, + "__values": true, + "process": true + } + }, + "ts-node>@cspotcode/source-map-support": { "builtin": { - "events.EventEmitter": true, - "util": true + "fs": true, + "path.isAbsolute": true, + "path.join": true, + "path.normalize": true, + "path.resolve": true, + "url.fileURLToPath": true, + "url.pathToFileURL": true, + "util.inspect": true }, "globals": { - "process.nextTick": true, - "process.stderr": true + "Buffer.from": true, + "URL": true, + "XMLHttpRequest": true, + "console.error": true, + "process": true }, "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>are-we-there-yet": true, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": true, - "@storybook/react>@storybook/node-logger>npmlog>console-control-strings": true, - "nyc>yargs>set-blocking": true + "ts-node>@cspotcode/source-map-support>@jridgewell/trace-mapping": true } }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>are-we-there-yet": { - "builtin": { - "events.EventEmitter": true, - "util.inherits": true - }, + "eslint-plugin-jsdoc>@es-joy/jsdoccomment": { "packages": { - "koa>delegates": true, - "readable-stream": true + "eslint-plugin-jsdoc>comment-parser": true, + "eslint>esquery": true, + "eslint-plugin-jsdoc>@es-joy/jsdoccomment>jsdoc-type-pratt-parser": true } }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": { + "eslint>@eslint-community/eslint-utils": { + "packages": { + "eslint>eslint-visitor-keys": true + } + }, + "eslint>@eslint/eslintrc": { "builtin": { - "util.format": true + "assert": true, + "fs": true, + "module": true, + "os": true, + "path": true, + "url": true, + "util": true }, "globals": { - "clearInterval": true, - "process": true, - "setImmediate": true, - "setInterval": true + "__filename": true, + "process.cwd": true, + "process.emitWarning": true, + "process.platform": true }, "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>aproba": true, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width": true, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": true, - "@storybook/react>@storybook/node-logger>npmlog>console-control-strings": true, - "@storybook/react>@storybook/node-logger>npmlog>gauge>has-unicode": true, - "@storybook/react>@storybook/node-logger>npmlog>gauge>wide-align": true, - "nyc>signal-exit": true, - "react>object-assign": true - } - }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width": { - "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": true, - "gulp>gulp-cli>yargs>string-width>code-point-at": true + "$root$": true, + "@babel/eslint-parser": true, + "@babel/eslint-plugin": true, + "@metamask/eslint-config": true, + "@metamask/eslint-config-nodejs": true, + "@metamask/eslint-config-typescript": true, + "@typescript-eslint/eslint-plugin": true, + "eslint>ajv": true, + "nock>debug": true, + "eslint": true, + "eslint-config-prettier": true, + "eslint-plugin-import": true, + "eslint-plugin-jsdoc": true, + "eslint-plugin-node": true, + "eslint-plugin-prettier": true, + "eslint-plugin-react": true, + "eslint-plugin-react-hooks": true, + "eslint>globals": true, + "eslint>ignore": true, + "eslint>minimatch": true, + "mocha>strip-json-comments": true } }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { + "gulp-sourcemaps>@gulp-sourcemaps/identity-map": { "packages": { - "gulp>gulp-cli>yargs>string-width>is-fullwidth-code-point>number-is-nan": true + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>acorn": true, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>normalize-path": true, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss": true, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>source-map": true, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>through2": true } }, - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": { + "gulp-sourcemaps>@gulp-sourcemaps/map-sources": { "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi>ansi-regex": true + "gulp-watch>anymatch>normalize-path": true, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2": true } }, - "@lavamoat/lavapack": { + "eslint>@humanwhocodes/config-array": { "builtin": { - "assert": true, - "buffer.Buffer.from": true, - "fs.promises.readFile": true, - "fs.promises.writeFile": true, - "fs.readFileSync": true, + "path.dirname": true, "path.join": true, "path.relative": true }, + "packages": { + "eslint>@humanwhocodes/config-array>@humanwhocodes/object-schema": true, + "nock>debug": true, + "eslint>minimatch": true + } + }, + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": { "globals": { - "__dirname": true, - "__filename.slice": true, - "console.error": true, - "console.warn": true, - "process.cwd": true, - "setTimeout": true + "define": true }, "packages": { - "@lavamoat/lavapack>combine-source-map": true, - "@lavamoat/lavapack>convert-source-map": true, - "@lavamoat/lavapack>json-stable-stringify": true, - "@lavamoat/lavapack>umd": true, - "browserify>JSONStream": true, - "eslint>espree": true, - "lavamoat-viz>lavamoat-core": true, - "readable-stream": true, - "through2": true + "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/set-array": true, + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true, + "terser-webpack-plugin>@jridgewell/trace-mapping": true } }, - "@lavamoat/lavapack>combine-source-map": { - "builtin": { - "path.dirname": true, - "path.join": true - }, + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": { "globals": { - "process.platform": true - }, + "define": true + } + }, + "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/set-array": { + "globals": { + "define": true + } + }, + "terser>@jridgewell/source-map": { "packages": { - "@lavamoat/lavapack>combine-source-map>inline-source-map": true, - "@lavamoat/lavapack>combine-source-map>lodash.memoize": true, - "@lavamoat/lavapack>combine-source-map>source-map": true, - "nyc>convert-source-map": true + "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true, + "terser-webpack-plugin>@jridgewell/trace-mapping": true } }, - "@lavamoat/lavapack>combine-source-map>inline-source-map": { + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": { "globals": { - "Buffer.from": true + "Buffer": true, + "TextDecoder": true, + "define": true + } + }, + "ts-node>@cspotcode/source-map-support>@jridgewell/trace-mapping": { + "globals": { + "define": true }, "packages": { - "@lavamoat/lavapack>combine-source-map>inline-source-map>source-map": true + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": true, + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true } }, - "@lavamoat/lavapack>convert-source-map": { + "terser-webpack-plugin>@jridgewell/trace-mapping": { "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "value": true + "define": true + }, + "packages": { + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": true, + "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true } }, - "@lavamoat/lavapack>json-stable-stringify": { + "lavamoat>@lavamoat/aa": { + "builtin": { + "node:fs.lstatSync": true, + "node:fs.readFileSync": true, + "node:fs.realpathSync": true, + "node:path.dirname": true, + "node:path.join": true, + "node:path.relative": true + }, "packages": { - "@lavamoat/lavapack>json-stable-stringify>isarray": true, - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "lavamoat>json-stable-stringify>jsonify": true, - "string.prototype.matchall>call-bind": true + "depcheck>resolve": true + } + }, + "@lavamoat/lavapack": { + "builtin": { + "node:assert": true, + "node:buffer.Buffer.from": true, + "node:fs.promises.readFile": true, + "node:fs.promises.writeFile": true, + "node:fs.readFileSync": true, + "node:path.join": true, + "node:path.relative": true + }, + "globals": { + "__dirname": true, + "__filename.slice": true, + "console.error": true, + "console.warn": true, + "process.cwd": true, + "setTimeout": true + }, + "packages": { + "browserify>JSONStream": true, + "@lavamoat/lavapack>combine-source-map": true, + "eslint>espree": true, + "@lavamoat/lavapack>json-stable-stringify": true, + "lavamoat>lavamoat-core": true, + "@lavamoat/lavapack>readable-stream": true, + "through2": true, + "@lavamoat/lavapack>umd": true } }, "@metamask/build-utils": { @@ -1124,37 +1020,16 @@ }, "packages": { "@metamask/utils>@metamask/superstruct": true, - "@metamask/utils>@scure/base": true, - "@metamask/utils>pony-cause": true, "@noble/hashes": true, + "@metamask/utils>@scure/base": true, "nock>debug": true, + "@metamask/utils>pony-cause": true, "semver": true } }, - "@metamask/eth-token-tracker>deep-equal>is-date-object": { - "packages": { - "koa>is-generator-function>has-tostringtag": true - } - }, - "@metamask/jazzicon>color>clone": { - "globals": { - "Buffer": true - } - }, - "@metamask/jazzicon>color>color-convert": { - "packages": { - "@metamask/jazzicon>color>color-convert>color-name": true - } - }, - "@metamask/object-multiplex>once": { + "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals": { "packages": { - "@metamask/object-multiplex>once>wrappy": true - } - }, - "@metamask/utils>@scure/base": { - "globals": { - "TextDecoder": true, - "TextEncoder": true + "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope": true } }, "@noble/hashes": { @@ -1163,93 +1038,120 @@ "crypto": true } }, - "@sentry/cli>which>isexe": { + "eslint>@nodelib/fs.walk>@nodelib/fs.scandir": { "builtin": { - "fs": true + "fs.lstat": true, + "fs.lstatSync": true, + "fs.readdir": true, + "fs.readdirSync": true, + "fs.stat": true, + "fs.statSync": true, + "path.sep": true }, "globals": { - "TESTING_WINDOWS": true, - "process.env.PATHEXT": true, - "process.getgid": true, - "process.getuid": true, - "process.platform": true - } - }, - "@storybook/addon-knobs>qs": { + "process.versions.node": true + }, "packages": { - "string.prototype.matchall>side-channel": true + "fast-glob>@nodelib/fs.stat": true, + "eslint>@nodelib/fs.walk>@nodelib/fs.scandir>run-parallel": true } }, - "@storybook/core>@storybook/core-server>x-default-browser>default-browser-id>untildify>os-homedir": { + "fast-glob>@nodelib/fs.stat": { "builtin": { - "os.homedir": true - }, - "globals": { - "process.env": true, - "process.getuid": true, - "process.platform": true + "fs.lstat": true, + "fs.lstatSync": true, + "fs.stat": true, + "fs.statSync": true } }, - "@storybook/react>@storybook/node-logger>npmlog>gauge>has-unicode": { + "eslint>@nodelib/fs.walk": { "builtin": { - "os.type": true + "events.EventEmitter": true, + "path.sep": true, + "stream.Readable": true }, "globals": { - "process.env.LANG": true, - "process.env.LC_ALL": true, - "process.env.LC_CTYPE": true + "setImmediate": true + }, + "packages": { + "eslint>@nodelib/fs.walk>@nodelib/fs.scandir": true, + "eslint>@nodelib/fs.walk>fastq": true } }, - "@storybook/react>@storybook/node-logger>npmlog>gauge>wide-align": { - "packages": { - "yargs>string-width": true + "@metamask/utils>@scure/base": { + "globals": { + "TextDecoder": true, + "TextEncoder": true } }, - "@storybook/react>acorn-walk": { + "stylelint>@stylelint/postcss-css-in-js": { "globals": { - "define": true + "__dirname": true + }, + "packages": { + "@babel/core": true, + "stylelint>postcss-syntax": true, + "stylelint>postcss": true } }, - "@storybook/test-runner>jest-circus>p-limit": { + "stylelint>@stylelint/postcss-markdown": { "packages": { - "@storybook/test-runner>jest-circus>p-limit>yocto-queue": true + "stylelint>postcss-html": true, + "stylelint>postcss-syntax": true, + "stylelint>@stylelint/postcss-markdown>remark": true, + "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after": true } }, "@typescript-eslint/eslint-plugin": { "packages": { + "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils": true, "@typescript-eslint/eslint-plugin>@typescript-eslint/utils": true, - "@typescript-eslint/eslint-plugin>tsutils": true, - "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, - "eslint": true, "eslint-plugin-jest>@typescript-eslint/utils": true, "eslint>debug": true, - "eslint>regexpp": true, + "eslint": true, "globby>ignore": true, + "eslint>regexpp": true, "semver": true, + "@typescript-eslint/eslint-plugin>tsutils": true, "typescript": true } }, + "eslint-plugin-jest>@typescript-eslint/experimental-utils": { + "builtin": { + "path": true + }, + "packages": { + "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, + "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, + "@typescript-eslint/parser>@typescript-eslint/types": true, + "eslint": true, + "eslint>eslint-scope": true, + "webpack>eslint-scope": true, + "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils": true, + "eslint>eslint-utils": true + } + }, + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": { + "builtin": { + "path": true + }, + "packages": { + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true, + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager>@typescript-eslint/visitor-keys": true + } + }, "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils": { "packages": { - "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug": true, "@typescript-eslint/eslint-plugin>@typescript-eslint/utils": true, - "@typescript-eslint/eslint-plugin>tsutils": true, "eslint-plugin-jest>@typescript-eslint/utils": true, + "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug": true, "eslint>debug": true, "nock>debug": true, + "@typescript-eslint/eslint-plugin>tsutils": true, "typescript": true } }, - "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug": { - "globals": { - "console.debug": true, - "console.log": true - }, - "packages": { - "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug>ms": true - } - }, "@typescript-eslint/eslint-plugin>@typescript-eslint/utils": { "builtin": { "path": true @@ -1259,95 +1161,50 @@ "@typescript-eslint/parser>@typescript-eslint/types": true, "@typescript-eslint/utils": true, "eslint": true, - "eslint-plugin-mocha>eslint-utils": true, + "webpack>eslint-scope": true, "eslint>eslint-utils": true, - "webpack>eslint-scope": true - } - }, - "autoprefixer": { - "globals": { - "console": true, - "process.cwd": true, - "process.env.AUTOPREFIXER_GRID": true - }, - "packages": { - "autoprefixer>caniuse-lite": true, - "autoprefixer>fraction.js": true, - "autoprefixer>normalize-range": true, - "browserslist": true, - "postcss": true, - "postcss>picocolors": true, - "stylelint>postcss-value-parser": true + "eslint-plugin-mocha>eslint-utils": true } }, - "babelify": { + "eslint-plugin-jest>@typescript-eslint/utils": { "builtin": { - "path.extname": true, - "path.resolve": true, - "stream.PassThrough": true, - "stream.Transform": true, - "util": true + "assert": true, + "path": true }, "globals": { - "Buffer.concat": true + "afterAll": true, + "process.cwd": true }, "packages": { - "@babel/core": true - } - }, - "bify-module-groups": { - "packages": { - "bify-module-groups>through2": true, - "pify": true, - "pumpify>pump": true + "eslint>@eslint-community/eslint-utils": true, + "eslint>@eslint-community": true, + "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": true, + "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, + "@typescript-eslint/parser>@typescript-eslint/types": true, + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true, + "@typescript-eslint/parser>@typescript-eslint": true, + "eslint": true, + "eslint-plugin-jest>@typescript-eslint/utils>eslint-scope": true, + "eslint>eslint-scope": true, + "webpack>eslint-scope": true, + "eslint-plugin-jest>@typescript-eslint/utils>webpack>eslint-scope": true, + "eslint>eslint-utils": true, + "eslint-plugin-mocha>eslint-utils": true, + "semver": true } }, - "bify-module-groups>through2": { + "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager>@typescript-eslint/visitor-keys": { "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true + "path": true }, "packages": { - "readable-stream": true + "eslint>eslint-visitor-keys": true } }, - "browserify": { - "builtin": { - "events.EventEmitter": true, - "fs.realpath": true, - "path.dirname": true, - "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true - }, + "eslint>@ungap/structured-clone": { "globals": { - "__dirname": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true - }, - "packages": { - "browserify>browser-pack": true, - "browserify>browser-resolve": true, - "browserify>cached-path-relative": true, - "browserify>concat-stream": true, - "browserify>deps-sort": true, - "browserify>has": true, - "browserify>insert-module-globals": true, - "browserify>module-deps": true, - "browserify>read-only-stream": true, - "browserify>shasum-object": true, - "browserify>syntax-error": true, - "browserify>through2": true, - "depcheck>resolve": true, - "labeled-stream-splicer": true, - "lavamoat>htmlescape": true, - "pumpify>inherits": true, - "watchify>defined": true, - "watchify>xtend": true + "structuredClone": true } }, "browserify>JSONStream": { @@ -1359,585 +1216,441 @@ "debounce-stream>through": true } }, - "browserify>JSONStream>jsonparse": { - "globals": { - "Buffer": true + "@lavamoat/lavapack>readable-stream>abort-controller": { + "packages": { + "@lavamoat/lavapack>readable-stream>abort-controller>event-target-shim": true } }, - "browserify>browser-pack": { - "builtin": { - "fs.readFileSync": true, - "path.join": true, - "path.relative": true - }, - "globals": { - "__dirname": true, - "process.cwd": true - }, + "eslint>espree>acorn-jsx": { "packages": { - "@lavamoat/lavapack>combine-source-map": true, - "@lavamoat/lavapack>umd": true, - "browserify>JSONStream": true, - "browserify>browser-pack>through2": true, - "koa>content-disposition>safe-buffer": true, - "watchify>defined": true + "jsdom>acorn": true } }, - "browserify>browser-pack>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, + "browserify>syntax-error>acorn-node": { "packages": { - "browserify>browser-pack>through2>readable-stream": true, + "@storybook/react>acorn-walk": true, + "browserify>syntax-error>acorn-node>acorn": true, "watchify>xtend": true } }, - "browserify>browser-pack>through2>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, + "@storybook/react>acorn-walk": { "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "browserify>browser-pack>through2>readable-stream>isarray": true, - "browserify>browser-pack>through2>readable-stream>safe-buffer": true, - "browserify>browser-pack>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "define": true } }, - "browserify>browser-pack>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "ts-node>acorn-walk": { + "globals": { + "define": true } }, - "browserify>browser-pack>through2>readable-stream>string_decoder": { - "packages": { - "browserify>browser-pack>through2>readable-stream>string_decoder>safe-buffer": true + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>acorn": { + "globals": { + "define": true } }, - "browserify>browser-pack>through2>readable-stream>string_decoder>safe-buffer": { - "builtin": { - "buffer": true + "browserify>syntax-error>acorn-node>acorn": { + "globals": { + "define": true } }, - "browserify>browser-resolve": { - "builtin": { - "fs.readFile": true, - "fs.readFileSync": true, - "path": true - }, + "gulp-sourcemaps>acorn": { "globals": { - "__dirname": true, - "process.platform": true - }, - "packages": { - "depcheck>resolve": true + "define": true } }, - "browserify>cached-path-relative": { - "builtin": { - "path": true - }, + "jsdom>acorn": { "globals": { - "process.cwd": true + "console": true, + "define": true } }, - "browserify>concat-stream": { - "globals": { - "Buffer.concat": true, - "Buffer.isBuffer": true - }, + "del>p-map>aggregate-error": { "packages": { - "browserify>concat-stream>readable-stream": true, - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "terser>source-map-support>buffer-from": true + "del>p-map>aggregate-error>clean-stack": true, + "prettier-eslint>indent-string": true } }, - "browserify>concat-stream>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, + "eslint>ajv": { "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "console": true }, "packages": { - "browserify>concat-stream>readable-stream>isarray": true, - "browserify>concat-stream>readable-stream>safe-buffer": true, - "browserify>concat-stream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "eslint>fast-deep-equal": true, + "@metamask/snaps-utils>fast-json-stable-stringify": true, + "eslint>ajv>json-schema-traverse": true, + "uri-js": true } }, - "browserify>concat-stream>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp-watch>ansi-colors": { + "packages": { + "fancy-log>ansi-gray>ansi-wrap": true } }, - "browserify>concat-stream>readable-stream>string_decoder": { + "fancy-log>ansi-gray": { "packages": { - "browserify>concat-stream>readable-stream>safe-buffer": true + "fancy-log>ansi-gray>ansi-wrap": true } }, - "browserify>deps-sort": { + "chalk>ansi-styles": { "packages": { - "browserify>deps-sort>through2": true, - "browserify>shasum-object": true + "chalk>ansi-styles>color-convert": true } }, - "browserify>deps-sort>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, + "gulp-livereload>chalk>ansi-styles": { "packages": { - "browserify>deps-sort>through2>readable-stream": true, - "watchify>xtend": true + "gulp-livereload>chalk>ansi-styles>color-convert": true } }, - "browserify>deps-sort>through2>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "stylelint>table>slice-ansi>ansi-styles": { "packages": { - "browserify>deps-sort>through2>readable-stream>isarray": true, - "browserify>deps-sort>through2>readable-stream>safe-buffer": true, - "browserify>deps-sort>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "stylelint>table>slice-ansi>ansi-styles>color-convert": true } }, - "browserify>deps-sort>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "chokidar>anymatch": { + "packages": { + "chokidar>anymatch>normalize-path": true, + "chokidar>anymatch>picomatch": true } }, - "browserify>deps-sort>through2>readable-stream>string_decoder": { + "gulp>glob-watcher>anymatch": { + "builtin": { + "path.sep": true + }, "packages": { - "browserify>deps-sort>through2>readable-stream>safe-buffer": true + "gulp>glob-watcher>anymatch>micromatch": true, + "gulp-watch>anymatch>normalize-path": true } }, - "browserify>duplexer2": { + "gulp-watch>anymatch": { + "builtin": { + "path.sep": true + }, "packages": { - "browserify>duplexer2>readable-stream": true + "gulp-watch>anymatch>micromatch": true, + "gulp-watch>anymatch>normalize-path": true } }, - "browserify>duplexer2>readable-stream": { + "gulp>vinyl-fs>vinyl-sourcemap>append-buffer": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "os.EOL": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer": true }, "packages": { - "browserify>duplexer2>readable-stream>isarray": true, - "browserify>duplexer2>readable-stream>safe-buffer": true, - "browserify>duplexer2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "gulp>vinyl-fs>vinyl-sourcemap>append-buffer>buffer-equal": true } }, - "browserify>duplexer2>readable-stream>safe-buffer": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>are-we-there-yet": { "builtin": { - "buffer": true + "events.EventEmitter": true, + "util.inherits": true + }, + "packages": { + "koa>delegates": true, + "readable-stream": true } }, - "browserify>duplexer2>readable-stream>string_decoder": { - "packages": { - "browserify>duplexer2>readable-stream>safe-buffer": true + "ts-node>arg": { + "globals": { + "process.argv.slice": true } }, - "browserify>has": { + "gulp-watch>anymatch>micromatch>arr-diff": { "packages": { - "browserify>has>function-bind": true + "gulp>undertaker>arr-flatten": true } }, - "browserify>insert-module-globals": { - "builtin": { - "path.dirname": true, - "path.isAbsolute": true, - "path.relative": true, - "path.sep": true - }, - "globals": { - "Buffer.concat": true, - "Buffer.isBuffer": true - }, + "gulp>undertaker>bach>arr-filter": { "packages": { - "@lavamoat/lavapack>combine-source-map": true, - "browserify>insert-module-globals>through2": true, - "browserify>insert-module-globals>undeclared-identifiers": true, - "browserify>syntax-error>acorn-node": true, - "gulp-watch>path-is-absolute": true, - "watchify>xtend": true + "gulp>undertaker>arr-map>make-iterator": true } }, - "browserify>insert-module-globals>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, + "gulp>undertaker>arr-map": { "packages": { - "browserify>insert-module-globals>through2>readable-stream": true, - "watchify>xtend": true + "gulp>undertaker>arr-map>make-iterator": true } }, - "browserify>insert-module-globals>through2>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "eslint-plugin-react>array-includes": { "packages": { - "browserify>insert-module-globals>through2>readable-stream>isarray": true, - "browserify>insert-module-globals>through2>readable-stream>safe-buffer": true, - "browserify>insert-module-globals>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true, + "string.prototype.matchall>get-intrinsic": true, + "eslint-plugin-react>array-includes>is-string": true } }, - "browserify>insert-module-globals>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp>undertaker>bach>array-initial": { + "packages": { + "gulp>undertaker>object.defaults>array-slice": true, + "gulp>undertaker>bach>array-last>is-number": true } }, - "browserify>insert-module-globals>through2>readable-stream>string_decoder": { + "gulp>undertaker>bach>array-last": { "packages": { - "browserify>insert-module-globals>through2>readable-stream>safe-buffer": true + "gulp>undertaker>bach>array-last>is-number": true } }, - "browserify>insert-module-globals>undeclared-identifiers": { + "eslint-plugin-import>array.prototype.flat": { "packages": { - "browserify>insert-module-globals>undeclared-identifiers>get-assigned-identifiers": true, - "browserify>syntax-error>acorn-node": true, - "watchify>xtend": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true } }, - "browserify>insert-module-globals>undeclared-identifiers>get-assigned-identifiers": { - "builtin": { - "assert.equal": true + "eslint-plugin-react>array.prototype.flatmap": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true, + "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true } }, - "browserify>module-deps": { - "builtin": { - "fs.createReadStream": true, - "fs.readFile": true, - "path.delimiter": true, - "path.dirname": true, - "path.join": true, - "path.resolve": true - }, + "gulp>glob-watcher>async-done": { "globals": { - "process.cwd": true, - "process.env.NODE_PATH": true, - "process.nextTick": true, - "process.platform": true, - "setTimeout": true, - "tr": true + "process.nextTick": true }, "packages": { - "browserify>browser-resolve": true, - "browserify>cached-path-relative": true, - "browserify>concat-stream": true, - "browserify>duplexer2": true, - "browserify>module-deps>detective": true, - "browserify>module-deps>readable-stream": true, - "browserify>module-deps>stream-combiner2": true, - "browserify>module-deps>through2": true, - "browserify>parents": true, - "depcheck>resolve": true, - "loose-envify": true, - "pumpify>inherits": true, - "watchify>defined": true, - "watchify>xtend": true + "duplexify>end-of-stream": true, + "@metamask/object-multiplex>once": true, + "readable-stream-2>process-nextick-args": true, + "gulp>glob-watcher>async-done>stream-exhaust": true } }, - "browserify>module-deps>detective": { + "gulp>undertaker>bach>async-settle": { "packages": { - "browserify>syntax-error>acorn-node": true, - "watchify>defined": true + "gulp>glob-watcher>async-done": true } }, - "browserify>module-deps>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "gulp-sourcemaps>css>source-map-resolve>atob": { + "globals": { + "Buffer.from": true + } + }, + "autoprefixer": { + "globals": { + "console": true, + "process.cwd": true, + "process.env.AUTOPREFIXER_GRID": true }, + "packages": { + "browserslist": true, + "autoprefixer>caniuse-lite": true, + "autoprefixer>fraction.js": true, + "autoprefixer>normalize-range": true, + "postcss>picocolors": true, + "postcss": true, + "stylelint>postcss-value-parser": true + } + }, + "stylelint>autoprefixer": { "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "console": true, + "process.cwd": true, + "process.env.AUTOPREFIXER_GRID": true }, "packages": { - "browserify>module-deps>readable-stream>isarray": true, - "browserify>module-deps>readable-stream>safe-buffer": true, - "browserify>module-deps>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "browserslist": true, + "autoprefixer>caniuse-lite": true, + "autoprefixer>normalize-range": true, + "stylelint>autoprefixer>num2fraction": true, + "stylelint>postcss>picocolors": true, + "stylelint>postcss-value-parser": true, + "stylelint>postcss": true } }, - "browserify>module-deps>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "@babel/preset-env>babel-plugin-polyfill-corejs2": { + "packages": { + "@babel/preset-env>@babel/compat-data": true, + "@babel/core": true, + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true, + "@babel/preset-env>babel-plugin-polyfill-corejs2>semver": true } }, - "browserify>module-deps>readable-stream>string_decoder": { + "@babel/preset-env>babel-plugin-polyfill-corejs3": { "packages": { - "browserify>module-deps>readable-stream>safe-buffer": true + "@babel/core": true, + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true, + "@babel/preset-env>core-js-compat": true } }, - "browserify>module-deps>stream-combiner2": { + "@babel/preset-env>babel-plugin-polyfill-regenerator": { "packages": { - "browserify>duplexer2": true, - "browserify>module-deps>stream-combiner2>readable-stream": true + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider": true } }, - "browserify>module-deps>stream-combiner2>readable-stream": { + "babelify": { "builtin": { - "events.EventEmitter": true, - "stream": true, + "path.extname": true, + "path.resolve": true, + "stream.PassThrough": true, + "stream.Transform": true, "util": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer.concat": true }, "packages": { - "browserify>module-deps>stream-combiner2>readable-stream>isarray": true, - "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": true, - "browserify>module-deps>stream-combiner2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "@babel/core": true } }, - "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": { + "gulp>undertaker>bach": { "builtin": { - "buffer": true - } - }, - "browserify>module-deps>stream-combiner2>readable-stream>string_decoder": { + "assert.ok": true + }, "packages": { - "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": true + "gulp>undertaker>bach>arr-filter": true, + "gulp>undertaker>arr-flatten": true, + "gulp>undertaker>arr-map": true, + "gulp>undertaker>bach>array-each": true, + "gulp>undertaker>bach>array-initial": true, + "gulp>undertaker>bach>array-last": true, + "gulp>glob-watcher>async-done": true, + "gulp>undertaker>bach>async-settle": true, + "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": true } }, - "browserify>module-deps>through2": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base": { "builtin": { "util.inherits": true }, - "globals": { - "process.nextTick": true - }, "packages": { - "browserify>module-deps>readable-stream": true, - "watchify>xtend": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>component-emitter": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>define-property": true, + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>pascalcase": true } }, - "browserify>parents": { - "globals": { - "process.cwd": true, - "process.platform": true + "bify-module-groups": { + "packages": { + "pify": true, + "pumpify>pump": true, + "bify-module-groups>through2": true + } + }, + "vinyl-buffer>bl": { + "builtin": { + "util.inherits": true }, "packages": { - "browserify>parents>path-platform": true + "vinyl-buffer>bl>readable-stream": true, + "koa>content-disposition>safe-buffer": true } }, - "browserify>parents>path-platform": { + "gulp-livereload>tiny-lr>body": { "builtin": { - "path": true, - "util.isObject": true, - "util.isString": true + "querystring.parse": true }, - "globals": { - "process.cwd": true, - "process.env": true, - "process.platform": true + "packages": { + "gulp-livereload>tiny-lr>body>continuable-cache": true, + "gulp-livereload>tiny-lr>body>error": true, + "gulp-livereload>tiny-lr>body>raw-body": true, + "gulp-livereload>tiny-lr>body>safe-json-parse": true } }, - "browserify>read-only-stream": { + "eslint>minimatch>brace-expansion": { "packages": { - "browserify>read-only-stream>readable-stream": true + "stylelint>balanced-match": true, + "eslint>minimatch>brace-expansion>concat-map": true } }, - "browserify>read-only-stream>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "chokidar>braces": { "packages": { - "browserify>read-only-stream>readable-stream>isarray": true, - "browserify>read-only-stream>readable-stream>safe-buffer": true, - "browserify>read-only-stream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "chokidar>braces>fill-range": true } }, - "browserify>read-only-stream>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp>glob-watcher>anymatch>micromatch>braces": { + "packages": { + "gulp>undertaker>arr-flatten": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, + "gulp>glob-watcher>anymatch>micromatch>braces>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range": true, + "gulp>gulp-cli>isobject": true, + "gulp-watch>anymatch>micromatch>braces>repeat-element": true, + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, + "gulp>gulp-cli>matchdep>micromatch>braces>split-string": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex": true } }, - "browserify>read-only-stream>readable-stream>string_decoder": { + "gulp-watch>anymatch>micromatch>braces": { "packages": { - "browserify>read-only-stream>readable-stream>safe-buffer": true + "gulp-watch>anymatch>micromatch>braces>expand-range": true, + "gulp-watch>anymatch>micromatch>braces>preserve": true, + "gulp-watch>anymatch>micromatch>braces>repeat-element": true } }, - "browserify>readable-stream": { + "browserify>browser-pack": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs.readFileSync": true, + "path.join": true, + "path.relative": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "__dirname": true, + "process.cwd": true }, "packages": { - "browserify>readable-stream>isarray": true, - "browserify>readable-stream>safe-buffer": true, - "browserify>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "browserify>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "browserify>readable-stream>string_decoder": { - "packages": { - "browserify>readable-stream>safe-buffer": true + "browserify>JSONStream": true, + "@lavamoat/lavapack>combine-source-map": true, + "watchify>defined": true, + "koa>content-disposition>safe-buffer": true, + "browserify>browser-pack>through2": true, + "@lavamoat/lavapack>umd": true } }, - "browserify>shasum-object": { + "browserify>browser-resolve": { "builtin": { - "crypto.createHash": true + "fs.readFile": true, + "fs.readFileSync": true, + "path": true }, "globals": { - "Buffer.isBuffer": true + "__dirname": true, + "process.platform": true }, "packages": { - "@metamask/rpc-errors>fast-safe-stringify": true - } - }, - "browserify>string_decoder": { - "packages": { - "koa>content-disposition>safe-buffer": true - } - }, - "browserify>syntax-error": { - "packages": { - "browserify>syntax-error>acorn-node": true - } - }, - "browserify>syntax-error>acorn-node": { - "packages": { - "@storybook/react>acorn-walk": true, - "browserify>syntax-error>acorn-node>acorn": true, - "watchify>xtend": true - } - }, - "browserify>syntax-error>acorn-node>acorn": { - "globals": { - "define": true + "depcheck>resolve": true } }, - "browserify>through2": { + "browserify": { "builtin": { - "util.inherits": true + "events.EventEmitter": true, + "fs.realpath": true, + "path.dirname": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true }, "globals": { - "process.nextTick": true + "__dirname": true, + "process.cwd": true, + "process.nextTick": true, + "process.platform": true }, "packages": { - "browserify>readable-stream": true, + "browserify>browser-pack": true, + "browserify>browser-resolve": true, + "browserify>cached-path-relative": true, + "browserify>concat-stream": true, + "watchify>defined": true, + "browserify>deps-sort": true, + "browserify>has": true, + "lavamoat>htmlescape": true, + "pumpify>inherits": true, + "browserify>insert-module-globals": true, + "labeled-stream-splicer": true, + "browserify>module-deps": true, + "browserify>read-only-stream": true, + "depcheck>resolve": true, + "browserify>shasum-object": true, + "browserify>syntax-error": true, + "browserify>through2": true, "watchify>xtend": true } }, @@ -1963,38 +1676,84 @@ "browserslist>node-releases": true } }, - "chalk": { - "packages": { - "chalk>ansi-styles": true, - "chalk>supports-color": true + "sass-embedded>buffer-builder": { + "globals": { + "Buffer": true } }, - "chalk>ansi-styles": { - "packages": { - "chalk>ansi-styles>color-convert": true + "gulp-zip>yazl>buffer-crc32": { + "builtin": { + "buffer.Buffer": true } }, - "chalk>ansi-styles>color-convert": { + "gulp>vinyl-fs>vinyl-sourcemap>append-buffer>buffer-equal": { + "builtin": { + "buffer.Buffer.isBuffer": true + } + }, + "terser>source-map-support>buffer-from": { + "globals": { + "Buffer": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base": { "packages": { - "jest-canvas-mock>moo-color>color-name": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>component-emitter": true, + "gulp>gulp-cli>array-sort>get-value": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value": true, + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>union-value": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value": true } }, - "chalk>supports-color": { + "browserify>cached-path-relative": { "builtin": { - "os.release": true, - "tty.isatty": true + "path": true }, "globals": { - "process.env": true, + "process.cwd": true + } + }, + "string.prototype.matchall>call-bind": { + "packages": { + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>call-bind>set-function-length": true + } + }, + "chalk": { + "packages": { + "chalk>ansi-styles": true, + "chalk>supports-color": true + } + }, + "gulp-livereload>chalk": { + "globals": { + "process.env.TERM": true, "process.platform": true }, "packages": { - "chalk>supports-color>has-flag": true + "gulp-livereload>chalk>ansi-styles": true, + "gulp-livereload>chalk>escape-string-regexp": true, + "gulp-livereload>chalk>supports-color": true } }, - "chalk>supports-color>has-flag": { + "postcss-discard-font-face>postcss>chalk": { "globals": { - "process.argv": true + "process.env.TERM": true, + "process.platform": true + }, + "packages": { + "postcss-discard-font-face>postcss>chalk>ansi-styles": true, + "postcss-discard-font-face>postcss>chalk>escape-string-regexp": true, + "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi": true, + "postcss-discard-font-face>postcss>chalk>strip-ansi": true, + "postcss-discard-font-face>postcss>chalk>supports-color": true } }, "chokidar": { @@ -2036,378 +1795,365 @@ "chokidar>anymatch": true, "chokidar>braces": true, "chokidar>fsevents": true, + "eslint>glob-parent": true, "chokidar>is-binary-path": true, - "chokidar>normalize-path": true, - "chokidar>readdirp": true, "del>is-glob": true, - "eslint>glob-parent": true + "chokidar>normalize-path": true, + "chokidar>readdirp": true } }, - "chokidar>anymatch": { + "gulp>glob-watcher>chokidar": { "packages": { - "chokidar>anymatch>normalize-path": true, - "chokidar>anymatch>picomatch": true + "gulp>glob-watcher>chokidar>fsevents": true } }, - "chokidar>anymatch>picomatch": { + "gulp-watch>chokidar": { "builtin": { + "events.EventEmitter": true, + "fs": true, "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, "path.sep": true }, "globals": { + "clearTimeout": true, + "console.error": true, + "process.env.CHOKIDAR_INTERVAL": true, + "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, + "process.env.CHOKIDAR_USEPOLLING": true, + "process.nextTick": true, "process.platform": true, - "process.version.slice": true - } - }, - "chokidar>braces": { + "setTimeout": true + }, "packages": { - "chokidar>braces>fill-range": true + "gulp-watch>chokidar>anymatch": true, + "gulp-watch>chokidar>async-each": true, + "gulp-watch>chokidar>braces": true, + "gulp-watch>chokidar>fsevents": true, + "gulp-watch>glob-parent": true, + "pumpify>inherits": true, + "gulp-watch>chokidar>is-binary-path": true, + "eslint>is-glob": true, + "chokidar>normalize-path": true, + "gulp-watch>path-is-absolute": true, + "gulp-watch>chokidar>readdirp": true, + "gulp-watch>chokidar>upath": true } }, - "chokidar>braces>fill-range": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils": { "builtin": { - "util.inspect": true + "util": true }, "packages": { - "chokidar>braces>fill-range>to-regex-range": true + "gulp-zip>plugin-error>arr-union": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true, + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend": true } }, - "chokidar>braces>fill-range>to-regex-range": { - "packages": { - "chokidar>braces>fill-range>to-regex-range>is-number": true + "del>p-map>aggregate-error>clean-stack": { + "builtin": { + "os.homedir": true } }, - "chokidar>fsevents": { + "yargs>cliui": { "globals": { - "console.assert": true, - "process.platform": true + "process": true }, - "native": true + "packages": { + "yargs>string-width": true, + "eslint>strip-ansi": true, + "yargs>cliui>wrap-ansi": true + } }, - "chokidar>is-binary-path": { + "vinyl>clone-buffer": { "builtin": { - "path.extname": true - }, + "buffer.Buffer": true + } + }, + "lavamoat>lavamoat-core>merge-deep>clone-deep": { "packages": { - "chokidar>is-binary-path>binary-extensions": true + "lavamoat>lavamoat-core>merge-deep>clone-deep>for-own": true, + "@babel/register>clone-deep>is-plain-object": true, + "lavamoat>lavamoat-core>merge-deep>kind-of": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep>lazy-cache": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone": true } }, - "chokidar>readdirp": { - "builtin": { - "fs": true, - "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true, - "stream.Readable": true, - "util.promisify": true - }, - "globals": { - "process.platform": true, - "process.versions.node.split": true - }, + "stylelint>execall>clone-regexp": { "packages": { - "chokidar>anymatch>picomatch": true + "stylelint>execall>clone-regexp>is-regexp": true } }, - "debounce-stream>duplexer": { + "vinyl>clone-stats": { "builtin": { - "stream": true + "fs.Stats": true } }, - "debounce-stream>through": { + "gulp-watch>vinyl-file>vinyl>clone-stats": { "builtin": { - "stream": true - }, - "globals": { - "process.nextTick": true + "fs.Stats": true } }, - "del": { - "builtin": { - "path.resolve": true, - "util.promisify": true - }, + "@metamask/jazzicon>color>clone": { "globals": { - "process.cwd": true, - "process.platform": true - }, - "packages": { - "del>graceful-fs": true, - "del>is-glob": true, - "del>is-path-cwd": true, - "del>is-path-inside": true, - "del>p-map": true, - "del>rimraf": true, - "del>slash": true, - "globby": true + "Buffer": true } }, - "del>graceful-fs": { - "builtin": { - "assert.equal": true, - "constants.O_SYMLINK": true, - "constants.O_WRONLY": true, - "constants.hasOwnProperty": true, - "fs": true, - "stream.Stream.call": true, - "util": true - }, + "vinyl>clone": { "globals": { - "clearTimeout": true, - "console.error": true, - "process": true, - "setTimeout": true + "Buffer": true } }, - "del>is-glob": { + "vinyl>cloneable-readable": { "packages": { - "del>is-glob>is-extglob": true + "pumpify>inherits": true, + "vinyl>cloneable-readable>process-nextick-args": true, + "vinyl>cloneable-readable>through2": true } }, - "del>is-path-cwd": { - "builtin": { - "path.resolve": true - }, - "globals": { - "process.cwd": true, - "process.platform": true + "gulp>undertaker>collection-map": { + "packages": { + "gulp>undertaker>arr-map": true, + "gulp>undertaker>object.reduce>for-own": true, + "gulp>undertaker>arr-map>make-iterator": true } }, - "del>is-path-inside": { - "builtin": { - "path.relative": true, - "path.resolve": true, - "path.sep": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>map-visit": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": true } }, - "del>p-map": { + "chalk>ansi-styles>color-convert": { "packages": { - "del>p-map>aggregate-error": true + "jest-canvas-mock>moo-color>color-name": true } }, - "del>p-map>aggregate-error": { + "gulp-livereload>chalk>ansi-styles>color-convert": { "packages": { - "del>p-map>aggregate-error>clean-stack": true, - "prettier-eslint>indent-string": true + "gulp-livereload>chalk>ansi-styles>color-convert>color-name": true } }, - "del>p-map>aggregate-error>clean-stack": { - "builtin": { - "os.homedir": true + "stylelint>table>slice-ansi>ansi-styles>color-convert": { + "packages": { + "stylelint>table>slice-ansi>ansi-styles>color-convert>color-name": true } }, - "del>rimraf": { + "fancy-log>color-support": { + "globals": { + "process": true + } + }, + "@lavamoat/lavapack>combine-source-map": { "builtin": { - "assert": true, - "fs": true, + "path.dirname": true, "path.join": true }, "globals": { - "process.platform": true, - "setTimeout": true + "process.platform": true }, "packages": { - "nyc>glob": true + "nyc>convert-source-map": true, + "@lavamoat/lavapack>combine-source-map>inline-source-map": true, + "@lavamoat/lavapack>combine-source-map>lodash.memoize": true, + "@lavamoat/lavapack>combine-source-map>source-map": true } }, - "depcheck>@babel/traverse": { + "browserify>concat-stream": { "globals": { - "console.log": true + "Buffer.concat": true, + "Buffer.isBuffer": true }, "packages": { - "@babel/code-frame": true, - "@babel/core>@babel/generator": true, - "@babel/core>@babel/parser": true, - "@babel/core>@babel/template": true, - "@babel/core>@babel/types": true, - "babel/preset-env>b@babel/types": true, - "depcheck>@babel/traverse>globals": true, - "nock>debug": true + "terser>source-map-support>buffer-from": true, + "pumpify>inherits": true, + "browserify>concat-stream>readable-stream": true, + "browserify>concat-stream>typedarray": true } }, - "depcheck>cosmiconfig>parse-json": { + "lavamoat-browserify>concat-stream": { + "globals": { + "Buffer.concat": true, + "Buffer.isBuffer": true + }, "packages": { - "@babel/code-frame": true, - "depcheck>cosmiconfig>parse-json>error-ex": true, - "depcheck>cosmiconfig>parse-json>lines-and-columns": true, - "webpack>json-parse-even-better-errors": true + "terser>source-map-support>buffer-from": true, + "pumpify>inherits": true, + "lavamoat-browserify>concat-stream>readable-stream": true, + "browserify>concat-stream>typedarray": true } }, - "depcheck>cosmiconfig>parse-json>error-ex": { + "@babel/core>convert-source-map": { + "globals": { + "Buffer": true, + "atob": true, + "btoa": true, + "value": true + } + }, + "nyc>convert-source-map": { "builtin": { - "util.inherits": true + "fs.readFileSync": true, + "path.join": true }, - "packages": { - "depcheck>cosmiconfig>parse-json>error-ex>is-arrayish": true + "globals": { + "Buffer.from": true } }, - "depcheck>is-core-module": { + "readable-stream-2>core-util-is": { "globals": { - "process.versions": true - }, - "packages": { - "depcheck>is-core-module>hasown": true + "Buffer.isBuffer": true } }, - "depcheck>is-core-module>hasown": { + "stylelint>cosmiconfig": { + "builtin": { + "fs": true, + "os": true, + "path": true + }, + "globals": { + "process.cwd": true + }, "packages": { - "browserify>has>function-bind": true + "eslint>@eslint/eslintrc>import-fresh": true, + "depcheck>cosmiconfig>parse-json": true, + "globby>dir-glob>path-type": true, + "stylelint>cosmiconfig>yaml": true } }, - "depcheck>json5": { + "ts-node>create-require": { + "builtin": { + "fs.lstatSync": true, + "module.Module": true, + "module.createRequire": true, + "module.createRequireFromPath": true, + "path.dirname": true, + "path.join": true + }, "globals": { - "console.warn": true + "process.cwd": true } }, - "depcheck>resolve": { + "gulp-sourcemaps>css": { "builtin": { - "fs.readFile": true, "fs.readFileSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "os.homedir": true, "path.dirname": true, - "path.join": true, - "path.parse": true, - "path.relative": true, - "path.resolve": true - }, - "globals": { - "process.env.HOME": true, - "process.env.HOMEDRIVE": true, - "process.env.HOMEPATH": true, - "process.env.LNAME": true, - "process.env.LOGNAME": true, - "process.env.USER": true, - "process.env.USERNAME": true, - "process.env.USERPROFILE": true, - "process.getuid": true, - "process.nextTick": true, - "process.platform": true, - "process.versions.pnp": true + "path.sep": true }, "packages": { - "depcheck>is-core-module": true, - "depcheck>resolve>path-parse": true + "pumpify>inherits": true, + "gulp-sourcemaps>css>source-map-resolve": true, + "gulp-sourcemaps>css>source-map": true } }, - "depcheck>resolve>path-parse": { + "resolve-url-loader>es6-iterator>d": { + "packages": { + "resolve-url-loader>es6-iterator>es5-ext": true, + "resolve-url-loader>es6-iterator>d>type": true + } + }, + "gulp-sourcemaps>debug-fabulous": { + "packages": { + "gulp-sourcemaps>debug-fabulous>debug": true, + "gulp-sourcemaps>debug-fabulous>memoizee": true, + "react>object-assign": true + } + }, + "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug": { "globals": { - "process.platform": true + "console.debug": true, + "console.log": true + }, + "packages": { + "@typescript-eslint/eslint-plugin>@typescript-eslint/type-utils>debug>ms": true } }, - "duplexify": { + "gulp-sourcemaps>debug-fabulous>debug": { + "builtin": { + "tty.isatty": true, + "util": true + }, "globals": { - "Buffer": true, - "process.nextTick": true + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "duplexify>end-of-stream": true, - "duplexify>stream-shift": true, - "pumpify>inherits": true, - "readable-stream": true + "mocha>ms": true, + "mocha>supports-color": true } }, - "duplexify>end-of-stream": { + "eslint-import-resolver-node>debug": { + "builtin": { + "tty.isatty": true, + "util": true + }, "globals": { - "process.nextTick": true + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "@metamask/object-multiplex>once": true + "mocha>ms": true, + "mocha>supports-color": true } }, - "eslint": { + "eslint-plugin-import>eslint-module-utils>debug": { "builtin": { - "assert": true, - "fs.existsSync": true, - "fs.lstatSync": true, - "fs.promises": true, - "fs.readFileSync": true, - "fs.readdirSync": true, - "fs.statSync": true, - "fs.unlinkSync": true, - "fs.writeFile": true, - "fs.writeFileSync": true, - "path.dirname": true, - "path.extname": true, - "path.isAbsolute": true, - "path.join": true, - "path.normalize": true, - "path.posix.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true, - "url.pathToFileURL": true, - "util.format": true, - "util.inspect": true, - "util.promisify": true + "tty.isatty": true, + "util": true }, "globals": { - "__dirname": true, - "console.log": true, - "describe": true, - "it": true, + "console": true, + "document": true, + "localStorage": true, + "navigator": true, "process": true }, "packages": { - "del>is-glob": true, - "del>is-path-inside": true, - "eslint>@eslint-community/eslint-utils": true, - "eslint>@eslint-community/regexpp": true, - "eslint>@eslint/eslintrc": true, - "eslint>@eslint/js": true, - "eslint>@humanwhocodes/config-array": true, - "eslint>@nodelib/fs.walk": true, - "eslint>@ungap/structured-clone": true, - "eslint>ajv": true, - "eslint>doctrine": true, - "eslint>eslint-scope": true, - "eslint>eslint-visitor-keys": true, - "eslint>espree": true, - "eslint>esquery": true, - "eslint>esutils": true, - "eslint>fast-deep-equal": true, - "eslint>file-entry-cache": true, - "eslint>glob-parent": true, - "eslint>globals": true, - "eslint>graphemer": true, - "eslint>ignore": true, - "eslint>imurmurhash": true, - "eslint>json-stable-stringify-without-jsonify": true, - "eslint>levn": true, - "eslint>lodash.merge": true, - "eslint>minimatch": true, - "eslint>natural-compare": true, - "mocha>escape-string-regexp": true, - "mocha>find-up": true, - "nock>debug": true - } - }, - "eslint-config-prettier": { - "globals": { - "process.env.ESLINT_CONFIG_PRETTIER_NO_DEPRECATED": true + "mocha>ms": true, + "mocha>supports-color": true } }, - "eslint-import-resolver-node": { + "eslint-plugin-import>debug": { "builtin": { - "path.dirname": true, - "path.join": true, - "path.resolve": true + "fs.SyncWriteStream": true, + "net.Socket": true, + "tty.WriteStream": true, + "tty.isatty": true, + "util": true + }, + "globals": { + "chrome": true, + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "depcheck>resolve": true, - "eslint-import-resolver-node>debug": true + "eslint-plugin-import>debug>ms": true } }, - "eslint-import-resolver-node>debug": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": { "builtin": { + "fs.SyncWriteStream": true, + "net.Socket": true, + "tty.WriteStream": true, "tty.isatty": true, "util": true }, "globals": { + "chrome": true, "console": true, "document": true, "localStorage": true, @@ -2415,61 +2161,46 @@ "process": true }, "packages": { - "mocha>ms": true, - "mocha>supports-color": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug>ms": true } }, - "eslint-import-resolver-typescript": { + "gulp-livereload>debug": { "builtin": { - "path": true + "tty.isatty": true, + "util": true }, "globals": { - "console.warn": true, - "process.cwd": true + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "del>is-glob": true, - "depcheck>resolve": true, - "eslint-plugin-import>tsconfig-paths": true, - "nock>debug": true, - "nyc>glob": true + "mocha>ms": true, + "gulp-livereload>chalk>supports-color": true } }, - "eslint-plugin-import": { + "nock>debug": { "builtin": { - "fs": true, - "path": true, - "vm": true + "tty.isatty": true, + "util.deprecate": true, + "util.formatWithOptions": true, + "util.inspect": true }, "globals": { - "process.cwd": true, - "process.env": true + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "browserify>has": true, - "del>is-glob": true, - "depcheck>is-core-module": true, - "eslint": true, - "eslint-plugin-import>array.prototype.flat": true, - "eslint-plugin-import>debug": true, - "eslint-plugin-import>doctrine": true, - "eslint-plugin-import>eslint-module-utils": true, - "eslint-plugin-import>tsconfig-paths": true, - "eslint-plugin-react>array-includes": true, - "eslint-plugin-react>object.values": true, - "eslint>minimatch": true, - "typescript": true - } - }, - "eslint-plugin-import>array.prototype.flat": { - "packages": { - "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true + "nock>debug>ms": true, + "mocha>supports-color": true } }, - "eslint-plugin-import>debug": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug": { "builtin": { "fs.SyncWriteStream": true, "net.Socket": true, @@ -2486,44 +2217,10 @@ "process": true }, "packages": { - "eslint-plugin-import>debug>ms": true - } - }, - "eslint-plugin-import>doctrine": { - "builtin": { - "assert": true - }, - "packages": { - "eslint>esutils": true - } - }, - "eslint-plugin-import>eslint-module-utils": { - "builtin": { - "crypto.createHash": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.readdirSync": true, - "module": true, - "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.parse": true, - "path.resolve": true - }, - "globals": { - "__dirname.toUpperCase": true, - "console.warn": true, - "process.cwd": true, - "process.hrtime": true - }, - "packages": { - "@babel/eslint-parser": true, - "eslint-import-resolver-node": true, - "eslint-plugin-import>eslint-module-utils>debug": true, - "eslint-plugin-import>eslint-module-utils>find-up": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug>ms": true } }, - "eslint-plugin-import>eslint-module-utils>debug": { + "gulp-livereload>tiny-lr>debug": { "builtin": { "tty.isatty": true, "util": true @@ -2540,902 +2237,666 @@ "mocha>supports-color": true } }, - "eslint-plugin-import>eslint-module-utils>find-up": { - "builtin": { - "path.dirname": true, - "path.join": true, - "path.parse": true, - "path.resolve": true - }, + "gulp>undertaker>last-run>default-resolution": { + "globals": { + "process.version.match": true + } + }, + "string.prototype.matchall>define-properties>define-data-property": { "packages": { - "eslint-plugin-import>eslint-module-utils>find-up>locate-path": true + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>gopd": true } }, - "eslint-plugin-import>eslint-module-utils>find-up>locate-path": { - "builtin": { - "path.resolve": true - }, - "globals": { - "process.cwd": true - }, + "string.prototype.matchall>define-properties": { "packages": { - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate": true, - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>path-exists": true + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>define-property": { "packages": { - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": { "packages": { - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit>p-try": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": true } }, - "eslint-plugin-import>eslint-module-utils>find-up>locate-path>path-exists": { - "builtin": { - "fs.access": true, - "fs.accessSync": true + "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "eslint-plugin-import>tsconfig-paths": { - "builtin": { - "fs.existsSync": true, - "fs.lstatSync": true, - "fs.readFile": true, - "fs.readFileSync": true, - "fs.stat": true, - "fs.statSync": true, - "module._resolveFilename": true, - "module.builtinModules": true, - "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "path.resolve": true - }, - "globals": { - "console.warn": true, - "process.argv.slice": true, - "process.cwd": true, - "process.env": true - }, + "gulp>glob-watcher>anymatch>micromatch>define-property": { "packages": { - "eslint-plugin-import>tsconfig-paths>json5": true, - "eslint-plugin-import>tsconfig-paths>strip-bom": true, - "wait-on>minimist": true - } - }, - "eslint-plugin-import>tsconfig-paths>json5": { - "globals": { - "console.warn": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true, + "gulp>gulp-cli>isobject": true } }, - "eslint-plugin-jest": { - "builtin": { - "fs.readdirSync": true, - "path.join": true, - "path.parse": true - }, - "globals": { - "__dirname": true - }, + "gulp>gulp-cli>matchdep>micromatch>nanomatch>define-property": { "packages": { - "@typescript-eslint/eslint-plugin": true, - "eslint-plugin-jest>@typescript-eslint/utils": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true, + "gulp>gulp-cli>isobject": true } }, - "eslint-plugin-jest>@typescript-eslint/experimental-utils": { - "builtin": { - "path": true - }, + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>define-property": { "packages": { - "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, - "@typescript-eslint/parser>@typescript-eslint/types": true, - "eslint": true, - "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, - "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils": true, - "eslint>eslint-scope": true, - "eslint>eslint-utils": true, - "webpack>eslint-scope": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": { "packages": { - "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils>eslint-visitor-keys": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor": true } }, - "eslint-plugin-jest>@typescript-eslint/utils": { - "builtin": { - "assert": true, - "path": true - }, + "gulp>gulp-cli>matchdep>micromatch>to-regex>define-property": { "packages": { - "@typescript-eslint/parser>@typescript-eslint/scope-manager": true, - "@typescript-eslint/parser>@typescript-eslint/types": true, - "eslint": true, - "eslint-plugin-jest>@typescript-eslint/experimental-utils>@typescript-eslint/types": true, - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": true, - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true, - "eslint-plugin-jest>@typescript-eslint/utils>webpack>eslint-scope": true, - "eslint-plugin-mocha>eslint-utils": true, - "eslint>@eslint-community/eslint-utils": true, - "eslint>eslint-scope": true, - "eslint>eslint-utils": true, - "semver": true, - "webpack>eslint-scope": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true, + "gulp>gulp-cli>isobject": true } }, - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager": { + "del": { "builtin": { - "path": true + "path.resolve": true, + "util.promisify": true }, - "packages": { - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager>@typescript-eslint/visitor-keys": true, - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/types": true - } - }, - "eslint-plugin-jest>@typescript-eslint/utils>@typescript-eslint/scope-manager>@typescript-eslint/visitor-keys": { - "builtin": { - "path": true + "globals": { + "process.cwd": true, + "process.platform": true }, "packages": { - "eslint>eslint-visitor-keys": true - } - }, - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": { - "packages": { - "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true, - "eslint>@eslint-community/eslint-utils": true, - "semver": true - } - }, - "eslint-plugin-jsdoc": { - "packages": { - "eslint": true, - "eslint-plugin-jsdoc>@es-joy/jsdoccomment": true, - "eslint-plugin-jsdoc>are-docs-informative": true, - "eslint-plugin-jsdoc>comment-parser": true, - "eslint-plugin-jsdoc>spdx-expression-parse": true, - "eslint>esquery": true, - "mocha>escape-string-regexp": true, - "nock>debug": true, - "semver": true + "globby": true, + "del>graceful-fs": true, + "del>is-glob": true, + "del>is-path-cwd": true, + "del>is-path-inside": true, + "del>p-map": true, + "del>rimraf": true, + "del>slash": true } }, - "eslint-plugin-jsdoc>@es-joy/jsdoccomment": { + "browserify>deps-sort": { "packages": { - "eslint-plugin-jsdoc>@es-joy/jsdoccomment>jsdoc-type-pratt-parser": true, - "eslint-plugin-jsdoc>comment-parser": true, - "eslint>esquery": true + "browserify>shasum-object": true, + "browserify>deps-sort>through2": true } }, - "eslint-plugin-jsdoc>@es-joy/jsdoccomment>jsdoc-type-pratt-parser": { + "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": { + "builtin": { + "child_process.spawnSync": true, + "fs.readdirSync": true, + "os.platform": true + }, "globals": { - "define": true + "process.env": true } }, - "eslint-plugin-jsdoc>spdx-expression-parse": { + "browserify>module-deps>detective": { "packages": { - "eslint-plugin-jsdoc>spdx-expression-parse>spdx-exceptions": true, - "eslint-plugin-jsdoc>spdx-expression-parse>spdx-license-ids": true + "browserify>syntax-error>acorn-node": true, + "watchify>defined": true } }, - "eslint-plugin-mocha>eslint-utils": { - "packages": { - "eslint-plugin-mocha>eslint-utils>eslint-visitor-keys": true + "ts-node>diff": { + "globals": { + "setTimeout": true } }, - "eslint-plugin-node": { + "globby>dir-glob": { "builtin": { - "fs.readFileSync": true, - "fs.readdirSync": true, - "fs.statSync": true, - "path.basename": true, - "path.dirname": true, "path.extname": true, "path.isAbsolute": true, "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true + "path.posix.join": true }, "globals": { "process.cwd": true }, "packages": { - "depcheck>resolve": true, - "eslint-plugin-node>eslint-plugin-es": true, - "eslint-plugin-node>eslint-utils": true, - "eslint-plugin-node>semver": true, - "eslint>ignore": true, - "eslint>minimatch": true - } - }, - "eslint-plugin-node>eslint-plugin-es": { - "packages": { - "eslint-plugin-node>eslint-plugin-es>regexpp": true, - "eslint-plugin-node>eslint-utils": true - } - }, - "eslint-plugin-node>eslint-utils": { - "packages": { - "eslint-plugin-node>eslint-utils>eslint-visitor-keys": true - } - }, - "eslint-plugin-node>semver": { - "globals": { - "console": true, - "process": true + "globby>dir-glob>path-type": true } }, - "eslint-plugin-prettier": { + "eslint>doctrine": { + "builtin": { + "assert": true + }, "packages": { - "eslint-plugin-prettier>prettier-linter-helpers": true, - "prettier": true + "eslint>esutils": true } }, - "eslint-plugin-prettier>prettier-linter-helpers": { + "eslint-plugin-import>doctrine": { + "builtin": { + "assert": true + }, "packages": { - "eslint-plugin-prettier>prettier-linter-helpers>fast-diff": true + "eslint>esutils": true } }, - "eslint-plugin-react": { + "eslint-plugin-react>doctrine": { "builtin": { - "fs.statSync": true, - "path.dirname": true, - "path.extname": true - }, - "globals": { - "console.error": true, - "console.log": true, - "process.argv.join": true, - "process.cwd": true + "assert": true }, "packages": { - "eslint": true, - "eslint-plugin-react>array-includes": true, - "eslint-plugin-react>array.prototype.flatmap": true, - "eslint-plugin-react>doctrine": true, - "eslint-plugin-react>estraverse": true, - "eslint-plugin-react>jsx-ast-utils": true, - "eslint-plugin-react>object.entries": true, - "eslint-plugin-react>object.fromentries": true, - "eslint-plugin-react>object.hasown": true, - "eslint-plugin-react>object.values": true, - "eslint-plugin-react>resolve": true, - "eslint-plugin-react>semver": true, - "eslint>minimatch": true, - "prop-types": true, - "string.prototype.matchall": true - } - }, - "eslint-plugin-react-hooks": { - "globals": { - "process.env.NODE_ENV": true + "eslint>esutils": true } }, - "eslint-plugin-react>array-includes": { + "stylelint>postcss-html>htmlparser2>domutils>dom-serializer": { "packages": { - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, - "string.prototype.matchall>get-intrinsic": true + "stylelint>postcss-html>htmlparser2>domelementtype": true, + "stylelint>postcss-html>htmlparser2>entities": true } }, - "eslint-plugin-react>array-includes>is-string": { + "stylelint>postcss-html>htmlparser2>domhandler": { "packages": { - "koa>is-generator-function>has-tostringtag": true + "stylelint>postcss-html>htmlparser2>domelementtype": true } }, - "eslint-plugin-react>array.prototype.flatmap": { + "stylelint>postcss-html>htmlparser2>domutils": { "packages": { - "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true + "stylelint>postcss-html>htmlparser2>domutils>dom-serializer": true, + "stylelint>postcss-html>htmlparser2>domelementtype": true } }, - "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": { + "browserify>duplexer2": { "packages": { - "browserify>has": true + "browserify>duplexer2>readable-stream": true } }, - "eslint-plugin-react>doctrine": { + "debounce-stream>duplexer": { "builtin": { - "assert": true - }, - "packages": { - "eslint>esutils": true + "stream": true } }, - "eslint-plugin-react>jsx-ast-utils": { + "duplexify": { "globals": { - "console.error": true + "Buffer": true, + "process.nextTick": true }, "packages": { - "gulp>vinyl-fs>object.assign": true + "duplexify>end-of-stream": true, + "pumpify>inherits": true, + "readable-stream": true, + "duplexify>stream-shift": true } }, - "eslint-plugin-react>object.entries": { + "gulp>vinyl-fs>glob-stream>pumpify>duplexify": { + "globals": { + "Buffer": true, + "process.nextTick": true + }, "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true + "duplexify>end-of-stream": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>glob-stream>readable-stream": true, + "duplexify>stream-shift": true } }, - "eslint-plugin-react>object.fromentries": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true - } - }, - "eslint-plugin-react>object.hasown": { - "packages": { - "string.prototype.matchall>es-abstract": true - } - }, - "eslint-plugin-react>resolve": { - "builtin": { - "fs.readFile": true, - "fs.readFileSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "os.homedir": true, - "path.dirname": true, - "path.join": true, - "path.parse": true, - "path.relative": true, - "path.resolve": true - }, + "gulp>vinyl-fs>pumpify>duplexify": { "globals": { - "process.env.HOME": true, - "process.env.HOMEDRIVE": true, - "process.env.HOMEPATH": true, - "process.env.LNAME": true, - "process.env.LOGNAME": true, - "process.env.USER": true, - "process.env.USERNAME": true, - "process.env.USERPROFILE": true, - "process.getuid": true, - "process.nextTick": true, - "process.platform": true, - "process.versions.pnp": true + "Buffer": true, + "process.nextTick": true }, "packages": { - "depcheck>is-core-module": true, - "depcheck>resolve>path-parse": true - } - }, - "eslint-plugin-react>semver": { - "globals": { - "console": true, - "process": true - } - }, - "eslint>@eslint-community/eslint-utils": { - "packages": { - "eslint>eslint-visitor-keys": true + "duplexify>end-of-stream": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>readable-stream": true, + "duplexify>stream-shift": true } }, - "eslint>@eslint/eslintrc": { - "builtin": { - "assert": true, - "fs": true, - "module": true, - "os": true, - "path": true, - "url": true, - "util": true - }, + "duplexify>end-of-stream": { "globals": { - "__filename": true, - "process.cwd": true, - "process.emitWarning": true, - "process.platform": true + "process.nextTick": true }, "packages": { - "$root$": true, - "@babel/eslint-parser": true, - "@babel/eslint-plugin": true, - "@metamask/eslint-config": true, - "@metamask/eslint-config-nodejs": true, - "@metamask/eslint-config-typescript": true, - "@typescript-eslint/eslint-plugin": true, - "eslint": true, - "eslint-config-prettier": true, - "eslint-plugin-import": true, - "eslint-plugin-jsdoc": true, - "eslint-plugin-node": true, - "eslint-plugin-prettier": true, - "eslint-plugin-react": true, - "eslint-plugin-react-hooks": true, - "eslint>ajv": true, - "eslint>globals": true, - "eslint>ignore": true, - "eslint>minimatch": true, - "mocha>strip-json-comments": true, - "nock>debug": true + "@metamask/object-multiplex>once": true } }, - "eslint>@eslint/eslintrc>import-fresh": { + "depcheck>cosmiconfig>parse-json>error-ex": { "builtin": { - "path.dirname": true - }, - "globals": { - "__dirname": true, - "__filename": true + "util.inherits": true }, "packages": { - "eslint>@eslint/eslintrc>import-fresh>parent-module": true, - "eslint>@eslint/eslintrc>import-fresh>resolve-from": true - } - }, - "eslint>@eslint/eslintrc>import-fresh>parent-module": { - "packages": { - "@metamask/test-bundler>ow>callsites": true - } - }, - "eslint>@eslint/eslintrc>import-fresh>resolve-from": { - "builtin": { - "fs.realpathSync": true, - "module._nodeModulePaths": true, - "module._resolveFilename": true, - "path.join": true, - "path.resolve": true + "depcheck>cosmiconfig>parse-json>error-ex>is-arrayish": true } }, - "eslint>@humanwhocodes/config-array": { + "gulp-livereload>tiny-lr>body>error": { "builtin": { - "path.dirname": true, - "path.join": true, - "path.relative": true + "assert": true }, "packages": { - "eslint>@humanwhocodes/config-array>@humanwhocodes/object-schema": true, - "eslint>minimatch": true, - "nock>debug": true + "gulp-livereload>tiny-lr>body>error>string-template": true, + "watchify>xtend": true } }, - "eslint>@nodelib/fs.walk": { - "builtin": { - "events.EventEmitter": true, - "path.sep": true, - "stream.Readable": true - }, - "globals": { - "setImmediate": true - }, + "string.prototype.matchall>es-abstract": { "packages": { - "eslint>@nodelib/fs.walk>@nodelib/fs.scandir": true, - "eslint>@nodelib/fs.walk>fastq": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>call-bind>es-define-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>es-object-atoms": true, + "string.prototype.matchall>es-abstract>es-set-tostringtag": true, + "string.prototype.matchall>es-abstract>es-to-primitive": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>internal-slot": true, + "string.prototype.matchall>es-abstract>is-callable": true, + "string.prototype.matchall>es-abstract>is-regex": true, + "eslint-plugin-react>array-includes>is-string": true, + "string.prototype.matchall>es-abstract>object-inspect": true, + "string.prototype.matchall>es-abstract>safe-regex-test": true, + "string.prototype.matchall>es-abstract>string.prototype.trim": true } }, - "eslint>@nodelib/fs.walk>@nodelib/fs.scandir": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, - "fs.readdirSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.sep": true - }, - "globals": { - "process.versions.node": true - }, + "string.prototype.matchall>call-bind>es-define-property": { "packages": { - "eslint>@nodelib/fs.walk>@nodelib/fs.scandir>run-parallel": true, - "fast-glob>@nodelib/fs.stat": true - } - }, - "eslint>@nodelib/fs.walk>@nodelib/fs.scandir>run-parallel": { - "globals": { - "process.nextTick": true + "string.prototype.matchall>get-intrinsic": true } }, - "eslint>@nodelib/fs.walk>fastq": { + "string.prototype.matchall>es-abstract>es-object-atoms": { "packages": { - "eslint>@nodelib/fs.walk>fastq>reusify": true - } - }, - "eslint>@ungap/structured-clone": { - "globals": { - "structuredClone": true + "string.prototype.matchall>call-bind>es-errors": true } }, - "eslint>ajv": { - "globals": { - "console": true - }, + "string.prototype.matchall>es-abstract>es-set-tostringtag": { "packages": { - "@metamask/snaps-utils>fast-json-stable-stringify": true, - "eslint>ajv>json-schema-traverse": true, - "eslint>fast-deep-equal": true, - "uri-js": true + "string.prototype.matchall>get-intrinsic": true, + "koa>is-generator-function>has-tostringtag": true, + "depcheck>is-core-module>hasown": true } }, - "eslint>doctrine": { - "builtin": { - "assert": true - }, + "eslint-plugin-react>array.prototype.flatmap>es-shim-unscopables": { "packages": { - "eslint>esutils": true + "browserify>has": true } }, - "eslint>eslint-scope": { - "builtin": { - "assert": true - }, + "string.prototype.matchall>es-abstract>es-to-primitive": { "packages": { - "eslint-plugin-react>estraverse": true, - "eslint>eslint-scope>esrecurse": true + "string.prototype.matchall>es-abstract>is-callable": true, + "@metamask/eth-token-tracker>deep-equal>is-date-object": true, + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true } }, - "eslint>eslint-scope>esrecurse": { + "resolve-url-loader>es6-iterator>es5-ext": { "packages": { - "eslint-plugin-react>estraverse": true + "resolve-url-loader>es6-iterator>es6-symbol": true } }, - "eslint>espree": { + "resolve-url-loader>es6-iterator": { "packages": { - "eslint>eslint-visitor-keys": true, - "eslint>espree>acorn-jsx": true, - "jsdom>acorn": true + "resolve-url-loader>es6-iterator>d": true, + "resolve-url-loader>es6-iterator>es5-ext": true, + "resolve-url-loader>es6-iterator>es6-symbol": true } }, - "eslint>espree>acorn-jsx": { + "resolve-url-loader>es6-iterator>es6-symbol": { "packages": { - "jsdom>acorn": true + "resolve-url-loader>es6-iterator>d": true, + "resolve-url-loader>es6-iterator>es6-symbol>ext": true } }, - "eslint>esquery": { - "globals": { - "define": true + "gulp>undertaker>es6-weak-map": { + "packages": { + "resolve-url-loader>es6-iterator>d": true, + "resolve-url-loader>es6-iterator>es5-ext": true, + "resolve-url-loader>es6-iterator": true, + "resolve-url-loader>es6-iterator>es6-symbol": true } }, - "eslint>file-entry-cache": { + "yargs>escalade": { "builtin": { - "crypto.createHash": true, - "fs.readFileSync": true, + "fs.readdirSync": true, "fs.statSync": true, - "path.basename": true, - "path.dirname": true - }, - "packages": { - "eslint>file-entry-cache>flat-cache": true + "path.dirname": true, + "path.resolve": true } }, - "eslint>file-entry-cache>flat-cache": { + "eslint": { "builtin": { + "assert": true, "fs.existsSync": true, - "fs.mkdirSync": true, - "fs.readFileSync": true, + "fs.lstatSync": true, + "fs.promises": true, + "fs.readFileSync": true, + "fs.readdirSync": true, + "fs.statSync": true, + "fs.unlinkSync": true, + "fs.writeFile": true, "fs.writeFileSync": true, - "path.basename": true, "path.dirname": true, - "path.resolve": true + "path.extname": true, + "path.isAbsolute": true, + "path.join": true, + "path.normalize": true, + "path.posix.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true, + "url.pathToFileURL": true, + "util.format": true, + "util.inspect": true, + "util.promisify": true }, "globals": { - "__dirname": true - }, - "packages": { - "del>rimraf": true, - "eslint>file-entry-cache>flat-cache>flatted": true - } - }, - "eslint>glob-parent": { - "builtin": { - "os.platform": true, - "path.posix.dirname": true + "__dirname": true, + "console.log": true, + "describe": true, + "it": true, + "process": true }, "packages": { - "del>is-glob": true + "eslint>@eslint-community/eslint-utils": true, + "eslint>@eslint-community/regexpp": true, + "eslint>@eslint/eslintrc": true, + "eslint>@eslint/js": true, + "eslint>@humanwhocodes/config-array": true, + "eslint>@nodelib/fs.walk": true, + "eslint>@ungap/structured-clone": true, + "eslint>ajv": true, + "nock>debug": true, + "eslint>doctrine": true, + "mocha>escape-string-regexp": true, + "eslint>eslint-scope": true, + "eslint>eslint-visitor-keys": true, + "eslint>espree": true, + "eslint>esquery": true, + "eslint>esutils": true, + "eslint>fast-deep-equal": true, + "eslint>file-entry-cache": true, + "mocha>find-up": true, + "eslint>glob-parent": true, + "eslint>globals": true, + "eslint>graphemer": true, + "eslint>ignore": true, + "eslint>imurmurhash": true, + "del>is-glob": true, + "del>is-path-inside": true, + "eslint>json-stable-stringify-without-jsonify": true, + "eslint>levn": true, + "eslint>lodash.merge": true, + "eslint>minimatch": true, + "eslint>natural-compare": true } }, - "eslint>ignore": { + "eslint-config-prettier": { "globals": { - "process": true - } - }, - "eslint>levn": { - "packages": { - "eslint>levn>prelude-ls": true, - "eslint>levn>type-check": true + "process.env.ESLINT_CONFIG_PRETTIER_NO_DEPRECATED": true } }, - "eslint>levn>type-check": { + "eslint-import-resolver-node": { + "builtin": { + "path.dirname": true, + "path.join": true, + "path.resolve": true + }, "packages": { - "eslint>levn>prelude-ls": true + "eslint-import-resolver-node>debug": true, + "depcheck>resolve": true } }, - "eslint>minimatch": { + "eslint-import-resolver-typescript": { "builtin": { "path": true }, "globals": { - "console": true + "console.warn": true, + "process.cwd": true }, "packages": { - "eslint>minimatch>brace-expansion": true + "nock>debug": true, + "nyc>glob": true, + "del>is-glob": true, + "depcheck>resolve": true, + "eslint-plugin-import>tsconfig-paths": true } }, - "eslint>minimatch>brace-expansion": { + "eslint-plugin-import>eslint-module-utils": { + "builtin": { + "crypto.createHash": true, + "fs.existsSync": true, + "fs.readFileSync": true, + "fs.readdirSync": true, + "module": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.parse": true, + "path.resolve": true + }, + "globals": { + "__dirname.toUpperCase": true, + "console.warn": true, + "process.cwd": true, + "process.hrtime": true + }, "packages": { - "eslint>minimatch>brace-expansion>concat-map": true, - "stylelint>balanced-match": true + "@babel/eslint-parser": true, + "eslint-plugin-import>eslint-module-utils>debug": true, + "eslint-import-resolver-node": true, + "eslint-plugin-import>eslint-module-utils>find-up": true } }, - "eslint>strip-ansi": { + "eslint-plugin-node>eslint-plugin-es": { "packages": { - "eslint>strip-ansi>ansi-regex": true + "eslint-plugin-node>eslint-utils": true, + "eslint-plugin-node>eslint-plugin-es>regexpp": true } }, - "eta": { + "eslint-plugin-import": { "builtin": { - "node:fs": true, - "node:path": true + "fs": true, + "path": true, + "vm": true }, "globals": { - "define": true + "process.cwd": true, + "process.env": true + }, + "packages": { + "eslint-plugin-react>array-includes": true, + "eslint-plugin-import>array.prototype.flat": true, + "eslint-plugin-import>debug": true, + "eslint-plugin-import>doctrine": true, + "eslint": true, + "eslint-plugin-import>eslint-module-utils": true, + "browserify>has": true, + "depcheck>is-core-module": true, + "del>is-glob": true, + "eslint>minimatch": true, + "eslint-plugin-react>object.values": true, + "eslint-plugin-import>tsconfig-paths": true, + "typescript": true } }, - "fancy-log": { + "eslint-plugin-jest": { "builtin": { - "console.Console": true + "fs.readdirSync": true, + "path.join": true, + "path.parse": true }, "globals": { - "process.argv.indexOf": true, - "process.platform": true, - "process.stderr": true, - "process.stdout": true, - "process.version": true + "__dirname": true }, "packages": { - "fancy-log>ansi-gray": true, - "fancy-log>color-support": true, - "fancy-log>parse-node-version": true, - "fancy-log>time-stamp": true + "@typescript-eslint/eslint-plugin": true, + "eslint-plugin-jest>@typescript-eslint/utils": true } }, - "fancy-log>ansi-gray": { + "eslint-plugin-jsdoc": { "packages": { - "fancy-log>ansi-gray>ansi-wrap": true - } - }, - "fancy-log>color-support": { - "globals": { - "process": true + "eslint-plugin-jsdoc>@es-joy/jsdoccomment": true, + "eslint-plugin-jsdoc>are-docs-informative": true, + "eslint-plugin-jsdoc>comment-parser": true, + "nock>debug": true, + "mocha>escape-string-regexp": true, + "eslint": true, + "eslint>esquery": true, + "semver": true, + "eslint-plugin-jsdoc>spdx-expression-parse": true } }, - "fast-glob": { + "eslint-plugin-node": { "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, + "fs.readFileSync": true, "fs.readdirSync": true, - "fs.stat": true, "fs.statSync": true, - "os.cpus": true, - "os.platform": true, "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.isAbsolute": true, + "path.join": true, + "path.relative": true, "path.resolve": true, - "stream.PassThrough": true, - "stream.Readable": true + "path.sep": true }, "globals": { "process.cwd": true }, "packages": { - "eslint>@nodelib/fs.walk": true, - "eslint>glob-parent": true, - "fast-glob>@nodelib/fs.stat": true, - "fast-glob>micromatch": true, - "globby>merge2": true - } - }, - "fast-glob>@nodelib/fs.stat": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.stat": true, - "fs.statSync": true + "eslint-plugin-node>eslint-plugin-es": true, + "eslint-plugin-node>eslint-utils": true, + "eslint>ignore": true, + "eslint>minimatch": true, + "depcheck>resolve": true, + "eslint-plugin-node>semver": true } }, - "fast-glob>micromatch": { - "builtin": { - "util.inspect": true - }, + "eslint-plugin-prettier": { "packages": { - "chokidar>anymatch>picomatch": true, - "chokidar>braces": true + "prettier": true, + "eslint-plugin-prettier>prettier-linter-helpers": true } }, - "fs-extra": { + "eslint-plugin-react": { "builtin": { - "assert": true, - "fs": true, - "os.tmpdir": true, + "fs.statSync": true, "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "path.normalize": true, - "path.parse": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true + "path.extname": true }, "globals": { - "Buffer": true, - "console.warn": true, - "process.arch": true, - "process.cwd": true, - "process.platform": true, - "process.umask": true, - "process.versions.node.split": true, - "setTimeout": true + "console.error": true, + "console.log": true, + "process.argv.join": true, + "process.cwd": true }, "packages": { - "del>graceful-fs": true, - "fs-extra>jsonfile": true, - "fs-extra>universalify": true - } - }, - "fs-extra>jsonfile": { - "builtin": { - "fs": true - }, - "globals": { - "Buffer.isBuffer": true - }, - "packages": { - "del>graceful-fs": true - } - }, - "gh-pages>globby>pinkie-promise": { - "packages": { - "gh-pages>globby>pinkie-promise>pinkie": true + "eslint-plugin-react>array-includes": true, + "eslint-plugin-react>array.prototype.flatmap": true, + "eslint-plugin-react>doctrine": true, + "eslint": true, + "eslint-plugin-react>estraverse": true, + "eslint-plugin-react>jsx-ast-utils": true, + "eslint>minimatch": true, + "eslint-plugin-react>object.entries": true, + "eslint-plugin-react>object.fromentries": true, + "eslint-plugin-react>object.hasown": true, + "eslint-plugin-react>object.values": true, + "prop-types": true, + "eslint-plugin-react>resolve": true, + "eslint-plugin-react>semver": true, + "string.prototype.matchall": true } }, - "gh-pages>globby>pinkie-promise>pinkie": { + "eslint-plugin-react-hooks": { "globals": { - "process": true, - "setImmediate": true, - "setTimeout": true + "process.env.NODE_ENV": true } }, - "globby": { + "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope": { "builtin": { - "fs.Stats": true, - "fs.readFile": true, - "fs.readFileSync": true, - "fs.statSync": true, - "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "path.posix.join": true, - "path.relative": true, - "stream.Transform": true, - "util.promisify": true - }, - "globals": { - "process.cwd": true + "assert": true }, "packages": { - "del>slash": true, - "eslint>ignore": true, - "fast-glob": true, - "globby>array-union": true, - "globby>dir-glob": true, - "globby>merge2": true + "eslint>eslint-scope>esrecurse": true, + "@babel/eslint-parser>@nicolo-ribaudo/eslint-scope-5-internals>eslint-scope>estraverse": true } }, - "globby>dir-glob": { + "eslint-plugin-jest>@typescript-eslint/utils>eslint-scope": { "builtin": { - "path.extname": true, - "path.isAbsolute": true, - "path.join": true, - "path.posix.join": true - }, - "globals": { - "process.cwd": true + "assert": true }, "packages": { - "globby>dir-glob>path-type": true + "eslint>eslint-scope>esrecurse": true, + "eslint-plugin-jest>@typescript-eslint/utils>eslint-scope>estraverse": true } }, - "globby>dir-glob>path-type": { + "eslint>eslint-scope": { "builtin": { - "fs": true, - "util.promisify": true + "assert": true + }, + "packages": { + "eslint>eslint-scope>esrecurse": true, + "eslint-plugin-react>estraverse": true } }, - "globby>merge2": { + "webpack>eslint-scope": { "builtin": { - "stream.PassThrough": true + "assert": true }, - "globals": { - "process.nextTick": true + "packages": { + "eslint>eslint-scope>esrecurse": true, + "webpack>eslint-scope>estraverse": true } }, - "gulp": { - "builtin": { - "util.inherits": true - }, + "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils": { "packages": { - "gulp>glob-watcher": true, - "gulp>undertaker": true, - "gulp>vinyl-fs": true + "eslint-plugin-jest>@typescript-eslint/experimental-utils>eslint-utils>eslint-visitor-keys": true } }, - "gulp-livereload": { - "builtin": { - "path.relative": true - }, + "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils": { "packages": { - "fancy-log": true, - "gulp-livereload>chalk": true, - "gulp-livereload>debug": true, - "gulp-livereload>event-stream": true, - "gulp-livereload>lodash.assign": true, - "gulp-livereload>tiny-lr": true + "eslint>@eslint-community/eslint-utils": true, + "eslint-plugin-jest>@typescript-eslint/utils>eslint-utils>eslint-visitor-keys": true, + "semver": true } }, - "gulp-livereload>chalk": { - "globals": { - "process.env.TERM": true, - "process.platform": true - }, + "eslint-plugin-mocha>eslint-utils": { "packages": { - "gulp-livereload>chalk>ansi-styles": true, - "gulp-livereload>chalk>escape-string-regexp": true, - "gulp-livereload>chalk>supports-color": true + "eslint-plugin-mocha>eslint-utils>eslint-visitor-keys": true } }, - "gulp-livereload>chalk>ansi-styles": { + "eslint-plugin-node>eslint-utils": { "packages": { - "@metamask/jazzicon>color>color-convert": true + "eslint-plugin-node>eslint-utils>eslint-visitor-keys": true } }, - "gulp-livereload>chalk>supports-color": { - "builtin": { - "os.release": true - }, - "globals": { - "process.env": true, - "process.platform": true, - "process.stderr": true, - "process.stdout": true, - "process.versions.node.split": true - }, + "eslint>espree": { "packages": { - "gulp-livereload>chalk>supports-color>has-flag": true + "eslint>espree>acorn-jsx": true, + "jsdom>acorn": true, + "eslint>eslint-visitor-keys": true } }, - "gulp-livereload>chalk>supports-color>has-flag": { + "eslint>esquery": { "globals": { - "process.argv": true + "define": true } }, - "gulp-livereload>debug": { + "eslint>eslint-scope>esrecurse": { + "packages": { + "eslint-plugin-react>estraverse": true + } + }, + "eta": { "builtin": { - "tty.isatty": true, - "util": true + "node:fs": true, + "node:path": true }, "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, + "define": true + } + }, + "gulp-sourcemaps>debug-fabulous>memoizee>event-emitter": { "packages": { - "gulp-livereload>chalk>supports-color": true, - "mocha>ms": true + "resolve-url-loader>es6-iterator>d": true, + "resolve-url-loader>es6-iterator>es5-ext": true } }, "gulp-livereload>event-stream": { @@ -3452,117 +2913,168 @@ }, "packages": { "debounce-stream>duplexer": true, - "debounce-stream>through": true, "gulp-livereload>event-stream>from": true, "gulp-livereload>event-stream>map-stream": true, "gulp-livereload>event-stream>pause-stream": true, "gulp-livereload>event-stream>split": true, - "gulp-livereload>event-stream>stream-combiner": true + "gulp-livereload>event-stream>stream-combiner": true, + "debounce-stream>through": true } }, - "gulp-livereload>event-stream>from": { - "builtin": { - "stream": true - }, + "@lavamoat/lavapack>readable-stream>abort-controller>event-target-shim": { "globals": { - "process.nextTick": true + "Event": true, + "EventTarget": true, + "console": true } }, - "gulp-livereload>event-stream>map-stream": { - "builtin": { - "stream.Stream": true - }, - "globals": { - "process.nextTick": true + "stylelint>execall": { + "packages": { + "stylelint>execall>clone-regexp": true } }, - "gulp-livereload>event-stream>pause-stream": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": { + "globals": { + "__filename": true + }, "packages": { - "debounce-stream>through": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>extglob>expand-brackets>posix-character-classes": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex": true } }, - "gulp-livereload>event-stream>split": { - "builtin": { - "string_decoder.StringDecoder": true - }, + "gulp-watch>anymatch>micromatch>expand-brackets": { "packages": { - "debounce-stream>through": true + "gulp-watch>anymatch>micromatch>expand-brackets>is-posix-bracket": true } }, - "gulp-livereload>event-stream>stream-combiner": { + "gulp-watch>anymatch>micromatch>braces>expand-range": { "packages": { - "debounce-stream>duplexer": true + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range": true } }, - "gulp-livereload>tiny-lr": { - "builtin": { - "events": true, - "fs": true, - "http": true, - "https": true, - "url.parse": true - }, + "resolve-url-loader>es6-iterator>es6-symbol>ext": { "globals": { - "console.error": true - }, + "__global__": true + } + }, + "gulp>glob-watcher>anymatch>micromatch>braces>extend-shallow": { "packages": { - "@storybook/addon-knobs>qs": true, - "gulp-livereload>tiny-lr>body": true, - "gulp-livereload>tiny-lr>debug": true, - "gulp-livereload>tiny-lr>faye-websocket": true, - "react>object-assign": true + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp-livereload>tiny-lr>body": { - "builtin": { - "querystring.parse": true - }, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>extend-shallow": { "packages": { - "gulp-livereload>tiny-lr>body>continuable-cache": true, - "gulp-livereload>tiny-lr>body>error": true, - "gulp-livereload>tiny-lr>body>raw-body": true, - "gulp-livereload>tiny-lr>body>safe-json-parse": true + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp-livereload>tiny-lr>body>error": { - "builtin": { - "assert": true - }, + "gulp>glob-watcher>anymatch>micromatch>extglob>extend-shallow": { "packages": { - "gulp-livereload>tiny-lr>body>error>string-template": true, - "watchify>xtend": true + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp-livereload>tiny-lr>body>raw-body": { - "globals": { - "Buffer.concat": true, - "process.nextTick": true - }, + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>extend-shallow": { "packages": { - "gulp-livereload>tiny-lr>body>raw-body>bytes": true, - "gulp-livereload>tiny-lr>body>raw-body>string_decoder": true + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp-livereload>tiny-lr>body>raw-body>string_decoder": { - "builtin": { - "buffer.Buffer": true + "gulp-zip>plugin-error>extend-shallow": { + "packages": { + "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, + "gulp-zip>plugin-error>extend-shallow>is-extendable": true } }, - "gulp-livereload>tiny-lr>debug": { - "builtin": { - "tty.isatty": true, - "util": true - }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value>extend-shallow": { + "packages": { + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>extend-shallow": { + "packages": { + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + } + }, + "gulp>glob-watcher>anymatch>micromatch>extglob": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex": true + } + }, + "gulp-watch>anymatch>micromatch>extglob": { + "packages": { + "gulp-watch>anymatch>micromatch>is-extglob": true + } + }, + "fancy-log": { + "builtin": { + "console.Console": true + }, + "globals": { + "process.argv.indexOf": true, + "process.platform": true, + "process.stderr": true, + "process.stdout": true, + "process.version": true + }, + "packages": { + "fancy-log>ansi-gray": true, + "fancy-log>color-support": true, + "fancy-log>parse-node-version": true, + "fancy-log>time-stamp": true + } + }, + "gulp-watch>fancy-log": { "globals": { "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "process.argv.indexOf": true, + "process.stderr.write": true, + "process.stdout.write": true }, "packages": { - "mocha>ms": true, - "mocha>supports-color": true + "fancy-log>ansi-gray": true, + "fancy-log>color-support": true, + "fancy-log>time-stamp": true + } + }, + "fast-glob": { + "builtin": { + "fs.lstat": true, + "fs.lstatSync": true, + "fs.readdir": true, + "fs.readdirSync": true, + "fs.stat": true, + "fs.statSync": true, + "os.cpus": true, + "os.platform": true, + "path.basename": true, + "path.resolve": true, + "stream.PassThrough": true, + "stream.Readable": true + }, + "globals": { + "process.cwd": true + }, + "packages": { + "fast-glob>@nodelib/fs.stat": true, + "eslint>@nodelib/fs.walk": true, + "eslint>glob-parent": true, + "globby>merge2": true, + "fast-glob>micromatch": true + } + }, + "eslint>@nodelib/fs.walk>fastq": { + "packages": { + "eslint>@nodelib/fs.walk>fastq>reusify": true } }, "gulp-livereload>tiny-lr>faye-websocket": { @@ -3583,429 +3095,588 @@ "webpack-dev-server>sockjs>websocket-driver": true } }, - "gulp-postcss": { + "eslint>file-entry-cache": { "builtin": { - "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "stream.Transform": true - }, - "globals": { - "Buffer.from": true, - "setImmediate": true + "crypto.createHash": true, + "fs.readFileSync": true, + "fs.statSync": true, + "path.basename": true, + "path.dirname": true }, "packages": { - "fancy-log": true, - "gulp-postcss>postcss-load-config": true, - "gulp-zip>plugin-error": true, - "postcss": true, - "vinyl-sourcemaps-apply": true + "eslint>file-entry-cache>flat-cache": true } }, - "gulp-postcss>postcss-load-config": { + "stylelint>file-entry-cache": { "builtin": { - "module.createRequire": true, - "module.createRequireFromPath": true, - "path.resolve": true + "crypto.createHash": true, + "fs.readFileSync": true, + "fs.statSync": true, + "path.basename": true, + "path.dirname": true }, - "globals": { - "process.cwd": true, - "process.env.NODE_ENV": true + "packages": { + "stylelint>file-entry-cache>flat-cache": true + } + }, + "chokidar>braces>fill-range": { + "builtin": { + "util.inspect": true }, "packages": { - "gulp-postcss>postcss-load-config>lilconfig": true, - "gulp-postcss>postcss-load-config>yaml": true, - "ts-node": true + "chokidar>braces>fill-range>to-regex-range": true } }, - "gulp-postcss>postcss-load-config>lilconfig": { + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range": { "builtin": { - "fs.accessSync": true, - "fs.promises.access": true, - "fs.promises.readFile": true, - "fs.readFileSync": true, - "os.homedir": true, - "path.extname": true, - "path.join": true, - "path.parse": true, - "path.resolve": true, - "path.sep": true + "util.inspect": true }, - "globals": { - "process.cwd": true + "packages": { + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true, + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>to-regex-range": true } }, - "gulp-postcss>postcss-load-config>yaml": { - "globals": { - "Buffer": true, - "YAML_SILENCE_DEPRECATION_WARNINGS": true, - "YAML_SILENCE_WARNINGS": true, - "atob": true, - "btoa": true, - "console.warn": true, - "process": true + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range": { + "packages": { + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number": true, + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject": true, + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic": true, + "gulp-watch>anymatch>micromatch>braces>repeat-element": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true } }, - "gulp-sass": { + "eslint-plugin-import>eslint-module-utils>find-up": { "builtin": { - "path.basename": true, "path.dirname": true, - "path.extname": true, "path.join": true, - "path.relative": true, - "stream.Transform": true - }, - "globals": { - "process.cwd": true, - "process.exit": true, - "process.stderr.write": true + "path.parse": true, + "path.resolve": true }, "packages": { - "eslint>strip-ansi": true, - "gulp-sass>lodash.clonedeep": true, - "gulp-sass>replace-ext": true, - "gulp-zip>plugin-error": true, - "postcss>picocolors": true, - "vinyl-sourcemaps-apply": true + "eslint-plugin-import>eslint-module-utils>find-up>locate-path": true } }, - "gulp-sass>replace-ext": { + "mocha>find-up": { "builtin": { - "path.basename": true, "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.sep": true - } - }, - "gulp-sort": { + "path.parse": true, + "path.resolve": true + }, "packages": { - "gulp-sort>through2": true + "mocha>find-up>locate-path": true, + "nyc>find-up>path-exists": true } }, - "gulp-sort>through2": { + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { "builtin": { "util.inherits": true }, "globals": { - "process.nextTick": true + "Buffer.concat": true, + "setImmediate": true }, "packages": { - "gulp-sort>through2>readable-stream": true, - "watchify>xtend": true + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream": true } }, - "gulp-sort>through2>readable-stream": { + "eslint>file-entry-cache>flat-cache": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs.existsSync": true, + "fs.mkdirSync": true, + "fs.readFileSync": true, + "fs.writeFileSync": true, + "path.basename": true, + "path.dirname": true, + "path.resolve": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "__dirname": true }, "packages": { - "gulp-sort>through2>readable-stream>isarray": true, - "gulp-sort>through2>readable-stream>safe-buffer": true, - "gulp-sort>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "gulp-sort>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "gulp-sort>through2>readable-stream>string_decoder": { - "packages": { - "gulp-sort>through2>readable-stream>safe-buffer": true + "eslint>file-entry-cache>flat-cache>flatted": true, + "del>rimraf": true } }, - "gulp-sourcemaps": { + "stylelint>file-entry-cache>flat-cache": { "builtin": { + "fs.existsSync": true, + "fs.readFileSync": true, + "path.basename": true, "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true + "path.resolve": true }, "globals": { - "Buffer.concat": true, - "Buffer.from": true + "__dirname": true }, "packages": { - "del>graceful-fs": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map": true, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources": true, - "gulp-sourcemaps>acorn": true, - "gulp-sourcemaps>css": true, - "gulp-sourcemaps>debug-fabulous": true, - "gulp-sourcemaps>detect-newline": true, - "gulp-sourcemaps>source-map": true, - "gulp-sourcemaps>strip-bom-string": true, - "gulp-sourcemaps>through2": true, - "nyc>convert-source-map": true + "stylelint>file-entry-cache>flat-cache>flatted": true, + "stylelint>file-entry-cache>flat-cache>rimraf": true, + "stylelint>file-entry-cache>flat-cache>write": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map": { + "gulp>vinyl-fs>lead>flush-write-stream": { + "globals": { + "Buffer": true + }, "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>acorn": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>normalize-path": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>source-map": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>through2": true + "pumpify>inherits": true, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>acorn": { + "lavamoat>lavamoat-core>merge-deep>clone-deep>for-own": { + "packages": { + "gulp>undertaker>object.reduce>for-own>for-in": true + } + }, + "gulp-watch>anymatch>micromatch>object.omit>for-own": { + "packages": { + "gulp>undertaker>object.reduce>for-own>for-in": true + } + }, + "gulp>undertaker>object.reduce>for-own": { + "packages": { + "gulp>undertaker>object.reduce>for-own>for-in": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": { + "packages": { + "gulp>gulp-cli>liftoff>fined>parse-filepath>map-cache": true + } + }, + "gulp-livereload>event-stream>from": { + "builtin": { + "stream": true + }, "globals": { - "define": true + "process.nextTick": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss": { + "fs-extra": { "builtin": { + "assert": true, "fs": true, - "path": true + "os.tmpdir": true, + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "path.normalize": true, + "path.parse": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true }, "globals": { "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "console.warn": true, + "process.arch": true, + "process.cwd": true, + "process.platform": true, + "process.umask": true, + "process.versions.node.split": true, + "setTimeout": true }, "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss>picocolors": true, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>source-map": true + "del>graceful-fs": true, + "fs-extra>jsonfile": true, + "fs-extra>universalify": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss>picocolors": { + "gulp>vinyl-fs>fs-mkdirp-stream": { "builtin": { - "tty.isatty": true + "path.dirname": true, + "path.resolve": true }, "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true + "process.umask": true + }, + "packages": { + "del>graceful-fs": true, + "gulp>vinyl-fs>fs-mkdirp-stream>through2": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/identity-map>through2": { + "nyc>glob>fs.realpath": { "builtin": { - "util.inherits": true + "fs.lstat": true, + "fs.lstatSync": true, + "fs.readlink": true, + "fs.readlinkSync": true, + "fs.realpath": true, + "fs.realpathSync": true, + "fs.stat": true, + "fs.statSync": true, + "path.normalize": true, + "path.resolve": true }, "globals": { - "process.nextTick": true - }, - "packages": { - "readable-stream": true + "console.error": true, + "console.trace": true, + "process.env.NODE_DEBUG": true, + "process.nextTick": true, + "process.noDeprecation": true, + "process.platform": true, + "process.throwDeprecation": true, + "process.traceDeprecation": true, + "process.version": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources": { - "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2": true, - "gulp-watch>anymatch>normalize-path": true - } + "chokidar>fsevents": { + "globals": { + "console.assert": true, + "process.platform": true + }, + "native": true }, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2": { + "gulp>glob-watcher>chokidar>fsevents": { "builtin": { + "events.EventEmitter": true, + "fs.stat": true, + "path.join": true, "util.inherits": true }, "globals": { - "process.nextTick": true + "__dirname": true, + "console.assert": true, + "process.nextTick": true, + "process.platform": true, + "setImmediate": true }, "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream": true, - "watchify>xtend": true + "gulp-watch>chokidar>fsevents>node-pre-gyp": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream": { + "gulp-watch>chokidar>fsevents": { "builtin": { "events.EventEmitter": true, - "stream": true, - "util": true + "fs.stat": true, + "path.join": true, + "util.inherits": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, + "__dirname": true, + "console.assert": true, + "process.nextTick": true, + "process.platform": true, "setImmediate": true }, "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>isarray": true, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": true, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "gulp-watch>chokidar>fsevents>node-pre-gyp": true } }, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": { "builtin": { - "buffer": true - } - }, - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>string_decoder": { + "util.format": true + }, + "globals": { + "clearInterval": true, + "process": true, + "setImmediate": true, + "setInterval": true + }, "packages": { - "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": true + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>aproba": true, + "@storybook/react>@storybook/node-logger>npmlog>console-control-strings": true, + "@storybook/react>@storybook/node-logger>npmlog>gauge>has-unicode": true, + "react>object-assign": true, + "nyc>signal-exit": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": true, + "@storybook/react>@storybook/node-logger>npmlog>gauge>wide-align": true } }, - "gulp-sourcemaps>acorn": { - "globals": { - "define": true + "browserify>insert-module-globals>undeclared-identifiers>get-assigned-identifiers": { + "builtin": { + "assert.equal": true } }, - "gulp-sourcemaps>css": { - "builtin": { - "fs.readFileSync": true, - "path.dirname": true, - "path.sep": true + "string.prototype.matchall>get-intrinsic": { + "globals": { + "AggregateError": true, + "FinalizationRegistry": true, + "WeakRef": true }, "packages": { - "gulp-sourcemaps>css>source-map": true, - "gulp-sourcemaps>css>source-map-resolve": true, - "pumpify>inherits": true + "string.prototype.matchall>call-bind>es-errors": true, + "browserify>has>function-bind": true, + "string.prototype.matchall>es-abstract>has-proto": true, + "string.prototype.matchall>has-symbols": true, + "depcheck>is-core-module>hasown": true } }, - "gulp-sourcemaps>css>source-map-resolve": { + "gulp-zip>get-stream": { "builtin": { - "path.sep": true, - "url.resolve": true + "buffer.constants.MAX_LENGTH": true, + "stream.PassThrough": true }, "globals": { - "TextDecoder": true, - "setImmediate": true + "Buffer.concat": true }, "packages": { - "gulp-sourcemaps>css>source-map-resolve>atob": true, - "gulp-sourcemaps>css>source-map-resolve>decode-uri-component": true + "pumpify>pump": true } }, - "gulp-sourcemaps>css>source-map-resolve>atob": { - "globals": { - "Buffer.from": true + "gulp-watch>anymatch>micromatch>parse-glob>glob-base": { + "builtin": { + "path.dirname": true + }, + "packages": { + "eslint>glob-parent": true, + "gulp-watch>anymatch>micromatch>parse-glob>glob-base>is-glob": true } }, - "gulp-sourcemaps>debug-fabulous": { + "eslint>glob-parent": { + "builtin": { + "os.platform": true, + "path.posix.dirname": true + }, "packages": { - "gulp-sourcemaps>debug-fabulous>debug": true, - "gulp-sourcemaps>debug-fabulous>memoizee": true, - "react>object-assign": true + "del>is-glob": true } }, - "gulp-sourcemaps>debug-fabulous>debug": { + "gulp>vinyl-fs>glob-stream": { "builtin": { - "tty.isatty": true, - "util": true + "util.inherits": true }, "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true + "process.cwd": true, + "process.nextTick": true }, "packages": { - "mocha>ms": true, - "mocha>supports-color": true + "react-markdown>unified>extend": true, + "eslint>glob-parent": true, + "nyc>glob": true, + "gulp>glob-watcher>is-negated-glob": true, + "gulp>vinyl-fs>glob-stream>ordered-read-streams": true, + "gulp>vinyl-fs>glob-stream>pumpify": true, + "gulp>vinyl-fs>glob-stream>readable-stream": true, + "vinyl>remove-trailing-separator": true, + "gulp>vinyl-fs>glob-stream>to-absolute-glob": true, + "gulp>vinyl-fs>glob-stream>unique-stream": true } }, - "gulp-sourcemaps>debug-fabulous>memoizee": { + "gulp>glob-watcher": { + "packages": { + "gulp>glob-watcher>anymatch": true, + "gulp>glob-watcher>async-done": true, + "chokidar": true, + "gulp>glob-watcher>is-negated-glob": true, + "gulp>glob-watcher>just-debounce": true, + "gulp>undertaker>object.defaults": true + } + }, + "nyc>glob": { + "builtin": { + "assert": true, + "events.EventEmitter": true, + "fs": true, + "path.join": true, + "path.resolve": true, + "util": true + }, "globals": { - "clearTimeout": true, - "setTimeout": true + "console.error": true, + "process.cwd": true, + "process.nextTick": true, + "process.platform": true }, "packages": { - "gulp-sourcemaps>debug-fabulous>memoizee>event-emitter": true, - "gulp-sourcemaps>debug-fabulous>memoizee>is-promise": true, - "gulp-sourcemaps>debug-fabulous>memoizee>lru-queue": true, - "gulp-sourcemaps>debug-fabulous>memoizee>next-tick": true, - "gulp-sourcemaps>debug-fabulous>memoizee>timers-ext": true, - "resolve-url-loader>es6-iterator>d": true, - "resolve-url-loader>es6-iterator>es5-ext": true + "nyc>glob>fs.realpath": true, + "nyc>glob>inflight": true, + "pumpify>inherits": true, + "eslint>minimatch": true, + "@metamask/object-multiplex>once": true, + "gulp-watch>path-is-absolute": true } }, - "gulp-sourcemaps>debug-fabulous>memoizee>event-emitter": { + "stylelint>global-modules": { + "builtin": { + "path.resolve": true + }, + "globals": { + "process.env.OSTYPE": true, + "process.platform": true + }, "packages": { - "resolve-url-loader>es6-iterator>d": true, - "resolve-url-loader>es6-iterator>es5-ext": true + "stylelint>global-modules>global-prefix": true } }, - "gulp-sourcemaps>debug-fabulous>memoizee>lru-queue": { + "stylelint>global-modules>global-prefix": { + "builtin": { + "fs.readFileSync": true, + "fs.realpathSync": true, + "os.homedir": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true + }, + "globals": { + "process.env.APPDATA": true, + "process.env.DESTDIR": true, + "process.env.OSTYPE": true, + "process.env.PREFIX": true, + "process.execPath": true, + "process.platform": true + }, "packages": { - "resolve-url-loader>es6-iterator>es5-ext": true + "stylelint>global-modules>global-prefix>ini": true, + "stylelint>global-modules>global-prefix>which": true } }, - "gulp-sourcemaps>debug-fabulous>memoizee>next-tick": { + "globby": { + "builtin": { + "fs.Stats": true, + "fs.readFile": true, + "fs.readFileSync": true, + "fs.statSync": true, + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "path.posix.join": true, + "path.relative": true, + "stream.Transform": true, + "util.promisify": true + }, "globals": { - "MutationObserver": true, - "WebKitMutationObserver": true, - "document": true, - "process": true, - "queueMicrotask": true, - "setImmediate": true, - "setTimeout": true + "process.cwd": true + }, + "packages": { + "globby>array-union": true, + "globby>dir-glob": true, + "fast-glob": true, + "eslint>ignore": true, + "globby>merge2": true, + "del>slash": true } }, - "gulp-sourcemaps>debug-fabulous>memoizee>timers-ext": { + "stylelint>globjoin": { + "builtin": { + "path.join": true + } + }, + "stylelint>postcss-sass>gonzales-pe": { + "globals": { + "console.error": true, + "define": true + } + }, + "string.prototype.matchall>es-abstract>gopd": { "packages": { - "resolve-url-loader>es6-iterator>es5-ext": true + "string.prototype.matchall>get-intrinsic": true } }, - "gulp-sourcemaps>through2": { + "del>graceful-fs": { "builtin": { - "util.inherits": true + "assert.equal": true, + "constants.O_SYMLINK": true, + "constants.O_WRONLY": true, + "constants.hasOwnProperty": true, + "fs": true, + "stream.Stream.call": true, + "util": true }, "globals": { - "process.nextTick": true + "clearTimeout": true, + "console.error": true, + "process": true, + "setTimeout": true + } + }, + "gulp": { + "builtin": { + "util.inherits": true }, "packages": { - "gulp-sourcemaps>through2>readable-stream": true, - "watchify>xtend": true + "gulp>glob-watcher": true, + "gulp>undertaker": true, + "gulp>vinyl-fs": true } }, - "gulp-sourcemaps>through2>readable-stream": { + "gulp-livereload": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "path.relative": true + }, + "packages": { + "gulp-livereload>chalk": true, + "gulp-livereload>debug": true, + "gulp-livereload>event-stream": true, + "fancy-log": true, + "gulp-livereload>lodash.assign": true, + "gulp-livereload>tiny-lr": true + } + }, + "gulp-postcss": { + "builtin": { + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "stream.Transform": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, + "Buffer.from": true, "setImmediate": true }, "packages": { - "gulp-sourcemaps>through2>readable-stream>isarray": true, - "gulp-sourcemaps>through2>readable-stream>safe-buffer": true, - "gulp-sourcemaps>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "fancy-log": true, + "gulp-zip>plugin-error": true, + "postcss": true, + "gulp-postcss>postcss-load-config": true, + "vinyl-sourcemaps-apply": true } }, - "gulp-sourcemaps>through2>readable-stream>safe-buffer": { + "gulp-sass": { "builtin": { - "buffer": true + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.relative": true, + "stream.Transform": true + }, + "globals": { + "process.cwd": true, + "process.exit": true, + "process.stderr.write": true + }, + "packages": { + "gulp-sass>lodash.clonedeep": true, + "postcss>picocolors": true, + "gulp-zip>plugin-error": true, + "gulp-sass>replace-ext": true, + "eslint>strip-ansi": true, + "vinyl-sourcemaps-apply": true } }, - "gulp-sourcemaps>through2>readable-stream>string_decoder": { + "gulp-sort": { "packages": { - "gulp-sourcemaps>through2>readable-stream>safe-buffer": true + "gulp-sort>through2": true + } + }, + "gulp-sourcemaps": { + "builtin": { + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true + }, + "globals": { + "Buffer.concat": true, + "Buffer.from": true + }, + "packages": { + "gulp-sourcemaps>@gulp-sourcemaps/identity-map": true, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources": true, + "gulp-sourcemaps>acorn": true, + "nyc>convert-source-map": true, + "gulp-sourcemaps>css": true, + "gulp-sourcemaps>debug-fabulous": true, + "gulp-sourcemaps>detect-newline": true, + "del>graceful-fs": true, + "gulp-sourcemaps>source-map": true, + "gulp-sourcemaps>strip-bom-string": true, + "gulp-sourcemaps>through2": true } }, "gulp-stylelint": { @@ -4021,23 +3692,12 @@ "process.nextTick": true }, "packages": { - "eslint>strip-ansi": true, "fancy-log": true, - "gulp-stylelint>through2": true, "gulp-zip>plugin-error": true, "source-map": true, - "stylelint": true - } - }, - "gulp-stylelint>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, - "packages": { - "readable-stream": true + "eslint>strip-ansi": true, + "stylelint": true, + "gulp-stylelint>through2": true } }, "gulp-watch": { @@ -4054,835 +3714,497 @@ "setTimeout": true }, "packages": { - "chokidar": true, - "eslint>glob-parent": true, "gulp-watch>ansi-colors": true, "gulp-watch>anymatch": true, + "chokidar": true, "gulp-watch>fancy-log": true, + "eslint>glob-parent": true, + "react>object-assign": true, "gulp-watch>path-is-absolute": true, + "gulp-zip>plugin-error": true, "gulp-watch>readable-stream": true, "gulp-watch>slash": true, - "gulp-watch>vinyl-file": true, - "gulp-zip>plugin-error": true, - "react>object-assign": true, - "vinyl": true - } - }, - "gulp-watch>ansi-colors": { - "packages": { - "fancy-log>ansi-gray>ansi-wrap": true + "vinyl": true, + "gulp-watch>vinyl-file": true } }, - "gulp-watch>anymatch": { + "gulp-zip": { "builtin": { - "path.sep": true + "buffer.constants.MAX_LENGTH": true, + "path.join": true }, "packages": { - "gulp-watch>anymatch>micromatch": true, - "gulp-watch>anymatch>normalize-path": true + "gulp-zip>get-stream": true, + "gulp-zip>plugin-error": true, + "gulp-zip>through2": true, + "vinyl": true, + "gulp-zip>yazl": true } }, - "gulp-watch>anymatch>micromatch": { - "builtin": { - "path.sep": true - }, - "globals": { - "process": true - }, + "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi": { "packages": { - "gulp-watch>anymatch>micromatch>arr-diff": true, - "gulp-watch>anymatch>micromatch>array-unique": true, - "gulp-watch>anymatch>micromatch>braces": true, - "gulp-watch>anymatch>micromatch>expand-brackets": true, - "gulp-watch>anymatch>micromatch>extglob": true, - "gulp-watch>anymatch>micromatch>filename-regex": true, - "gulp-watch>anymatch>micromatch>is-extglob": true, - "gulp-watch>anymatch>micromatch>is-glob": true, - "gulp-watch>anymatch>micromatch>kind-of": true, - "gulp-watch>anymatch>micromatch>object.omit": true, - "gulp-watch>anymatch>micromatch>parse-glob": true, - "gulp-watch>anymatch>micromatch>regex-cache": true, - "gulp-watch>anymatch>normalize-path": true + "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi>ansi-regex": true } }, - "gulp-watch>anymatch>micromatch>arr-diff": { - "packages": { - "gulp>undertaker>arr-flatten": true + "chalk>supports-color>has-flag": { + "globals": { + "process.argv": true } }, - "gulp-watch>anymatch>micromatch>braces": { - "packages": { - "gulp-watch>anymatch>micromatch>braces>expand-range": true, - "gulp-watch>anymatch>micromatch>braces>preserve": true, - "gulp-watch>anymatch>micromatch>braces>repeat-element": true + "gulp-livereload>chalk>supports-color>has-flag": { + "globals": { + "process.argv": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range": { - "packages": { - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range": true + "postcss-discard-font-face>postcss>supports-color>has-flag": { + "globals": { + "process.argv": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range": { + "string.prototype.matchall>es-abstract>has-property-descriptors": { "packages": { - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number": true, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject": true, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic": true, - "gulp-watch>anymatch>micromatch>braces>repeat-element": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true + "string.prototype.matchall>call-bind>es-define-property": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number": { + "koa>is-generator-function>has-tostringtag": { "packages": { - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number>kind-of": true + "string.prototype.matchall>has-symbols": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true + "@storybook/react>@storybook/node-logger>npmlog>gauge>has-unicode": { + "builtin": { + "os.type": true + }, + "globals": { + "process.env.LANG": true, + "process.env.LC_ALL": true, + "process.env.LC_CTYPE": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value": { "packages": { - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject>isarray": true + "gulp>gulp-cli>array-sort>get-value": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values": true, + "gulp>gulp-cli>isobject": true } }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value": { "packages": { - "@babel/register>clone-deep>kind-of": true, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": true, - "gulp>undertaker>bach>array-last>is-number": true - } - }, - "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": { - "builtin": { - "crypto.randomBytes": true + "gulp>gulp-cli>array-sort>get-value": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>has-values": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject": true } }, - "gulp-watch>anymatch>micromatch>expand-brackets": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values": { "packages": { - "gulp-watch>anymatch>micromatch>expand-brackets>is-posix-bracket": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>kind-of": true } }, - "gulp-watch>anymatch>micromatch>extglob": { + "browserify>has": { "packages": { - "gulp-watch>anymatch>micromatch>is-extglob": true + "browserify>has>function-bind": true } }, - "gulp-watch>anymatch>micromatch>is-glob": { + "depcheck>is-core-module>hasown": { "packages": { - "gulp-watch>anymatch>micromatch>is-extglob": true + "browserify>has>function-bind": true } }, - "gulp-watch>anymatch>micromatch>kind-of": { + "stylelint>postcss-html>htmlparser2": { + "builtin": { + "buffer.Buffer": true, + "events.EventEmitter": true, + "string_decoder.StringDecoder": true + }, "packages": { - "browserify>insert-module-globals>is-buffer": true + "stylelint>postcss-html>htmlparser2>domelementtype": true, + "stylelint>postcss-html>htmlparser2>domhandler": true, + "stylelint>postcss-html>htmlparser2>domutils": true, + "stylelint>postcss-html>htmlparser2>entities": true, + "pumpify>inherits": true, + "readable-stream": true } }, - "gulp-watch>anymatch>micromatch>object.omit": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>for-own": true, - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + "webpack-dev-server>sockjs>websocket-driver>http-parser-js": { + "builtin": { + "assert.equal": true, + "assert.ok": true } }, - "gulp-watch>anymatch>micromatch>object.omit>for-own": { - "packages": { - "gulp>undertaker>object.reduce>for-own>for-in": true + "eslint>ignore": { + "globals": { + "process": true } }, - "gulp-watch>anymatch>micromatch>parse-glob": { - "packages": { - "gulp-watch>anymatch>micromatch>is-extglob": true, - "gulp-watch>anymatch>micromatch>parse-glob>glob-base": true, - "gulp-watch>anymatch>micromatch>parse-glob>is-dotfile": true, - "gulp-watch>anymatch>micromatch>parse-glob>is-glob": true + "sass-embedded>immutable": { + "globals": { + "console": true, + "define": true } }, - "gulp-watch>anymatch>micromatch>parse-glob>glob-base": { + "eslint>@eslint/eslintrc>import-fresh": { "builtin": { "path.dirname": true }, + "globals": { + "__dirname": true, + "__filename": true + }, "packages": { - "eslint>glob-parent": true, - "gulp-watch>anymatch>micromatch>parse-glob>glob-base>is-glob": true + "eslint>@eslint/eslintrc>import-fresh>parent-module": true, + "eslint>@eslint/eslintrc>import-fresh>resolve-from": true } }, - "gulp-watch>anymatch>micromatch>parse-glob>glob-base>is-glob": { + "nyc>glob>inflight": { + "globals": { + "process.nextTick": true + }, "packages": { - "gulp-watch>anymatch>micromatch>is-extglob": true + "@metamask/object-multiplex>once": true, + "@metamask/object-multiplex>once>wrappy": true } }, - "gulp-watch>anymatch>micromatch>parse-glob>is-glob": { - "packages": { - "gulp-watch>anymatch>micromatch>is-extglob": true + "pumpify>inherits": { + "builtin": { + "util.inherits": true } }, - "gulp-watch>anymatch>micromatch>regex-cache": { - "packages": { - "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow": true + "ini": { + "globals": { + "process": true } }, - "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow": { - "packages": { - "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow>is-primitive": true + "stylelint>global-modules>global-prefix>ini": { + "globals": { + "process": true } }, - "gulp-watch>anymatch>normalize-path": { + "@lavamoat/lavapack>combine-source-map>inline-source-map": { + "globals": { + "Buffer.from": true + }, "packages": { - "vinyl>remove-trailing-separator": true + "@lavamoat/lavapack>combine-source-map>inline-source-map>source-map": true } }, - "gulp-watch>chokidar": { + "browserify>insert-module-globals": { "builtin": { - "events.EventEmitter": true, - "fs": true, - "path.basename": true, "path.dirname": true, - "path.extname": true, - "path.join": true, + "path.isAbsolute": true, "path.relative": true, - "path.resolve": true, "path.sep": true }, "globals": { - "clearTimeout": true, - "console.error": true, - "process.env.CHOKIDAR_INTERVAL": true, - "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, - "process.env.CHOKIDAR_USEPOLLING": true, - "process.nextTick": true, - "process.platform": true, - "setTimeout": true + "Buffer.concat": true, + "Buffer.isBuffer": true }, "packages": { - "chokidar>normalize-path": true, - "eslint>is-glob": true, - "gulp-watch>chokidar>anymatch": true, - "gulp-watch>chokidar>async-each": true, - "gulp-watch>chokidar>braces": true, - "gulp-watch>chokidar>fsevents": true, - "gulp-watch>chokidar>is-binary-path": true, - "gulp-watch>chokidar>readdirp": true, - "gulp-watch>chokidar>upath": true, - "gulp-watch>glob-parent": true, + "browserify>syntax-error>acorn-node": true, + "@lavamoat/lavapack>combine-source-map": true, "gulp-watch>path-is-absolute": true, - "pumpify>inherits": true + "browserify>insert-module-globals>through2": true, + "browserify>insert-module-globals>undeclared-identifiers": true, + "watchify>xtend": true } }, - "gulp-watch>chokidar>fsevents": { - "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "console.assert": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true - }, + "string.prototype.matchall>internal-slot": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp": true + "string.prototype.matchall>call-bind>es-errors": true, + "depcheck>is-core-module>hasown": true, + "string.prototype.matchall>side-channel": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp": { - "builtin": { - "events.EventEmitter": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.renameSync": true, - "path.dirname": true, - "path.existsSync": true, - "path.join": true, - "path.resolve": true, - "url.parse": true, - "url.resolve": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "console.log": true, - "process.arch": true, - "process.cwd": true, - "process.env": true, - "process.platform": true, - "process.version.substr": true, - "process.versions": true - }, + "gulp>gulp-cli>replace-homedir>is-absolute": { "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": true + "gulp>gulp-cli>replace-homedir>is-absolute>is-relative": true, + "nyc>spawn-wrap>is-windows": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": { - "builtin": { - "child_process.spawnSync": true, - "fs.readdirSync": true, - "os.platform": true - }, - "globals": { - "process.env": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { + "packages": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": { - "builtin": { - "path": true, - "stream.Stream": true, - "url": true - }, - "globals": { - "console": true, - "process.argv": true, - "process.env.DEBUG_NOPT": true, - "process.env.NOPT_DEBUG": true, - "process.platform": true - }, + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-accessor-descriptor": { "packages": { - "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>nopt>abbrev": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": true + "@babel/register>clone-deep>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": { - "builtin": { - "child_process.exec": true, - "path": true - }, - "globals": { - "process.env.COMPUTERNAME": true, - "process.env.ComSpec": true, - "process.env.EDITOR": true, - "process.env.HOSTNAME": true, - "process.env.PATH": true, - "process.env.PROMPT": true, - "process.env.PS1": true, - "process.env.Path": true, - "process.env.SHELL": true, - "process.env.USER": true, - "process.env.USERDOMAIN": true, - "process.env.USERNAME": true, - "process.env.VISUAL": true, - "process.env.path": true, - "process.nextTick": true, - "process.platform": true - }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-accessor-descriptor": { "packages": { - "@storybook/core>@storybook/core-server>x-default-browser>default-browser-id>untildify>os-homedir": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { - "globals": { - "process.env.SystemRoot": true, - "process.env.TEMP": true, - "process.env.TMP": true, - "process.env.TMPDIR": true, - "process.env.windir": true, - "process.platform": true + "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": { + "packages": { + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-alphabetical": true, + "react-syntax-highlighter>refractor>parse-entities>is-decimal": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": { + "chokidar>is-binary-path": { "builtin": { - "assert": true, - "fs": true, - "path.join": true - }, - "globals": { - "process.platform": true, - "setTimeout": true + "path.extname": true }, "packages": { - "nyc>glob": true + "chokidar>is-binary-path>binary-extensions": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": { + "string.prototype.matchall>es-abstract>is-callable": { "globals": { - "console": true, - "process": true + "document": true } }, - "gulp-watch>fancy-log": { + "depcheck>is-core-module": { "globals": { - "console": true, - "process.argv.indexOf": true, - "process.stderr.write": true, - "process.stdout.write": true + "process.versions": true }, "packages": { - "fancy-log>ansi-gray": true, - "fancy-log>color-support": true, - "fancy-log>time-stamp": true + "depcheck>is-core-module>hasown": true } }, - "gulp-watch>path-is-absolute": { - "globals": { - "process.platform": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { + "packages": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": true } }, - "gulp-watch>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-data-descriptor": { "packages": { - "gulp-watch>readable-stream>isarray": true, - "gulp-watch>readable-stream>safe-buffer": true, - "gulp-watch>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "@babel/register>clone-deep>kind-of": true } }, - "gulp-watch>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": true } }, - "gulp-watch>readable-stream>string_decoder": { + "@metamask/eth-token-tracker>deep-equal>is-date-object": { "packages": { - "gulp-watch>readable-stream>safe-buffer": true + "koa>is-generator-function>has-tostringtag": true } }, - "gulp-watch>vinyl-file": { - "builtin": { - "path.resolve": true - }, - "globals": { - "process.cwd": true - }, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": { "packages": { - "del>graceful-fs": true, - "gh-pages>globby>pinkie-promise": true, - "gulp-watch>vinyl-file>pify": true, - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream": true, - "gulp-watch>vinyl-file>vinyl": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true } }, - "gulp-watch>vinyl-file>strip-bom": { - "globals": { - "Buffer.isBuffer": true - }, + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": { "packages": { - "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-data-descriptor": true, + "@babel/register>clone-deep>kind-of": true } }, - "gulp-watch>vinyl-file>strip-bom-stream": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor": { "packages": { - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>kind-of": true } }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { - "builtin": { - "util.inherits": true - }, - "globals": { - "Buffer.concat": true, - "setImmediate": true - }, + "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow": { "packages": { - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream": true + "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow>is-primitive": true } }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "gulp-zip>plugin-error>extend-shallow>is-extendable": { "packages": { - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>isarray": true, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": true, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "@babel/register>clone-deep>is-plain-object": true } }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep>is-extendable": { + "packages": { + "@babel/register>clone-deep>is-plain-object": true } }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>string_decoder": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { "packages": { - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": true + "gulp>gulp-cli>yargs>string-width>is-fullwidth-code-point>number-is-nan": true } }, - "gulp-watch>vinyl-file>vinyl": { - "builtin": { - "buffer.Buffer": true, - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.relative": true, - "stream.PassThrough": true, - "stream.Stream": true - }, - "globals": { - "process.cwd": true - }, + "del>is-glob": { "packages": { - "@metamask/jazzicon>color>clone": true, - "gulp-watch>vinyl-file>vinyl>clone-stats": true, - "gulp-watch>vinyl-file>vinyl>replace-ext": true + "del>is-glob>is-extglob": true } }, - "gulp-watch>vinyl-file>vinyl>clone-stats": { - "builtin": { - "fs.Stats": true - } - }, - "gulp-watch>vinyl-file>vinyl>replace-ext": { - "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true - } - }, - "gulp-zip": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "path.join": true - }, + "gulp-watch>anymatch>micromatch>parse-glob>glob-base>is-glob": { "packages": { - "gulp-zip>get-stream": true, - "gulp-zip>plugin-error": true, - "gulp-zip>through2": true, - "gulp-zip>yazl": true, - "vinyl": true + "gulp-watch>anymatch>micromatch>is-extglob": true } }, - "gulp-zip>get-stream": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "stream.PassThrough": true - }, - "globals": { - "Buffer.concat": true - }, + "gulp-watch>anymatch>micromatch>is-glob": { "packages": { - "pumpify>pump": true + "gulp-watch>anymatch>micromatch>is-extglob": true } }, - "gulp-zip>plugin-error": { - "builtin": { - "util.inherits": true - }, + "gulp-watch>anymatch>micromatch>parse-glob>is-glob": { "packages": { - "gulp-watch>ansi-colors": true, - "gulp-zip>plugin-error>arr-diff": true, - "gulp-zip>plugin-error>arr-union": true, - "gulp-zip>plugin-error>extend-shallow": true + "gulp-watch>anymatch>micromatch>is-extglob": true } }, - "gulp-zip>plugin-error>extend-shallow": { + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": { "packages": { - "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, - "gulp-zip>plugin-error>extend-shallow>is-extendable": true + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number>kind-of": true } }, - "gulp-zip>plugin-error>extend-shallow>is-extendable": { + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number": { "packages": { - "@babel/register>clone-deep>is-plain-object": true + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number>kind-of": true } }, - "gulp-zip>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number": { "packages": { - "readable-stream": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number>kind-of": true } }, - "gulp-zip>yazl": { + "del>is-path-cwd": { "builtin": { - "events.EventEmitter": true, - "fs.createReadStream": true, - "fs.stat": true, - "stream.PassThrough": true, - "stream.Transform": true, - "util.inherits": true, - "zlib.DeflateRaw": true, - "zlib.deflateRaw": true + "path.resolve": true }, "globals": { - "Buffer": true, - "setImmediate": true, - "utf8FileName.length": true - }, - "packages": { - "gulp-zip>yazl>buffer-crc32": true + "process.cwd": true, + "process.platform": true } }, - "gulp-zip>yazl>buffer-crc32": { + "del>is-path-inside": { "builtin": { - "buffer.Buffer": true + "path.relative": true, + "path.resolve": true, + "path.sep": true } }, - "gulp>glob-watcher": { + "@babel/register>clone-deep>is-plain-object": { "packages": { - "chokidar": true, - "gulp>glob-watcher>anymatch": true, - "gulp>glob-watcher>async-done": true, - "gulp>glob-watcher>is-negated-glob": true, - "gulp>glob-watcher>just-debounce": true, - "gulp>undertaker>object.defaults": true + "gulp>gulp-cli>isobject": true } }, - "gulp>glob-watcher>anymatch": { - "builtin": { - "path.sep": true - }, + "string.prototype.matchall>es-abstract>is-regex": { "packages": { - "gulp-watch>anymatch>normalize-path": true, - "gulp>glob-watcher>anymatch>micromatch": true + "string.prototype.matchall>call-bind": true, + "koa>is-generator-function>has-tostringtag": true } }, - "gulp>glob-watcher>anymatch>micromatch": { - "builtin": { - "path.basename": true, - "path.sep": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - }, + "gulp>gulp-cli>replace-homedir>is-absolute>is-relative": { "packages": { - "@babel/register>clone-deep>kind-of": true, - "gulp-zip>plugin-error>arr-diff": true, - "gulp-zip>plugin-error>extend-shallow": true, - "gulp>glob-watcher>anymatch>micromatch>braces": true, - "gulp>glob-watcher>anymatch>micromatch>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extglob": true, - "gulp>gulp-cli>liftoff>fined>object.pick": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, - "gulp>gulp-cli>matchdep>micromatch>nanomatch": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex": true + "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces": { + "eslint-plugin-react>array-includes>is-string": { "packages": { - "gulp-watch>anymatch>micromatch>braces>repeat-element": true, - "gulp>glob-watcher>anymatch>micromatch>braces>extend-shallow": true, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range": true, - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node": true, - "gulp>gulp-cli>matchdep>micromatch>braces>split-string": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex": true, - "gulp>undertaker>arr-flatten": true + "koa>is-generator-function>has-tostringtag": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>extend-shallow": { + "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + "string.prototype.matchall>has-symbols": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range": { - "builtin": { - "util.inspect": true - }, + "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path": { "packages": { - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>extend-shallow": true, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": true, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>to-regex-range": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true + "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path>unc-path-regex": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>extend-shallow": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + "mocha>log-symbols>is-unicode-supported": { + "globals": { + "process.env.CI": true, + "process.env.TERM": true, + "process.env.TERM_PROGRAM": true, + "process.env.WT_SESSION": true, + "process.platform": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number>kind-of": true + "nyc>spawn-wrap>is-windows": { + "globals": { + "define": true, + "isWindows": "write", + "process": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true + "@sentry/cli>which>isexe": { + "builtin": { + "fs": true + }, + "globals": { + "TESTING_WINDOWS": true, + "process.env.PATHEXT": true, + "process.getgid": true, + "process.getuid": true, + "process.platform": true } }, - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>to-regex-range": { + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject": { "packages": { - "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>isobject>isarray": true } }, - "gulp>glob-watcher>anymatch>micromatch>define-property": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject": { "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject>isarray": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>extend-shallow": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex": true + "postcss-discard-font-face>postcss>js-base64": { + "globals": { + "Base64": "write", + "define": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": { - "packages": { - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "eslint-plugin-jsdoc>@es-joy/jsdoccomment>jsdoc-type-pratt-parser": { + "globals": { + "define": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": { + "@babel/core>@babel/generator>jsesc": { "globals": { - "__filename": true - }, - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>extend-shallow": true, - "gulp>gulp-cli>matchdep>micromatch>extglob>expand-brackets>posix-character-classes": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex": true + "Buffer": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": { - "builtin": { - "fs.SyncWriteStream": true, - "net.Socket": true, - "tty.WriteStream": true, - "tty.isatty": true, - "util": true - }, + "webpack>json-parse-even-better-errors": { "globals": { - "chrome": true, - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug>ms": true + "Buffer.isBuffer": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": { + "@lavamoat/lavapack>json-stable-stringify": { "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": true + "string.prototype.matchall>call-bind": true, + "@lavamoat/lavapack>json-stable-stringify>isarray": true, + "@lavamoat/lavapack>json-stable-stringify>jsonify": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>extend-shallow": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>extend-shallow": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + "depcheck>json5": { + "globals": { + "console.warn": true } }, - "gulp>glob-watcher>async-done": { + "eslint-plugin-import>tsconfig-paths>json5": { "globals": { - "process.nextTick": true - }, - "packages": { - "@metamask/object-multiplex>once": true, - "duplexify>end-of-stream": true, - "gulp>glob-watcher>async-done>stream-exhaust": true, - "readable-stream-2>process-nextick-args": true + "console.warn": true } }, - "gulp>glob-watcher>async-done>stream-exhaust": { + "fs-extra>jsonfile": { "builtin": { - "stream.Writable": true, - "util.inherits": true + "fs": true }, "globals": { - "setImmediate": true + "Buffer.isBuffer": true + }, + "packages": { + "del>graceful-fs": true } }, - "gulp>glob-watcher>chokidar": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents": true + "browserify>JSONStream>jsonparse": { + "globals": { + "Buffer": true } }, - "gulp>glob-watcher>chokidar>fsevents": { - "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, + "eslint-plugin-react>jsx-ast-utils": { "globals": { - "__dirname": true, - "console.assert": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true + "console.error": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp": true + "gulp>vinyl-fs>object.assign": true } }, "gulp>glob-watcher>just-debounce": { @@ -4891,1855 +4213,1297 @@ "setTimeout": true } }, - "gulp>gulp-cli>liftoff>fined>object.pick": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>kind-of": { "packages": { - "gulp>gulp-cli>isobject": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": { "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>define-property": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": { "packages": { - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": { "packages": { - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util>kind-of": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util>kind-of": { + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number>kind-of": { "packages": { "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>braces>split-string": { + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>is-number>kind-of": { "packages": { - "gulp-zip>plugin-error>extend-shallow": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number>kind-of": { "packages": { - "@babel/register>clone-deep>kind-of": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-data-descriptor": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-accessor-descriptor": { + "lavamoat>lavamoat-core>merge-deep>kind-of": { "packages": { - "@babel/register>clone-deep>kind-of": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor>is-data-descriptor": { + "gulp-watch>anymatch>micromatch>kind-of": { "packages": { - "@babel/register>clone-deep>kind-of": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>kind-of": { "packages": { - "gulp>gulp-cli>liftoff>fined>parse-filepath>map-cache": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>nanomatch": { - "builtin": { - "path.basename": true, - "path.sep": true, - "util.inspect": true + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>kind-of": { + "globals": { + "Buffer": true }, "packages": { - "@babel/register>clone-deep>kind-of": true, - "gulp-zip>plugin-error>arr-diff": true, - "gulp-zip>plugin-error>extend-shallow": true, - "gulp>gulp-cli>liftoff>fined>object.pick": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, - "gulp>gulp-cli>matchdep>micromatch>nanomatch>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex": true, - "nyc>spawn-wrap>is-windows": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>nanomatch>define-property": { + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util>kind-of": { "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>regex-not": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path>kind-of": { "packages": { - "gulp-zip>plugin-error>extend-shallow": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon": { - "builtin": { - "fs.readFileSync": true, - "path.dirname": true, - "util.inspect": true - }, - "globals": { - "__filename": true - }, + "labeled-stream-splicer": { "packages": { - "gulp>gulp-cli>liftoff>fined>parse-filepath>map-cache": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>extend-shallow": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>source-map": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>use": true, - "resolve-url-loader>rework>css>source-map-resolve": true + "pumpify>inherits": true, + "labeled-stream-splicer>stream-splicer": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base": { + "gulp>undertaker>last-run": { "builtin": { - "util.inherits": true + "assert": true }, "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>component-emitter": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>pascalcase": true + "gulp>undertaker>last-run>default-resolution": true, + "gulp>undertaker>es6-weak-map": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base": { + "lavamoat-browserify": { + "builtin": { + "node:fs.existsSync": true, + "node:fs.mkdirSync": true, + "node:fs.readFileSync": true, + "node:fs.writeFileSync": true, + "node:path.dirname": true, + "node:path.extname": true, + "node:path.resolve": true, + "node:util.callbackify": true + }, + "globals": { + "console.warn": true, + "process.cwd": true, + "setTimeout": true + }, "packages": { - "gulp>gulp-cli>array-sort>get-value": true, - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>union-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>component-emitter": true + "lavamoat>@lavamoat/aa": true, + "@lavamoat/lavapack": true, + "browserify>browser-resolve": true, + "lavamoat-browserify>concat-stream": true, + "duplexify": true, + "lavamoat>lavamoat-core": true, + "lavamoat-browserify>readable-stream": true, + "through2": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit": { + "lavamoat>lavamoat-core": { + "builtin": { + "node:events": true, + "node:fs.readFileSync": true, + "node:fs/promises": true, + "node:path.extname": true, + "node:path.join": true + }, + "globals": { + "__dirname": true, + "console.error": true, + "console.warn": true, + "define": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>map-visit": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": true + "@lavamoat/lavapack>json-stable-stringify": true, + "lavamoat>lavamoat-tofu": true, + "lavamoat>lavamoat-core>merge-deep": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>map-visit": { - "builtin": { - "util.inspect": true + "lavamoat>lavamoat-tofu": { + "globals": { + "console.log": true }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": true + "@babel/core>@babel/parser": true, + "depcheck>@babel/traverse": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": { - "packages": { - "gulp>gulp-cli>isobject": true + "lavamoat>lavamoat-core>merge-deep>clone-deep>lazy-cache": { + "globals": { + "process.env.TRAVIS": true, + "process.env.UNLAZY": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value": { - "packages": { - "gulp>gulp-cli>array-sort>get-value": true, - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values": true + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>lazy-cache": { + "globals": { + "process.env.UNLAZY": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values": { + "gulp>vinyl-fs>lazystream": { + "builtin": { + "util.inherits": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>kind-of": true + "gulp>vinyl-fs>lazystream>readable-stream": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number": { + "gulp>vinyl-fs>lead": { + "globals": { + "process.nextTick": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number>kind-of": true + "gulp>vinyl-fs>lead>flush-write-stream": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>is-number>kind-of": { + "eslint>levn": { "packages": { - "browserify>insert-module-globals>is-buffer": true + "eslint>levn>prelude-ls": true, + "eslint>levn>type-check": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>has-value>has-values>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true + "gulp-postcss>postcss-load-config>lilconfig": { + "builtin": { + "fs.accessSync": true, + "fs.promises.access": true, + "fs.promises.readFile": true, + "fs.readFileSync": true, + "os.homedir": true, + "path.extname": true, + "path.join": true, + "path.parse": true, + "path.resolve": true, + "path.sep": true + }, + "globals": { + "process.cwd": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": { + "eslint-plugin-import>eslint-module-utils>find-up>locate-path": { + "builtin": { + "path.resolve": true + }, + "globals": { + "process.cwd": true + }, "packages": { - "@babel/register>clone-deep>is-plain-object": true, - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, - "gulp>gulp-cli>matchdep>micromatch>braces>split-string": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value>extend-shallow": true + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate": true, + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>path-exists": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value>extend-shallow": { + "mocha>find-up>locate-path": { + "builtin": { + "fs.lstat": true, + "fs.lstatSync": true, + "fs.stat": true, + "fs.statSync": true, + "path.resolve": true, + "util.promisify": true + }, + "globals": { + "process.cwd": true + }, "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true + "mocha>find-up>locate-path>p-locate": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path": { - "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path>kind-of": true + "lodash": { + "globals": { + "define": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path>kind-of": { + "@babel/preset-env>babel-plugin-polyfill-corejs2>@babel/helper-define-polyfill-provider>lodash.debounce": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "mocha>log-symbols": { "packages": { - "browserify>insert-module-globals>is-buffer": true + "chalk": true, + "mocha>log-symbols>is-unicode-supported": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>union-value": { + "loose-envify": { + "builtin": { + "stream.PassThrough": true, + "stream.Transform": true, + "util.inherits": true + }, + "globals": { + "process.env": true + }, "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, - "gulp-zip>plugin-error>arr-union": true, - "gulp>gulp-cli>array-sort>get-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": true + "loose-envify>js-tokens": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value": { + "@babel/core>@babel/helper-compilation-targets>lru-cache": { "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value": true + "@babel/core>@babel/helper-compilation-targets>lru-cache>yallist": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value": { + "gulp-sourcemaps>debug-fabulous>memoizee>lru-queue": { "packages": { - "gulp>gulp-cli>array-sort>get-value": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>has-values": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject": true + "resolve-url-loader>es6-iterator>es5-ext": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject": { + "gulp>undertaker>arr-map>make-iterator": { "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value>isobject>isarray": true + "@babel/register>clone-deep>kind-of": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils": { + "gulp-livereload>event-stream>map-stream": { "builtin": { - "util": true + "stream.Stream": true }, - "packages": { - "gulp-zip>plugin-error>arr-union": true, - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true + "globals": { + "process.nextTick": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>map-visit": { "builtin": { - "util.inherits": true + "util.inspect": true }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy": { + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>markdown-table": { "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>copy-descriptor": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>kind-of": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": { + "builtin": { + "crypto.randomBytes": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>define-property": { + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>mdast-util-compact": { "packages": { - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "react-markdown>unist-util-visit": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep": { + "gulp-sourcemaps>debug-fabulous>memoizee": { + "globals": { + "clearTimeout": true, + "setTimeout": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep>is-extendable": true, - "gulp>undertaker>object.reduce>for-own>for-in": true + "resolve-url-loader>es6-iterator>d": true, + "resolve-url-loader>es6-iterator>es5-ext": true, + "gulp-sourcemaps>debug-fabulous>memoizee>event-emitter": true, + "gulp-sourcemaps>debug-fabulous>memoizee>is-promise": true, + "gulp-sourcemaps>debug-fabulous>memoizee>lru-queue": true, + "gulp-sourcemaps>debug-fabulous>memoizee>next-tick": true, + "gulp-sourcemaps>debug-fabulous>memoizee>timers-ext": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep>is-extendable": { + "lavamoat>lavamoat-core>merge-deep": { "packages": { - "@babel/register>clone-deep>is-plain-object": true + "gulp-zip>plugin-error>arr-union": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep": true, + "lavamoat>lavamoat-core>merge-deep>kind-of": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug": { + "globby>merge2": { "builtin": { - "fs.SyncWriteStream": true, - "net.Socket": true, - "tty.WriteStream": true, - "tty.isatty": true, - "util": true + "stream.PassThrough": true }, "globals": { - "chrome": true, - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, - "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug>ms": true + "process.nextTick": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": { + "gulp>glob-watcher>anymatch>micromatch": { + "builtin": { + "path.basename": true, + "path.sep": true, + "util.inspect": true + }, + "globals": { + "process.platform": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor": true + "gulp-zip>plugin-error>arr-diff": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, + "gulp>glob-watcher>anymatch>micromatch>braces": true, + "gulp>glob-watcher>anymatch>micromatch>define-property": true, + "gulp-zip>plugin-error>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>extglob": true, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, + "@babel/register>clone-deep>kind-of": true, + "gulp>gulp-cli>matchdep>micromatch>nanomatch": true, + "gulp>gulp-cli>liftoff>fined>object.pick": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor": { + "gulp-watch>anymatch>micromatch": { + "builtin": { + "path.sep": true + }, + "globals": { + "process": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor": true, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>kind-of": true + "gulp-watch>anymatch>micromatch>arr-diff": true, + "gulp-watch>anymatch>micromatch>array-unique": true, + "gulp-watch>anymatch>micromatch>braces": true, + "gulp-watch>anymatch>micromatch>expand-brackets": true, + "gulp-watch>anymatch>micromatch>extglob": true, + "gulp-watch>anymatch>micromatch>filename-regex": true, + "gulp-watch>anymatch>micromatch>is-extglob": true, + "gulp-watch>anymatch>micromatch>is-glob": true, + "gulp-watch>anymatch>micromatch>kind-of": true, + "gulp-watch>anymatch>normalize-path": true, + "gulp-watch>anymatch>micromatch>object.omit": true, + "gulp-watch>anymatch>micromatch>parse-glob": true, + "gulp-watch>anymatch>micromatch>regex-cache": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-accessor-descriptor": { + "fast-glob>micromatch": { + "builtin": { + "util.inspect": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": true + "chokidar>braces": true, + "chokidar>anymatch>picomatch": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor": { + "eslint>minimatch": { + "builtin": { + "path": true + }, + "globals": { + "console": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": true + "eslint>minimatch>brace-expansion": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property>is-descriptor>is-data-descriptor>kind-of": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep": { "packages": { - "browserify>insert-module-globals>is-buffer": true + "gulp>undertaker>object.reduce>for-own>for-in": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>mixin-deep>is-extendable": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>extend-shallow": { + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": { "packages": { + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object>for-in": true, "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp>gulp-cli>matchdep>micromatch>snapdragon>use": { - "packages": { - "@babel/register>clone-deep>kind-of": true + "mockttp>portfinder>mkdirp": { + "builtin": { + "fs": true, + "path.dirname": true, + "path.resolve": true } }, - "gulp>gulp-cli>matchdep>micromatch>to-regex": { + "browserify>module-deps": { + "builtin": { + "fs.createReadStream": true, + "fs.readFile": true, + "path.delimiter": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true + }, + "globals": { + "process.cwd": true, + "process.env.NODE_PATH": true, + "process.nextTick": true, + "process.platform": true, + "setTimeout": true, + "tr": true + }, "packages": { - "gulp-zip>plugin-error>extend-shallow": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": true + "browserify>browser-resolve": true, + "browserify>cached-path-relative": true, + "browserify>concat-stream": true, + "watchify>defined": true, + "browserify>module-deps>detective": true, + "browserify>duplexer2": true, + "pumpify>inherits": true, + "loose-envify": true, + "browserify>parents": true, + "browserify>module-deps>readable-stream": true, + "depcheck>resolve": true, + "browserify>module-deps>stream-combiner2": true, + "browserify>module-deps>through2": true, + "watchify>xtend": true } }, - "gulp>gulp-cli>matchdep>micromatch>to-regex>define-property": { + "gulp>gulp-cli>matchdep>micromatch>nanomatch": { + "builtin": { + "path.basename": true, + "path.sep": true, + "util.inspect": true + }, "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true + "gulp-zip>plugin-error>arr-diff": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, + "gulp>gulp-cli>matchdep>micromatch>nanomatch>define-property": true, + "gulp-zip>plugin-error>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, + "nyc>spawn-wrap>is-windows": true, + "@babel/register>clone-deep>kind-of": true, + "gulp>gulp-cli>liftoff>fined>object.pick": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex": true } }, - "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": { + "gulp-sourcemaps>debug-fabulous>memoizee>next-tick": { + "globals": { + "MutationObserver": true, + "WebKitMutationObserver": true, + "document": true, + "process": true, + "queueMicrotask": true, + "setImmediate": true, + "setTimeout": true + } + }, + "gulp-watch>chokidar>fsevents>node-pre-gyp": { + "builtin": { + "events.EventEmitter": true, + "fs.existsSync": true, + "fs.readFileSync": true, + "fs.renameSync": true, + "path.dirname": true, + "path.existsSync": true, + "path.join": true, + "path.resolve": true, + "url.parse": true, + "url.resolve": true, + "util.inherits": true + }, + "globals": { + "__dirname": true, + "console.log": true, + "process.arch": true, + "process.cwd": true, + "process.env": true, + "process.platform": true, + "process.version.substr": true, + "process.versions": true + }, "packages": { - "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex>ret": true + "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": true, + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog": true, + "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": true, + "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": true } }, - "gulp>gulp-cli>replace-homedir>is-absolute": { + "node-sass": { + "native": true + }, + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": { + "builtin": { + "path": true, + "stream.Stream": true, + "url": true + }, + "globals": { + "console": true, + "process.argv": true, + "process.env.DEBUG_NOPT": true, + "process.env.NOPT_DEBUG": true, + "process.platform": true + }, "packages": { - "gulp>gulp-cli>replace-homedir>is-absolute>is-relative": true, - "nyc>spawn-wrap>is-windows": true + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>nopt>abbrev": true, + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": true } }, - "gulp>gulp-cli>replace-homedir>is-absolute>is-relative": { + "gulp-watch>anymatch>normalize-path": { "packages": { - "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path": true + "vinyl>remove-trailing-separator": true } }, - "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path": { + "stylelint>normalize-selector": { + "globals": { + "define": true + } + }, + "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": { "packages": { - "gulp>gulp-cli>replace-homedir>is-absolute>is-relative>is-unc-path>unc-path-regex": true + "@metamask/object-multiplex>once": true } }, - "gulp>undertaker": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog": { "builtin": { - "assert": true, "events.EventEmitter": true, - "util.inherits": true + "util": true }, "globals": { - "process.env.UNDERTAKER_SETTLE": true, - "process.env.UNDERTAKER_TIME_RESOLUTION": true, - "process.hrtime": true + "process.nextTick": true, + "process.stderr": true }, "packages": { - "gulp>undertaker>arr-flatten": true, - "gulp>undertaker>arr-map": true, - "gulp>undertaker>bach": true, - "gulp>undertaker>collection-map": true, - "gulp>undertaker>es6-weak-map": true, - "gulp>undertaker>last-run": true, - "gulp>undertaker>object.defaults": true, - "gulp>undertaker>object.reduce": true, - "gulp>undertaker>undertaker-registry": true - } - }, - "gulp>undertaker>arr-map": { - "packages": { - "gulp>undertaker>arr-map>make-iterator": true + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>are-we-there-yet": true, + "@storybook/react>@storybook/node-logger>npmlog>console-control-strings": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": true, + "nyc>yargs>set-blocking": true } }, - "gulp>undertaker>arr-map>make-iterator": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy": { "packages": { - "@babel/register>clone-deep>kind-of": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>copy-descriptor": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy>kind-of": true } }, - "gulp>undertaker>bach": { + "string.prototype.matchall>es-abstract>object-inspect": { "builtin": { - "assert.ok": true + "util.inspect": true }, - "packages": { - "gulp>glob-watcher>async-done": true, - "gulp>undertaker>arr-flatten": true, - "gulp>undertaker>arr-map": true, - "gulp>undertaker>bach>arr-filter": true, - "gulp>undertaker>bach>array-each": true, - "gulp>undertaker>bach>array-initial": true, - "gulp>undertaker>bach>array-last": true, - "gulp>undertaker>bach>async-settle": true, - "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": true + "globals": { + "HTMLElement": true, + "WeakRef": true } }, - "gulp>undertaker>bach>arr-filter": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>collection-visit>object-visit": { "packages": { - "gulp>undertaker>arr-map>make-iterator": true + "gulp>gulp-cli>isobject": true } }, - "gulp>undertaker>bach>array-initial": { + "gulp>vinyl-fs>object.assign": { "packages": { - "gulp>undertaker>bach>array-last>is-number": true, - "gulp>undertaker>object.defaults>array-slice": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>has-symbols": true, + "@lavamoat/lavapack>json-stable-stringify>object-keys": true } }, - "gulp>undertaker>bach>array-last": { + "gulp>undertaker>object.defaults": { "packages": { - "gulp>undertaker>bach>array-last>is-number": true + "gulp>undertaker>bach>array-each": true, + "gulp>undertaker>object.defaults>array-slice": true, + "gulp>undertaker>object.reduce>for-own": true, + "gulp>gulp-cli>isobject": true } }, - "gulp>undertaker>bach>async-settle": { + "eslint-plugin-react>object.entries": { "packages": { - "gulp>glob-watcher>async-done": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true } }, - "gulp>undertaker>collection-map": { + "eslint-plugin-react>object.fromentries": { "packages": { - "gulp>undertaker>arr-map": true, - "gulp>undertaker>arr-map>make-iterator": true, - "gulp>undertaker>object.reduce>for-own": true + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true } }, - "gulp>undertaker>es6-weak-map": { + "eslint-plugin-react>object.hasown": { "packages": { - "resolve-url-loader>es6-iterator": true, - "resolve-url-loader>es6-iterator>d": true, - "resolve-url-loader>es6-iterator>es5-ext": true, - "resolve-url-loader>es6-iterator>es6-symbol": true + "string.prototype.matchall>es-abstract": true } }, - "gulp>undertaker>last-run": { - "builtin": { - "assert": true - }, + "gulp-watch>anymatch>micromatch>object.omit": { "packages": { - "gulp>undertaker>es6-weak-map": true, - "gulp>undertaker>last-run>default-resolution": true - } - }, - "gulp>undertaker>last-run>default-resolution": { - "globals": { - "process.version.match": true + "gulp-watch>anymatch>micromatch>object.omit>for-own": true, + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true } }, - "gulp>undertaker>object.defaults": { + "gulp>gulp-cli>liftoff>fined>object.pick": { "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>undertaker>bach>array-each": true, - "gulp>undertaker>object.defaults>array-slice": true, - "gulp>undertaker>object.reduce>for-own": true + "gulp>gulp-cli>isobject": true } }, "gulp>undertaker>object.reduce": { "packages": { - "gulp>undertaker>arr-map>make-iterator": true, - "gulp>undertaker>object.reduce>for-own": true + "gulp>undertaker>object.reduce>for-own": true, + "gulp>undertaker>arr-map>make-iterator": true } }, - "gulp>undertaker>object.reduce>for-own": { + "@metamask/object-multiplex>once": { "packages": { - "gulp>undertaker>object.reduce>for-own>for-in": true + "@metamask/object-multiplex>once>wrappy": true } }, - "gulp>vinyl-fs": { + "gulp>vinyl-fs>glob-stream>ordered-read-streams": { "builtin": { - "os.platform": true, - "path.relative": true, - "path.resolve": true, "util.inherits": true }, - "globals": { - "Buffer.isBuffer": true, - "process.cwd": true, - "process.geteuid": true, - "process.getuid": true, - "process.nextTick": true - }, "packages": { - "del>graceful-fs": true, - "gulp>vinyl-fs>fs-mkdirp-stream": true, - "gulp>vinyl-fs>glob-stream": true, - "gulp>vinyl-fs>is-valid-glob": true, - "gulp>vinyl-fs>lazystream": true, - "gulp>vinyl-fs>lead": true, - "gulp>vinyl-fs>object.assign": true, - "gulp>vinyl-fs>pumpify": true, - "gulp>vinyl-fs>readable-stream": true, - "gulp>vinyl-fs>remove-bom-buffer": true, - "gulp>vinyl-fs>remove-bom-stream": true, - "gulp>vinyl-fs>resolve-options": true, - "gulp>vinyl-fs>through2": true, - "gulp>vinyl-fs>to-through": true, - "gulp>vinyl-fs>value-or-function": true, - "gulp>vinyl-fs>vinyl-sourcemap": true, - "vinyl": true + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream": true } }, - "gulp>vinyl-fs>fs-mkdirp-stream": { + "@storybook/core>@storybook/core-server>x-default-browser>default-browser-id>untildify>os-homedir": { "builtin": { - "path.dirname": true, - "path.resolve": true + "os.homedir": true }, "globals": { - "process.umask": true - }, - "packages": { - "del>graceful-fs": true, - "gulp>vinyl-fs>fs-mkdirp-stream>through2": true + "process.env": true, + "process.getuid": true, + "process.platform": true } }, - "gulp>vinyl-fs>fs-mkdirp-stream>through2": { - "builtin": { - "util.inherits": true - }, + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { "globals": { - "process.nextTick": true - }, - "packages": { - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream": true, - "watchify>xtend": true + "process.env.SystemRoot": true, + "process.env.TEMP": true, + "process.env.TMP": true, + "process.env.TMPDIR": true, + "process.env.windir": true, + "process.platform": true } }, - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream": { + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "child_process.exec": true, + "path": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "process.env.COMPUTERNAME": true, + "process.env.ComSpec": true, + "process.env.EDITOR": true, + "process.env.HOSTNAME": true, + "process.env.PATH": true, + "process.env.PROMPT": true, + "process.env.PS1": true, + "process.env.Path": true, + "process.env.SHELL": true, + "process.env.USER": true, + "process.env.USERDOMAIN": true, + "process.env.USERNAME": true, + "process.env.VISUAL": true, + "process.env.path": true, + "process.nextTick": true, + "process.platform": true }, "packages": { - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>isarray": true, - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "@storybook/core>@storybook/core-server>x-default-browser>default-browser-id>untildify>os-homedir": true, + "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true } }, - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "@storybook/test-runner>jest-circus>p-limit": { + "packages": { + "@storybook/test-runner>jest-circus>p-limit>yocto-queue": true } }, - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>string_decoder": { + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit": { "packages": { - "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": true + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit>p-try": true } }, - "gulp>vinyl-fs>glob-stream": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.cwd": true, - "process.nextTick": true - }, + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate": { "packages": { - "eslint>glob-parent": true, - "gulp>glob-watcher>is-negated-glob": true, - "gulp>vinyl-fs>glob-stream>ordered-read-streams": true, - "gulp>vinyl-fs>glob-stream>pumpify": true, - "gulp>vinyl-fs>glob-stream>readable-stream": true, - "gulp>vinyl-fs>glob-stream>to-absolute-glob": true, - "gulp>vinyl-fs>glob-stream>unique-stream": true, - "nyc>glob": true, - "react-markdown>unified>extend": true, - "vinyl>remove-trailing-separator": true + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>p-locate>p-limit": true } }, - "gulp>vinyl-fs>glob-stream>ordered-read-streams": { - "builtin": { - "util.inherits": true - }, + "mocha>find-up>locate-path>p-locate": { "packages": { - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream": true + "@storybook/test-runner>jest-circus>p-limit": true } }, - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, + "del>p-map": { "packages": { - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>isarray": true, - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "del>p-map>aggregate-error": true } }, - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "eslint>@eslint/eslintrc>import-fresh>parent-module": { + "packages": { + "@metamask/test-bundler>ow>callsites": true } }, - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>string_decoder": { + "browserify>parents": { + "globals": { + "process.cwd": true, + "process.platform": true + }, "packages": { - "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": true + "browserify>parents>path-platform": true } }, - "gulp>vinyl-fs>glob-stream>pumpify": { + "react-syntax-highlighter>refractor>parse-entities": { "packages": { - "gulp>vinyl-fs>glob-stream>pumpify>duplexify": true, - "gulp>vinyl-fs>glob-stream>pumpify>pump": true, - "pumpify>inherits": true + "react-syntax-highlighter>refractor>parse-entities>character-entities-legacy": true, + "react-syntax-highlighter>refractor>parse-entities>character-entities": true, + "react-syntax-highlighter>refractor>parse-entities>character-reference-invalid": true, + "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": true, + "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, + "react-syntax-highlighter>refractor>parse-entities>is-hexadecimal": true } }, - "gulp>vinyl-fs>glob-stream>pumpify>duplexify": { - "globals": { - "Buffer": true, - "process.nextTick": true - }, + "gulp-watch>anymatch>micromatch>parse-glob": { "packages": { - "duplexify>end-of-stream": true, - "duplexify>stream-shift": true, - "gulp>vinyl-fs>glob-stream>readable-stream": true, - "pumpify>inherits": true + "gulp-watch>anymatch>micromatch>parse-glob>glob-base": true, + "gulp-watch>anymatch>micromatch>parse-glob>is-dotfile": true, + "gulp-watch>anymatch>micromatch>is-extglob": true, + "gulp-watch>anymatch>micromatch>parse-glob>is-glob": true } }, - "gulp>vinyl-fs>glob-stream>pumpify>pump": { - "builtin": { - "fs": true - }, + "depcheck>cosmiconfig>parse-json": { "packages": { - "@metamask/object-multiplex>once": true, - "duplexify>end-of-stream": true + "@babel/code-frame": true, + "depcheck>cosmiconfig>parse-json>error-ex": true, + "webpack>json-parse-even-better-errors": true, + "depcheck>cosmiconfig>parse-json>lines-and-columns": true } }, - "gulp>vinyl-fs>glob-stream>readable-stream": { + "nyc>find-up>path-exists": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "gulp>vinyl-fs>glob-stream>readable-stream>isarray": true, - "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>glob-stream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "fs.access": true, + "fs.accessSync": true, + "util.promisify": true } }, - "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": { + "eslint-plugin-import>eslint-module-utils>find-up>locate-path>path-exists": { "builtin": { - "buffer": true + "fs.access": true, + "fs.accessSync": true } }, - "gulp>vinyl-fs>glob-stream>readable-stream>string_decoder": { - "packages": { - "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": true + "gulp-watch>path-is-absolute": { + "globals": { + "process.platform": true } }, - "gulp>vinyl-fs>glob-stream>to-absolute-glob": { + "depcheck>resolve>path-parse": { + "globals": { + "process.platform": true + } + }, + "browserify>parents>path-platform": { "builtin": { - "path.resolve": true + "path": true, + "util.isObject": true, + "util.isString": true }, "globals": { "process.cwd": true, + "process.env": true, "process.platform": true - }, - "packages": { - "gulp>glob-watcher>is-negated-glob": true, - "gulp>gulp-cli>replace-homedir>is-absolute": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify": true, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter": true + "globby>dir-glob>path-type": { + "builtin": { + "fs": true, + "util.promisify": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter": { + "gulp-livereload>event-stream>pause-stream": { "packages": { - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2": true, - "watchify>xtend": true + "debounce-stream>through": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2": { + "postcss>picocolors": { + "globals": { + "process": true + } + }, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss>picocolors": { "builtin": { - "util.inherits": true + "tty.isatty": true }, "globals": { - "process.nextTick": true + "process.argv.includes": true, + "process.env": true, + "process.platform": true + } + }, + "stylelint>postcss-less>postcss>picocolors": { + "builtin": { + "tty.isatty": true }, - "packages": { - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream": true, - "watchify>xtend": true + "globals": { + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream": { + "stylelint>postcss-safe-parser>postcss>picocolors": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "tty.isatty": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>isarray": true, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": { + "stylelint>postcss-sass>postcss>picocolors": { "builtin": { - "buffer": true + "tty.isatty": true + }, + "globals": { + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>string_decoder": { - "packages": { - "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": true + "stylelint>postcss-scss>postcss>picocolors": { + "builtin": { + "tty.isatty": true + }, + "globals": { + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>lazystream": { + "stylelint>postcss>picocolors": { "builtin": { - "util.inherits": true + "tty.isatty": true }, - "packages": { - "gulp>vinyl-fs>lazystream>readable-stream": true + "globals": { + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>lazystream>readable-stream": { + "stylelint>sugarss>postcss>picocolors": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "tty.isatty": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "gulp>vinyl-fs>lazystream>readable-stream>isarray": true, - "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>lazystream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "process.argv.includes": true, + "process.env": true, + "process.platform": true } }, - "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": { + "chokidar>anymatch>picomatch": { "builtin": { - "buffer": true + "path.basename": true, + "path.sep": true + }, + "globals": { + "process.platform": true, + "process.version.slice": true } }, - "gulp>vinyl-fs>lazystream>readable-stream>string_decoder": { + "gh-pages>globby>pinkie-promise": { "packages": { - "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": true + "gh-pages>globby>pinkie-promise>pinkie": true } }, - "gulp>vinyl-fs>lead": { + "gh-pages>globby>pinkie-promise>pinkie": { "globals": { - "process.nextTick": true - }, - "packages": { - "gulp>vinyl-fs>lead>flush-write-stream": true + "process": true, + "setImmediate": true, + "setTimeout": true } }, - "gulp>vinyl-fs>lead>flush-write-stream": { - "globals": { - "Buffer": true + "gulp-zip>plugin-error": { + "builtin": { + "util.inherits": true }, "packages": { - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream": true, - "pumpify>inherits": true + "gulp-watch>ansi-colors": true, + "gulp-zip>plugin-error>arr-diff": true, + "gulp-zip>plugin-error>arr-union": true, + "gulp-zip>plugin-error>extend-shallow": true } }, - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream": { + "postcss": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs.existsSync": true, + "fs.readFileSync": true, + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true, + "url.fileURLToPath": true, + "url.pathToFileURL": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer": true, + "URL": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.LANG": true, + "process.env.NODE_ENV": true }, "packages": { - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>isarray": true, - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "nanoid": true, + "postcss>picocolors": true, + "postcss>source-map-js": true } }, - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>string_decoder": { + "postcss-discard-font-face": { "packages": { - "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": true + "postcss-discard-font-face>balanced-match": true, + "postcss-discard-font-face>postcss": true } }, - "gulp>vinyl-fs>object.assign": { + "stylelint>postcss-html": { + "globals": { + "__dirname": true + }, "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>has-symbols": true + "stylelint>postcss-html>htmlparser2": true, + "stylelint>postcss-syntax": true } }, - "gulp>vinyl-fs>pumpify": { + "stylelint>postcss-less": { "packages": { - "gulp>vinyl-fs>pumpify>duplexify": true, - "gulp>vinyl-fs>pumpify>pump": true, - "pumpify>inherits": true + "stylelint>postcss-less>postcss": true } }, - "gulp>vinyl-fs>pumpify>duplexify": { + "gulp-postcss>postcss-load-config": { + "builtin": { + "module.createRequire": true, + "module.createRequireFromPath": true, + "path.resolve": true + }, "globals": { - "Buffer": true, - "process.nextTick": true + "process.cwd": true, + "process.env.NODE_ENV": true }, "packages": { - "duplexify>end-of-stream": true, - "duplexify>stream-shift": true, - "gulp>vinyl-fs>readable-stream": true, - "pumpify>inherits": true + "gulp-postcss>postcss-load-config>lilconfig": true, + "ts-node": true, + "gulp-postcss>postcss-load-config>yaml": true } }, - "gulp>vinyl-fs>pumpify>pump": { - "builtin": { - "fs": true - }, + "stylelint>postcss-reporter": { "packages": { - "@metamask/object-multiplex>once": true, - "duplexify>end-of-stream": true + "lodash": true } }, - "gulp>vinyl-fs>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, + "postcss-rtlcss": { "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "SuppressedError": true }, "packages": { - "gulp>vinyl-fs>readable-stream>isarray": true, - "gulp>vinyl-fs>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true + "postcss": true, + "postcss-rtlcss>rtlcss": true } }, - "gulp>vinyl-fs>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "stylelint>postcss-safe-parser": { + "packages": { + "stylelint>postcss-safe-parser>postcss": true } }, - "gulp>vinyl-fs>readable-stream>string_decoder": { + "stylelint>postcss-sass": { "packages": { - "gulp>vinyl-fs>readable-stream>safe-buffer": true + "stylelint>postcss-sass>gonzales-pe": true, + "stylelint>postcss-sass>postcss": true } }, - "gulp>vinyl-fs>remove-bom-buffer": { + "stylelint>postcss-scss": { "packages": { - "browserify>insert-module-globals>is-buffer": true, - "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true + "stylelint>postcss-scss>postcss": true } }, - "gulp>vinyl-fs>remove-bom-stream": { + "stylelint>postcss-selector-parser": { "packages": { - "gulp>vinyl-fs>remove-bom-buffer": true, - "gulp>vinyl-fs>remove-bom-stream>through2": true, - "koa>content-disposition>safe-buffer": true + "stylelint>postcss-selector-parser>cssesc": true, + "readable-stream>util-deprecate": true } }, - "gulp>vinyl-fs>remove-bom-stream>through2": { + "stylelint>postcss-syntax": { "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true + "path.isAbsolute": true, + "path.resolve": true, + "path.sep": true }, "packages": { - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream": true, - "watchify>xtend": true + "stylelint>postcss": true } }, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream": { + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs": true, + "path": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>isarray": true, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder": { - "packages": { - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder>safe-buffer": true - } - }, - "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "gulp>vinyl-fs>resolve-options": { + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true + }, "packages": { - "gulp>vinyl-fs>value-or-function": true + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>postcss>picocolors": true, + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>source-map": true } }, - "gulp>vinyl-fs>through2": { + "postcss-discard-font-face>postcss": { "builtin": { - "util.inherits": true + "fs": true, + "path": true }, "globals": { - "process.nextTick": true + "console": true }, "packages": { - "gulp>vinyl-fs>readable-stream": true, - "watchify>xtend": true - } - }, - "gulp>vinyl-fs>to-through": { - "packages": { - "gulp>vinyl-fs>to-through>through2": true + "postcss-discard-font-face>postcss>chalk": true, + "postcss-discard-font-face>postcss>js-base64": true, + "postcss-discard-font-face>postcss>source-map": true, + "postcss-discard-font-face>postcss>supports-color": true } }, - "gulp>vinyl-fs>to-through>through2": { + "stylelint>postcss-less>postcss": { "builtin": { - "util.inherits": true + "fs": true, + "path": true }, "globals": { - "process.nextTick": true + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true }, "packages": { - "gulp>vinyl-fs>to-through>through2>readable-stream": true, - "watchify>xtend": true + "stylelint>postcss-less>postcss>picocolors": true, + "stylelint>postcss-less>postcss>source-map": true } }, - "gulp>vinyl-fs>to-through>through2>readable-stream": { + "stylelint>postcss-safe-parser>postcss": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs": true, + "path": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true }, "packages": { - "gulp>vinyl-fs>to-through>through2>readable-stream>isarray": true, - "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": true, - "gulp>vinyl-fs>to-through>through2>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "gulp>vinyl-fs>to-through>through2>readable-stream>string_decoder": { - "packages": { - "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": true + "stylelint>postcss-safe-parser>postcss>picocolors": true, + "stylelint>postcss-safe-parser>postcss>source-map": true } }, - "gulp>vinyl-fs>vinyl-sourcemap": { + "stylelint>postcss-sass>postcss": { "builtin": { - "path.dirname": true, - "path.join": true, - "path.relative": true, - "path.resolve": true + "fs": true, + "path": true }, "globals": { - "Buffer": true + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true }, "packages": { - "del>graceful-fs": true, - "gulp-watch>anymatch>normalize-path": true, - "gulp>vinyl-fs>remove-bom-buffer": true, - "gulp>vinyl-fs>vinyl-sourcemap>append-buffer": true, - "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": true, - "nyc>convert-source-map": true, - "vinyl": true + "stylelint>postcss-sass>postcss>picocolors": true, + "stylelint>postcss-sass>postcss>source-map": true } }, - "gulp>vinyl-fs>vinyl-sourcemap>append-buffer": { + "stylelint>postcss-scss>postcss": { "builtin": { - "os.EOL": true + "fs": true, + "path": true }, "globals": { - "Buffer": true + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true }, "packages": { - "gulp>vinyl-fs>vinyl-sourcemap>append-buffer>buffer-equal": true + "stylelint>postcss-scss>postcss>picocolors": true, + "stylelint>postcss-scss>postcss>source-map": true } }, - "gulp>vinyl-fs>vinyl-sourcemap>append-buffer>buffer-equal": { + "stylelint>postcss": { "builtin": { - "buffer.Buffer.isBuffer": true - } - }, - "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": { - "packages": { - "@metamask/object-multiplex>once": true - } - }, - "ini": { - "globals": { - "process": true - } - }, - "jsdom>acorn": { + "fs": true, + "path": true + }, "globals": { + "Buffer": true, + "atob": true, + "btoa": true, "console": true, - "define": true - } - }, - "koa>content-disposition>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "koa>is-generator-function>has-tostringtag": { - "packages": { - "string.prototype.matchall>has-symbols": true - } - }, - "labeled-stream-splicer": { - "packages": { - "labeled-stream-splicer>stream-splicer": true, - "pumpify>inherits": true - } - }, - "labeled-stream-splicer>stream-splicer": { - "globals": { - "process.nextTick": true, - "setImmediate": true + "process.env.NODE_ENV": true }, "packages": { - "labeled-stream-splicer>stream-splicer>readable-stream": true, - "pumpify>inherits": true + "stylelint>postcss>picocolors": true, + "stylelint>postcss>source-map": true } }, - "labeled-stream-splicer>stream-splicer>readable-stream": { + "stylelint>sugarss>postcss": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "fs": true, + "path": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer": true, + "atob": true, + "btoa": true, + "console": true, + "process.env.NODE_ENV": true }, "packages": { - "labeled-stream-splicer>stream-splicer>readable-stream>isarray": true, - "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": true, - "labeled-stream-splicer>stream-splicer>readable-stream>string_decoder": true, - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true - } - }, - "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "labeled-stream-splicer>stream-splicer>readable-stream>string_decoder": { - "packages": { - "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": true + "stylelint>sugarss>postcss>picocolors": true, + "stylelint>sugarss>postcss>source-map": true } }, - "lavamoat-browserify": { + "prettier": { "builtin": { - "fs.existsSync": true, - "fs.mkdirSync": true, - "fs.readFileSync": true, - "fs.writeFileSync": true, - "path.dirname": true, - "path.extname": true, - "path.resolve": true, - "util.callbackify": true + "assert": true, + "events.EventEmitter": true, + "fs": true, + "module._nodeModulePaths": true, + "module._resolveFilename": true, + "os": true, + "path": true, + "stream.PassThrough": true, + "stream.Readable": true, + "util.inherits": true, + "util.inspect": true, + "util.promisify": true }, "globals": { - "console.warn": true, - "process.cwd": true, - "setTimeout": true - }, - "packages": { - "@lavamoat/lavapack": true, - "@lavamoat/lavapack>json-stable-stringify": true, - "browserify>browser-resolve": true, - "lavamoat-browserify>concat-stream": true, - "lavamoat-browserify>duplexify": true, - "lavamoat-viz>lavamoat-core": true, - "lavamoat>@lavamoat/aa": true, - "readable-stream": true, - "through2": true - } - }, - "lavamoat-browserify>concat-stream": { - "globals": { - "Buffer.concat": true, - "Buffer.isBuffer": true - }, - "packages": { - "browserify>concat-stream>typedarray": true, - "pumpify>inherits": true, - "readable-stream": true, - "terser>source-map-support>buffer-from": true - } - }, - "lavamoat-browserify>duplexify": { - "globals": { + "ANONYMOUS": true, "Buffer": true, - "process.nextTick": true - }, - "packages": { - "duplexify>end-of-stream": true, - "duplexify>stream-shift": true, - "pumpify>inherits": true, - "readable-stream": true - } - }, - "lavamoat-viz>lavamoat-core": { - "builtin": { - "node:events": true, - "node:fs.readFileSync": true, - "node:fs/promises.writeFile": true, - "node:path.extname": true, - "node:path.join": true - }, - "globals": { + "BuilderFileEmit": true, + "BuilderProgramKind": true, + "BuilderState": true, + "CheckMode": true, + "ClassificationType": true, + "ClassificationTypeNames": true, + "CompletionInfoFlags": true, + "CompletionTriggerKind": true, + "ConfigFileProgramReloadLevel": true, + "CoreServicesShimHostAdapter": true, + "DocumentHighlights": true, + "Element": true, + "EndOfLineState": true, + "ExportKind": true, + "FileSystemEntryKind": true, + "FileWatcherEventKind": true, + "FlattenLevel": true, + "ForegroundColorEscapeSequences": true, + "HTMLElement": true, + "HighlightSpanKind": true, + "ImportKind": true, + "IndentStyle": true, + "InlayHintKind": true, + "Intl": true, + "InvalidatedProjectKind": true, + "LanguageServiceMode": true, + "LanguageServiceShimHostAdapter": true, + "ModuleInstanceState": true, + "NodeResolutionFeatures": true, + "OrganizeImportsMode": true, + "OutliningSpanKind": true, + "OutputFileType": true, + "PackageJsonAutoImportPreference": true, + "PackageJsonDependencyGroup": true, + "PatternMatchKind": true, + "PollingInterval": true, + "PrivateIdentifierKind": true, + "ProcessLevel": true, + "QuotePreference": true, + "SVGElement": true, + "ScriptElementKind": true, + "ScriptElementKindModifier": true, + "ScriptSnapshot": true, + "SemanticClassificationFormat": true, + "SemanticMeaning": true, + "SemicolonPreference": true, + "SignatureCheckMode": true, + "SymbolDisplayPartKind": true, + "TokenClass": true, + "TypeFacts": true, + "TypeScriptServicesFactory": true, + "UpToDateStatusType": true, + "Version": true, + "VersionRange": true, + "WatchLogLevel": true, + "WatchType": true, + "WorkerGlobalScope": true, + "YAML_SILENCE_DEPRECATION_WARNINGS": true, + "YAML_SILENCE_WARNINGS": true, "__dirname": true, - "console.error": true, - "console.warn": true, - "define": true - }, - "packages": { - "@lavamoat/lavapack>json-stable-stringify": true, - "lavamoat-viz>lavamoat-core>lavamoat-tofu": true, - "lavamoat>lavamoat-core>merge-deep": true - } - }, - "lavamoat-viz>lavamoat-core>lavamoat-tofu": { - "globals": { - "console.log": true - }, - "packages": { - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/parser": true, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse": true - } - }, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse": { - "globals": { - "console.log": true - }, - "packages": { - "@babel/code-frame": true, - "@babel/core>@babel/generator": true, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse>@babel/parser": true, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse>@babel/types": true, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse>globals": true, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-environment-visitor": true, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-function-name": true, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-hoist-variables": true, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-split-export-declaration": true, - "nock>debug": true - } - }, - "lavamoat-viz>lavamoat-core>lavamoat-tofu>@babel/traverse>@babel/types": { - "globals": { - "console.warn": true, - "process.env": true - }, - "packages": { - "@babel/core>@babel/types>@babel/helper-string-parser": true, - "lavamoat>@babel/highlight>@babel/helper-validator-identifier": true - } - }, - "lavamoat>@lavamoat/aa": { - "builtin": { - "node:fs.lstatSync": true, - "node:fs.readFileSync": true, - "node:fs.realpathSync": true, - "node:path.dirname": true, - "node:path.join": true, - "node:path.relative": true - }, - "packages": { - "depcheck>resolve": true - } - }, - "lavamoat>lavamoat-core>merge-deep": { - "packages": { - "gulp-zip>plugin-error>arr-union": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep": true, - "lavamoat>lavamoat-core>merge-deep>kind-of": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep": { - "packages": { - "@babel/register>clone-deep>is-plain-object": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>for-own": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>lazy-cache": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone": true, - "lavamoat>lavamoat-core>merge-deep>kind-of": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>for-own": { - "packages": { - "gulp>undertaker>object.reduce>for-own>for-in": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>lazy-cache": { - "globals": { - "process.env.TRAVIS": true, - "process.env.UNLAZY": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>kind-of": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>lazy-cache": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>kind-of": { - "globals": { - "Buffer": true - }, - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>lazy-cache": { - "globals": { - "process.env.UNLAZY": true - } - }, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": { - "packages": { - "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, - "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object>for-in": true - } - }, - "lavamoat>lavamoat-core>merge-deep>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-function-name": { - "packages": { - "@babel/core>@babel/template": true, - "@babel/core>@babel/types": true - } - }, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-hoist-variables": { - "packages": { - "@babel/core>@babel/types": true - } - }, - "lavamoat>lavamoat-tofu>@babel/traverse>@babel/helper-split-export-declaration": { - "packages": { - "@babel/core>@babel/types": true - } - }, - "lodash": { - "globals": { - "define": true - } - }, - "loose-envify": { - "builtin": { - "stream.PassThrough": true, - "stream.Transform": true, - "util.inherits": true - }, - "globals": { - "process.env": true - }, - "packages": { - "loose-envify>js-tokens": true - } - }, - "mocha>find-up": { - "builtin": { - "path.dirname": true, - "path.parse": true, - "path.resolve": true - }, - "packages": { - "mocha>find-up>locate-path": true, - "nyc>find-up>path-exists": true - } - }, - "mocha>find-up>locate-path": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.resolve": true, - "util.promisify": true - }, - "globals": { - "process.cwd": true - }, - "packages": { - "mocha>find-up>locate-path>p-locate": true - } - }, - "mocha>find-up>locate-path>p-locate": { - "packages": { - "@storybook/test-runner>jest-circus>p-limit": true - } - }, - "mocha>log-symbols": { - "packages": { - "chalk": true, - "mocha>log-symbols>is-unicode-supported": true - } - }, - "mocha>log-symbols>is-unicode-supported": { - "globals": { - "process.env.CI": true, - "process.env.TERM": true, - "process.env.TERM_PROGRAM": true, - "process.env.WT_SESSION": true, - "process.platform": true - } - }, - "mocha>supports-color": { - "builtin": { - "os.release": true, - "tty.isatty": true - }, - "globals": { - "process.env": true, - "process.platform": true - }, - "packages": { - "mocha>supports-color>has-flag": true - } - }, - "mocha>supports-color>has-flag": { - "globals": { - "process.argv": true - } - }, - "mockttp>portfinder>mkdirp": { - "builtin": { - "fs": true, - "path.dirname": true, - "path.resolve": true - } - }, - "nock>debug": { - "builtin": { - "tty.isatty": true, - "util.deprecate": true, - "util.formatWithOptions": true, - "util.inspect": true - }, - "globals": { - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, - "packages": { - "mocha>supports-color": true, - "nock>debug>ms": true - } - }, - "node-sass": { - "native": true - }, - "nyc>convert-source-map": { - "builtin": { - "fs.readFileSync": true, - "path.join": true - }, - "globals": { - "Buffer.from": true - } - }, - "nyc>find-up>path-exists": { - "builtin": { - "fs.access": true, - "fs.accessSync": true, - "util.promisify": true - } - }, - "nyc>glob": { - "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs": true, - "path.join": true, - "path.resolve": true, - "util": true - }, - "globals": { - "console.error": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true - }, - "packages": { - "@metamask/object-multiplex>once": true, - "eslint>minimatch": true, - "gulp-watch>path-is-absolute": true, - "nyc>glob>fs.realpath": true, - "nyc>glob>inflight": true, - "pumpify>inherits": true - } - }, - "nyc>glob>fs.realpath": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readlink": true, - "fs.readlinkSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.normalize": true, - "path.resolve": true - }, - "globals": { - "console.error": true, - "console.trace": true, - "process.env.NODE_DEBUG": true, - "process.nextTick": true, - "process.noDeprecation": true, - "process.platform": true, - "process.throwDeprecation": true, - "process.traceDeprecation": true, - "process.version": true - } - }, - "nyc>glob>inflight": { - "globals": { - "process.nextTick": true - }, - "packages": { - "@metamask/object-multiplex>once": true, - "@metamask/object-multiplex>once>wrappy": true - } - }, - "nyc>resolve-from": { - "builtin": { - "fs.realpathSync": true, - "module._nodeModulePaths": true, - "module._resolveFilename": true, - "path.join": true, - "path.resolve": true - } - }, - "nyc>signal-exit": { - "builtin": { - "assert.equal": true, - "events": true - }, - "globals": { - "process": true - } - }, - "nyc>spawn-wrap>is-windows": { - "globals": { - "define": true, - "isWindows": "write", - "process": true - } - }, - "nyc>yargs>set-blocking": { - "globals": { - "process.stderr": true, - "process.stdout": true - } - }, - "postcss": { - "builtin": { - "fs.existsSync": true, - "fs.readFileSync": true, - "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true, - "url.fileURLToPath": true, - "url.pathToFileURL": true - }, - "globals": { - "Buffer": true, - "URL": true, + "__filename": true, + "accessPrivateIdentifier": true, + "addEmitFlags": true, + "addEmitHelper": true, + "addEmitHelpers": true, + "addInternalEmitFlags": true, + "addSyntheticLeadingComment": true, + "addSyntheticTrailingComment": true, + "advancedAsyncSuperHelper": true, + "affectsDeclarationPathOptionDeclarations": true, + "affectsEmitOptionDeclarations": true, + "allKeysStartWithDot": true, + "assertDoc": true, + "assignHelper": true, + "asyncDelegator": true, + "asyncGeneratorHelper": true, + "asyncSuperHelper": true, + "asyncValues": true, "atob": true, + "awaitHelper": true, + "awaiterHelper": true, + "bindSourceFile": true, + "breakIntoCharacterSpans": true, + "breakIntoWordSpans": true, "btoa": true, - "console": true, - "process.env.LANG": true, - "process.env.NODE_ENV": true - }, - "packages": { - "nanoid": true, - "postcss>picocolors": true, - "postcss>source-map-js": true - } - }, - "postcss-discard-font-face": { - "packages": { - "postcss-discard-font-face>balanced-match": true, - "postcss-discard-font-face>postcss": true - } - }, - "postcss-discard-font-face>postcss": { - "builtin": { - "fs": true, - "path": true - }, - "globals": { - "console": true - }, - "packages": { - "postcss-discard-font-face>postcss>chalk": true, - "postcss-discard-font-face>postcss>js-base64": true, - "postcss-discard-font-face>postcss>source-map": true, - "postcss-discard-font-face>postcss>supports-color": true - } - }, - "postcss-discard-font-face>postcss>chalk": { - "globals": { - "process.env.TERM": true, - "process.platform": true - }, - "packages": { - "postcss-discard-font-face>postcss>chalk>ansi-styles": true, - "postcss-discard-font-face>postcss>chalk>escape-string-regexp": true, - "postcss-discard-font-face>postcss>chalk>strip-ansi": true, - "postcss-discard-font-face>postcss>chalk>supports-color": true, - "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi": true - } - }, - "postcss-discard-font-face>postcss>chalk>strip-ansi": { - "packages": { - "postcss-discard-font-face>postcss>chalk>strip-ansi>ansi-regex": true - } - }, - "postcss-discard-font-face>postcss>chalk>supports-color": { - "globals": { - "process.argv": true, - "process.env": true, - "process.platform": true, - "process.stdout": true - } - }, - "postcss-discard-font-face>postcss>js-base64": { - "globals": { - "Base64": "write", - "define": true - } - }, - "postcss-discard-font-face>postcss>supports-color": { - "globals": { - "process": true - }, - "packages": { - "postcss-discard-font-face>postcss>supports-color>has-flag": true - } - }, - "postcss-discard-font-face>postcss>supports-color>has-flag": { - "globals": { - "process.argv": true - } - }, - "postcss-rtlcss": { - "globals": { - "SuppressedError": true - }, - "packages": { - "postcss": true, - "postcss-rtlcss>rtlcss": true - } - }, - "postcss-rtlcss>rtlcss": { - "packages": { - "postcss": true - } - }, - "postcss>picocolors": { - "globals": { - "process": true - } - }, - "postcss>source-map-js": { - "globals": { - "console": true - } - }, - "prettier": { - "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs": true, - "module._nodeModulePaths": true, - "module._resolveFilename": true, - "os": true, - "path": true, - "stream.PassThrough": true, - "stream.Readable": true, - "util.inherits": true, - "util.inspect": true, - "util.promisify": true - }, - "globals": { - "ANONYMOUS": true, - "Buffer": true, - "BuilderFileEmit": true, - "BuilderProgramKind": true, - "BuilderState": true, - "CheckMode": true, - "ClassificationType": true, - "ClassificationTypeNames": true, - "CompletionInfoFlags": true, - "CompletionTriggerKind": true, - "ConfigFileProgramReloadLevel": true, - "CoreServicesShimHostAdapter": true, - "DocumentHighlights": true, - "Element": true, - "EndOfLineState": true, - "ExportKind": true, - "FileSystemEntryKind": true, - "FileWatcherEventKind": true, - "FlattenLevel": true, - "ForegroundColorEscapeSequences": true, - "HTMLElement": true, - "HighlightSpanKind": true, - "ImportKind": true, - "IndentStyle": true, - "InlayHintKind": true, - "Intl": true, - "InvalidatedProjectKind": true, - "LanguageServiceMode": true, - "LanguageServiceShimHostAdapter": true, - "ModuleInstanceState": true, - "NodeResolutionFeatures": true, - "OrganizeImportsMode": true, - "OutliningSpanKind": true, - "OutputFileType": true, - "PackageJsonAutoImportPreference": true, - "PackageJsonDependencyGroup": true, - "PatternMatchKind": true, - "PollingInterval": true, - "PrivateIdentifierKind": true, - "ProcessLevel": true, - "QuotePreference": true, - "SVGElement": true, - "ScriptElementKind": true, - "ScriptElementKindModifier": true, - "ScriptSnapshot": true, - "SemanticClassificationFormat": true, - "SemanticMeaning": true, - "SemicolonPreference": true, - "SignatureCheckMode": true, - "SymbolDisplayPartKind": true, - "TokenClass": true, - "TypeFacts": true, - "TypeScriptServicesFactory": true, - "UpToDateStatusType": true, - "Version": true, - "VersionRange": true, - "WatchLogLevel": true, - "WatchType": true, - "WorkerGlobalScope": true, - "YAML_SILENCE_DEPRECATION_WARNINGS": true, - "YAML_SILENCE_WARNINGS": true, - "__dirname": true, - "__filename": true, - "accessPrivateIdentifier": true, - "addEmitFlags": true, - "addEmitHelper": true, - "addEmitHelpers": true, - "addInternalEmitFlags": true, - "addSyntheticLeadingComment": true, - "addSyntheticTrailingComment": true, - "advancedAsyncSuperHelper": true, - "affectsDeclarationPathOptionDeclarations": true, - "affectsEmitOptionDeclarations": true, - "allKeysStartWithDot": true, - "assertDoc": true, - "assignHelper": true, - "asyncDelegator": true, - "asyncGeneratorHelper": true, - "asyncSuperHelper": true, - "asyncValues": true, - "atob": true, - "awaitHelper": true, - "awaiterHelper": true, - "bindSourceFile": true, - "breakIntoCharacterSpans": true, - "breakIntoWordSpans": true, - "btoa": true, - "buildLinkParts": true, - "buildOpts": true, - "buildOverload": true, - "bundlerModuleNameResolver": true, - "canBeConvertedToAsync": true, - "canJsonReportNoInputFiles": true, - "canProduceDiagnostics": true, - "canWatchDirectoryOrFile": true, - "chainBundle": true, - "changeCompilerHostLikeToUseCache": true, - "classPrivateFieldGetHelper": true, - "classPrivateFieldInHelper": true, - "classPrivateFieldSetHelper": true, - "classicNameResolver": true, - "cleanExtendedConfigCache": true, - "clearSharedExtendedConfigFileWatcher": true, - "clearTimeout": true, - "climbPastPropertyAccess": true, - "climbPastPropertyOrElementAccess": true, - "cloneCompilerOptions": true, - "closeFileWatcherOf": true, - "collectExternalModuleInfo": true, - "commonOptionsWithBuild": true, - "compareEmitHelpers": true, - "comparePatternKeys": true, - "compileOnSaveCommandLineOption": true, - "compilerOptionsDidYouMeanDiagnostics": true, - "compilerOptionsIndicateEsModules": true, - "computeCommonSourceDirectoryOfFilenames": true, - "computeSignature": true, - "computeSignatureWithDiagnostics": true, - "computeSuggestionDiagnostics": true, + "buildLinkParts": true, + "buildOpts": true, + "buildOverload": true, + "bundlerModuleNameResolver": true, + "canBeConvertedToAsync": true, + "canJsonReportNoInputFiles": true, + "canProduceDiagnostics": true, + "canWatchDirectoryOrFile": true, + "chainBundle": true, + "changeCompilerHostLikeToUseCache": true, + "classPrivateFieldGetHelper": true, + "classPrivateFieldInHelper": true, + "classPrivateFieldSetHelper": true, + "classicNameResolver": true, + "cleanExtendedConfigCache": true, + "clearSharedExtendedConfigFileWatcher": true, + "clearTimeout": true, + "climbPastPropertyAccess": true, + "climbPastPropertyOrElementAccess": true, + "cloneCompilerOptions": true, + "closeFileWatcherOf": true, + "collectExternalModuleInfo": true, + "commonOptionsWithBuild": true, + "compareEmitHelpers": true, + "comparePatternKeys": true, + "compileOnSaveCommandLineOption": true, + "compilerOptionsDidYouMeanDiagnostics": true, + "compilerOptionsIndicateEsModules": true, + "computeCommonSourceDirectoryOfFilenames": true, + "computeSignature": true, + "computeSignatureWithDiagnostics": true, + "computeSuggestionDiagnostics": true, "console": true, "consumesNodeCoreModules": true, "convertCompilerOptionsForTelemetry": true, @@ -7399,208 +6163,1361 @@ "zipToModeAwareCache": true } }, - "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi": { + "eslint-plugin-prettier>prettier-linter-helpers": { + "packages": { + "eslint-plugin-prettier>prettier-linter-helpers>fast-diff": true + } + }, + "process": { + "globals": { + "process": true + } + }, + "vinyl>cloneable-readable>process-nextick-args": { + "globals": { + "process.nextTick": true, + "process.version": true + } + }, + "readable-stream-2>process-nextick-args": { + "globals": { + "process": true + } + }, + "vinyl>cloneable-readable>through2>readable-stream>process-nextick-args": { + "globals": { + "process": true + } + }, + "prop-types": { + "globals": { + "console": true, + "process.env.NODE_ENV": true + }, + "packages": { + "react>object-assign": true, + "prop-types>react-is": true + } + }, + "pumpify>pump": { + "builtin": { + "fs": true + }, + "globals": { + "process.version": true + }, + "packages": { + "duplexify>end-of-stream": true, + "@metamask/object-multiplex>once": true + } + }, + "gulp>vinyl-fs>glob-stream>pumpify>pump": { + "builtin": { + "fs": true + }, + "packages": { + "duplexify>end-of-stream": true, + "@metamask/object-multiplex>once": true + } + }, + "gulp>vinyl-fs>pumpify>pump": { + "builtin": { + "fs": true + }, + "packages": { + "duplexify>end-of-stream": true, + "@metamask/object-multiplex>once": true + } + }, + "pumpify": { + "packages": { + "duplexify": true, + "pumpify>inherits": true, + "pumpify>pump": true + } + }, + "gulp>vinyl-fs>glob-stream>pumpify": { + "packages": { + "gulp>vinyl-fs>glob-stream>pumpify>duplexify": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>glob-stream>pumpify>pump": true + } + }, + "gulp>vinyl-fs>pumpify": { + "packages": { + "gulp>vinyl-fs>pumpify>duplexify": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>pumpify>pump": true + } + }, + "@storybook/addon-knobs>qs": { + "packages": { + "string.prototype.matchall>side-channel": true + } + }, + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic": { + "packages": { + "gulp>undertaker>bach>array-last>is-number": true, + "@babel/register>clone-deep>kind-of": true, + "gulp-watch>anymatch>micromatch>braces>expand-range>fill-range>randomatic>math-random": true + } + }, + "randomcolor": { + "globals": { + "define": true + } + }, + "gulp-livereload>tiny-lr>body>raw-body": { + "globals": { + "Buffer.concat": true, + "process.nextTick": true + }, + "packages": { + "gulp-livereload>tiny-lr>body>raw-body>bytes": true, + "gulp-livereload>tiny-lr>body>raw-body>string_decoder": true + } + }, + "prop-types>react-is": { + "globals": { + "console": true, + "process.env.NODE_ENV": true + } + }, + "browserify>read-only-stream": { + "packages": { + "browserify>read-only-stream>readable-stream": true + } + }, + "readable-stream": { + "builtin": { + "buffer.Buffer": true, + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.env.READABLE_STREAM": true, + "process.nextTick": true, + "process.stderr": true, + "process.stdout": true + }, + "packages": { + "pumpify>inherits": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "@lavamoat/lavapack>readable-stream": { + "builtin": { + "buffer.Blob": true, + "buffer.Buffer": true, + "events.EventEmitter": true, + "events.addAbortListener": true, + "stream": true, + "string_decoder.StringDecoder": true + }, + "globals": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "process.env.READABLE_STREAM": true, + "queueMicrotask": true + }, + "packages": { + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "process": true + } + }, + "vinyl-buffer>bl>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "vinyl-buffer>bl>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "vinyl-buffer>bl>readable-stream>safe-buffer": true, + "vinyl-buffer>bl>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>readable-stream>safe-buffer": true, + "browserify>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>concat-stream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>concat-stream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>concat-stream>readable-stream>safe-buffer": true, + "browserify>concat-stream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "lavamoat-browserify>concat-stream>readable-stream": { + "builtin": { + "buffer.Buffer": true, + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.env.READABLE_STREAM": true, + "process.nextTick": true, + "process.stderr": true, + "process.stdout": true + }, + "packages": { + "pumpify>inherits": true, + "browserify>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>duplexer2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>duplexer2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>duplexer2>readable-stream>safe-buffer": true, + "browserify>duplexer2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": true, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>glob-stream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>glob-stream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>glob-stream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp-watch>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp-watch>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp-watch>readable-stream>safe-buffer": true, + "gulp-watch>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "lavamoat-browserify>readable-stream": { + "builtin": { + "buffer.Blob": true, + "buffer.Buffer": true, + "events.EventEmitter": true, + "events.addAbortListener": true, + "stream": true, + "string_decoder.StringDecoder": true + }, + "globals": { + "AbortController": true, + "AbortSignal": true, + "AggregateError": true, + "Blob": true, + "ERR_INVALID_ARG_TYPE": true, + "process.env.READABLE_STREAM": true, + "queueMicrotask": true + }, + "packages": { + "@lavamoat/lavapack>readable-stream>abort-controller": true, + "process": true + } + }, + "gulp>vinyl-fs>lazystream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>lazystream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>lazystream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>module-deps>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>module-deps>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>module-deps>readable-stream>safe-buffer": true, + "browserify>module-deps>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>read-only-stream>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>read-only-stream>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>read-only-stream>readable-stream>safe-buffer": true, + "browserify>read-only-stream>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>module-deps>stream-combiner2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>module-deps>stream-combiner2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": true, + "browserify>module-deps>stream-combiner2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "labeled-stream-splicer>stream-splicer>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "labeled-stream-splicer>stream-splicer>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": true, + "labeled-stream-splicer>stream-splicer>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": true, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>browser-pack>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>browser-pack>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>browser-pack>through2>readable-stream>safe-buffer": true, + "browserify>browser-pack>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "vinyl>cloneable-readable>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "vinyl>cloneable-readable>through2>readable-stream>isarray": true, + "vinyl>cloneable-readable>through2>readable-stream>process-nextick-args": true, + "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": true, + "vinyl>cloneable-readable>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>deps-sort>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>deps-sort>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>deps-sort>through2>readable-stream>safe-buffer": true, + "browserify>deps-sort>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp-sort>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp-sort>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp-sort>through2>readable-stream>safe-buffer": true, + "gulp-sort>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp-sourcemaps>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp-sourcemaps>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp-sourcemaps>through2>readable-stream>safe-buffer": true, + "gulp-sourcemaps>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "browserify>insert-module-globals>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "browserify>insert-module-globals>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "browserify>insert-module-globals>through2>readable-stream>safe-buffer": true, + "browserify>insert-module-globals>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>to-through>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>to-through>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>to-through>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "vinyl-source-stream>through2>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "vinyl-source-stream>through2>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "vinyl-source-stream>through2>readable-stream>safe-buffer": true, + "vinyl-source-stream>through2>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "gulp>vinyl-fs>readable-stream": { + "builtin": { + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.browser": true, + "process.env.READABLE_STREAM": true, + "process.stderr": true, + "process.stdout": true, + "process.version.slice": true, + "setImmediate": true + }, + "packages": { + "readable-stream-2>core-util-is": true, + "pumpify>inherits": true, + "gulp>vinyl-fs>readable-stream>isarray": true, + "readable-stream-2>process-nextick-args": true, + "gulp>vinyl-fs>readable-stream>safe-buffer": true, + "gulp>vinyl-fs>readable-stream>string_decoder": true, + "readable-stream>util-deprecate": true + } + }, + "chokidar>readdirp": { + "builtin": { + "fs": true, + "path.join": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true, + "stream.Readable": true, + "util.promisify": true + }, + "globals": { + "process.platform": true, + "process.versions.node.split": true + }, + "packages": { + "chokidar>anymatch>picomatch": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regenerate": { + "globals": { + "define": true + } + }, + "@babel/preset-env>@babel/plugin-transform-regenerator>regenerator-transform": { + "builtin": { + "assert": true, + "util.inherits": true + }, + "packages": { + "@babel/runtime": true + } + }, + "gulp-watch>anymatch>micromatch>regex-cache": { + "packages": { + "gulp-watch>anymatch>micromatch>regex-cache>is-equal-shallow": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>regex-not": { + "packages": { + "gulp-zip>plugin-error>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": true + } + }, + "string.prototype.matchall>regexp.prototype.flags": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core": { + "globals": { + "characterClassItem.kind": true + }, + "packages": { + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regenerate": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsgen": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsparser": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-value-ecmascript": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsgen": { + "globals": { + "define": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>regjsparser": { + "globals": { + "regjsparser": "write" + } + }, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse": { + "packages": { + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>ccount": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>collapse-white-space": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-alphabetical": true, + "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-whitespace-character": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-word-character": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>markdown-escapes": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>state-toggle": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>trim-trailing-lines": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>trim": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unist-util-remove-position": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>vfile-location": true, + "watchify>xtend": true + } + }, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify": { + "packages": { + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>ccount": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>is-alphanumeric": true, + "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-whitespace-character": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>longest-streak": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>markdown-escapes": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>markdown-table": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>mdast-util-compact": true, + "react-syntax-highlighter>refractor>parse-entities": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>state-toggle": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": true, + "watchify>xtend": true + } + }, + "stylelint>@stylelint/postcss-markdown>remark": { + "packages": { + "stylelint>@stylelint/postcss-markdown>remark>remark-parse": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify": true, + "react-markdown>unified": true + } + }, + "gulp>vinyl-fs>remove-bom-buffer": { + "packages": { + "browserify>insert-module-globals>is-buffer": true, + "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true + } + }, + "gulp>vinyl-fs>remove-bom-stream": { + "packages": { + "gulp>vinyl-fs>remove-bom-buffer": true, + "koa>content-disposition>safe-buffer": true, + "gulp>vinyl-fs>remove-bom-stream>through2": true + } + }, + "vinyl>remove-trailing-separator": { + "globals": { + "process.platform": true + } + }, + "gulp-sass>replace-ext": { + "builtin": { + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.sep": true + } + }, + "react-markdown>vfile>replace-ext": { + "builtin": { + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true + } + }, + "vinyl>replace-ext": { + "builtin": { + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true, + "path.sep": true + } + }, + "gulp-watch>vinyl-file>vinyl>replace-ext": { + "builtin": { + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true + } + }, + "yargs>require-directory": { + "builtin": { + "fs.readdirSync": true, + "fs.statSync": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true + } + }, + "eslint>@eslint/eslintrc>import-fresh>resolve-from": { + "builtin": { + "fs.realpathSync": true, + "module._nodeModulePaths": true, + "module._resolveFilename": true, + "path.join": true, + "path.resolve": true + } + }, + "nyc>resolve-from": { + "builtin": { + "fs.realpathSync": true, + "module._nodeModulePaths": true, + "module._resolveFilename": true, + "path.join": true, + "path.resolve": true + } + }, + "gulp>vinyl-fs>resolve-options": { "packages": { - "prettier-eslint>loglevel-colored-level-prefix>chalk>has-ansi>ansi-regex": true + "gulp>vinyl-fs>value-or-function": true } }, - "prop-types": { + "depcheck>resolve": { + "builtin": { + "fs.readFile": true, + "fs.readFileSync": true, + "fs.realpath": true, + "fs.realpathSync": true, + "fs.stat": true, + "fs.statSync": true, + "os.homedir": true, + "path.dirname": true, + "path.join": true, + "path.parse": true, + "path.relative": true, + "path.resolve": true + }, "globals": { - "console": true, - "process.env.NODE_ENV": true + "process.env.HOME": true, + "process.env.HOMEDRIVE": true, + "process.env.HOMEPATH": true, + "process.env.LNAME": true, + "process.env.LOGNAME": true, + "process.env.USER": true, + "process.env.USERNAME": true, + "process.env.USERPROFILE": true, + "process.getuid": true, + "process.nextTick": true, + "process.platform": true, + "process.versions.pnp": true }, "packages": { - "prop-types>react-is": true, - "react>object-assign": true + "depcheck>is-core-module": true, + "depcheck>resolve>path-parse": true } }, - "prop-types>react-is": { + "eslint-plugin-react>resolve": { + "builtin": { + "fs.readFile": true, + "fs.readFileSync": true, + "fs.realpath": true, + "fs.realpathSync": true, + "fs.stat": true, + "fs.statSync": true, + "os.homedir": true, + "path.dirname": true, + "path.join": true, + "path.parse": true, + "path.relative": true, + "path.resolve": true + }, "globals": { - "console": true, - "process.env.NODE_ENV": true + "process.env.HOME": true, + "process.env.HOMEDRIVE": true, + "process.env.HOMEPATH": true, + "process.env.LNAME": true, + "process.env.LOGNAME": true, + "process.env.USER": true, + "process.env.USERNAME": true, + "process.env.USERPROFILE": true, + "process.getuid": true, + "process.nextTick": true, + "process.platform": true, + "process.versions.pnp": true + }, + "packages": { + "depcheck>is-core-module": true, + "depcheck>resolve>path-parse": true } }, - "pumpify": { + "del>rimraf": { + "builtin": { + "assert": true, + "fs": true, + "path.join": true + }, + "globals": { + "process.platform": true, + "setTimeout": true + }, "packages": { - "duplexify": true, - "pumpify>inherits": true, - "pumpify>pump": true + "nyc>glob": true } }, - "pumpify>inherits": { + "stylelint>file-entry-cache>flat-cache>rimraf": { "builtin": { - "util.inherits": true + "assert": true, + "fs": true, + "path.join": true + }, + "globals": { + "process.platform": true, + "setTimeout": true + }, + "packages": { + "nyc>glob": true } }, - "pumpify>pump": { + "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": { "builtin": { - "fs": true + "assert": true, + "fs": true, + "path.join": true }, "globals": { - "process.version": true + "process.platform": true, + "setTimeout": true }, "packages": { - "@metamask/object-multiplex>once": true, - "duplexify>end-of-stream": true + "nyc>glob": true } }, - "randomcolor": { + "postcss-rtlcss>rtlcss": { + "packages": { + "postcss": true + } + }, + "eslint>@nodelib/fs.walk>@nodelib/fs.scandir>run-parallel": { "globals": { - "define": true + "process.nextTick": true } }, - "react-markdown>unified": { - "packages": { - "mocha>yargs-unparser>is-plain-obj": true, - "react-markdown>unified>bail": true, - "react-markdown>unified>extend": true, - "react-markdown>unified>is-buffer": true, - "react-markdown>unified>trough": true, - "react-markdown>vfile": true + "wait-on>rxjs": { + "globals": { + "cancelAnimationFrame": true, + "clearInterval": true, + "clearTimeout": true, + "performance": true, + "requestAnimationFrame": true, + "setInterval.apply": true, + "setTimeout.apply": true } }, - "react-markdown>unist-util-visit": { - "packages": { - "react-markdown>unist-util-visit>unist-util-visit-parents": true + "koa>content-disposition>safe-buffer": { + "builtin": { + "buffer": true } }, - "react-markdown>unist-util-visit>unist-util-visit-parents": { - "packages": { - "react-markdown>unist-util-visit>unist-util-is": true + "vinyl-buffer>bl>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "react-markdown>vfile": { + "browserify>readable-stream>safe-buffer": { "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.sep": true - }, - "globals": { - "process.cwd": true - }, - "packages": { - "react-markdown>vfile>is-buffer": true, - "react-markdown>vfile>replace-ext": true, - "react-markdown>vfile>vfile-message": true + "buffer": true } }, - "react-markdown>vfile>replace-ext": { + "browserify>concat-stream>readable-stream>safe-buffer": { "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true + "buffer": true } }, - "react-markdown>vfile>vfile-message": { - "packages": { - "react-markdown>vfile>unist-util-stringify-position": true + "browserify>duplexer2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "react-syntax-highlighter>refractor>parse-entities": { - "packages": { - "react-syntax-highlighter>refractor>parse-entities>character-entities": true, - "react-syntax-highlighter>refractor>parse-entities>character-entities-legacy": true, - "react-syntax-highlighter>refractor>parse-entities>character-reference-invalid": true, - "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": true, - "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, - "react-syntax-highlighter>refractor>parse-entities>is-hexadecimal": true + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp-watch>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "browserify>module-deps>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "browserify>read-only-stream>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "browserify>browser-pack>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "browserify>deps-sort>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true + } + }, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": { - "packages": { - "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-alphabetical": true + "gulp-sort>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "readable-stream": { + "gulp-sourcemaps>through2>readable-stream>safe-buffer": { "builtin": { - "buffer.Buffer": true, - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.env.READABLE_STREAM": true, - "process.nextTick": true, - "process.stderr": true, - "process.stdout": true - }, - "packages": { - "browserify>string_decoder": true, - "pumpify>inherits": true, - "readable-stream>util-deprecate": true + "buffer": true } }, - "readable-stream-2>core-util-is": { - "globals": { - "Buffer.isBuffer": true + "browserify>insert-module-globals>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "readable-stream-2>process-nextick-args": { - "globals": { - "process": true + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "readable-stream>util-deprecate": { + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": { "builtin": { - "util.deprecate": true + "buffer": true } }, - "resolve-url-loader>es6-iterator": { - "packages": { - "resolve-url-loader>es6-iterator>d": true, - "resolve-url-loader>es6-iterator>es5-ext": true, - "resolve-url-loader>es6-iterator>es6-symbol": true + "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "resolve-url-loader>es6-iterator>d": { - "packages": { - "resolve-url-loader>es6-iterator>d>type": true, - "resolve-url-loader>es6-iterator>es5-ext": true + "vinyl-source-stream>through2>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "resolve-url-loader>es6-iterator>es5-ext": { - "packages": { - "resolve-url-loader>es6-iterator>es6-symbol": true + "gulp>vinyl-fs>readable-stream>safe-buffer": { + "builtin": { + "buffer": true } }, - "resolve-url-loader>es6-iterator>es6-symbol": { - "packages": { - "resolve-url-loader>es6-iterator>d": true, - "resolve-url-loader>es6-iterator>es6-symbol>ext": true + "vinyl-buffer>bl>readable-stream>string_decoder>safe-buffer": { + "builtin": { + "buffer": true } }, - "resolve-url-loader>es6-iterator>es6-symbol>ext": { - "globals": { - "__global__": true + "browserify>browser-pack>through2>readable-stream>string_decoder>safe-buffer": { + "builtin": { + "buffer": true } }, - "resolve-url-loader>rework>css>source-map-resolve": { + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder>safe-buffer": { "builtin": { - "url.resolve": true - }, - "globals": { - "TextDecoder": true, - "setImmediate": true - }, - "packages": { - "gulp-sourcemaps>css>source-map-resolve>atob": true, - "gulp-sourcemaps>css>source-map-resolve>decode-uri-component": true, - "resolve-url-loader>rework>css>source-map-resolve>source-map-url": true, - "resolve-url-loader>rework>css>urix": true + "buffer": true } }, - "resolve-url-loader>rework>css>source-map-resolve>source-map-url": { - "globals": { - "define": true + "string.prototype.matchall>es-abstract>safe-regex-test": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>is-regex": true } }, - "resolve-url-loader>rework>css>urix": { - "builtin": { - "path.sep": true + "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex>ret": true } }, "sass": { @@ -7651,37 +7568,183 @@ "process.stderr.write": true }, "packages": { - "mocha>supports-color": true, "sass-embedded>@bufbuild/protobuf": true, "sass-embedded>buffer-builder": true, "sass-embedded>immutable": true, - "sass-embedded>varint": true, - "wait-on>rxjs": true + "wait-on>rxjs": true, + "mocha>supports-color": true, + "sass-embedded>varint": true } }, - "sass-embedded>@bufbuild/protobuf": { + "semver": { "globals": { - "TextDecoder": true, - "TextEncoder": true, - "__values": true, + "console.error": true, "process": true } }, - "sass-embedded>buffer-builder": { + "@babel/core>semver": { "globals": { - "Buffer": true + "console": true, + "process": true } }, - "sass-embedded>immutable": { + "@babel/eslint-parser>semver": { "globals": { "console": true, - "define": true + "process": true } }, - "semver": { + "@babel/core>@babel/helper-compilation-targets>semver": { + "globals": { + "console": true, + "process": true + } + }, + "@babel/preset-env>@babel/plugin-transform-private-methods>@babel/helper-create-class-features-plugin>semver": { + "globals": { + "console": true, + "process": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>semver": { + "globals": { + "console": true, + "process": true + } + }, + "@babel/preset-env>semver": { + "globals": { + "console": true, + "process": true + } + }, + "@babel/preset-env>babel-plugin-polyfill-corejs2>semver": { + "globals": { + "console": true, + "process": true + } + }, + "eslint-plugin-node>semver": { + "globals": { + "console": true, + "process": true + } + }, + "eslint-plugin-react>semver": { + "globals": { + "console": true, + "process": true + } + }, + "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": { + "globals": { + "console": true, + "process": true + } + }, + "nyc>yargs>set-blocking": { + "globals": { + "process.stderr": true, + "process.stdout": true + } + }, + "string.prototype.matchall>call-bind>set-function-length": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>gopd": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true + } + }, + "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "packages": { + "string.prototype.matchall>define-properties>define-data-property": true, + "string.prototype.matchall>call-bind>es-errors": true, + "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, + "string.prototype.matchall>es-abstract>has-property-descriptors": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value>extend-shallow": true, + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, + "@babel/register>clone-deep>is-plain-object": true, + "gulp>gulp-cli>matchdep>micromatch>braces>split-string": true + } + }, + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone": { + "packages": { + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>kind-of": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>lazy-cache": true, + "lavamoat>lavamoat-core>merge-deep>clone-deep>shallow-clone>mixin-object": true + } + }, + "browserify>shasum-object": { + "builtin": { + "crypto.createHash": true + }, + "globals": { + "Buffer.isBuffer": true + }, + "packages": { + "@metamask/rpc-errors>fast-safe-stringify": true + } + }, + "string.prototype.matchall>side-channel": { + "packages": { + "string.prototype.matchall>call-bind": true, + "string.prototype.matchall>get-intrinsic": true, + "string.prototype.matchall>es-abstract>object-inspect": true + } + }, + "nyc>signal-exit": { + "builtin": { + "assert.equal": true, + "events": true + }, + "globals": { + "process": true + } + }, + "stylelint>table>slice-ansi": { + "packages": { + "stylelint>table>slice-ansi>ansi-styles": true, + "stylelint>table>slice-ansi>astral-regex": true, + "stylelint>table>slice-ansi>is-fullwidth-code-point": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>define-property": true, + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>braces>snapdragon-node>snapdragon-util>kind-of": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon": { + "builtin": { + "fs.readFileSync": true, + "path.dirname": true, + "util.inspect": true + }, "globals": { - "console.error": true, - "process": true + "__filename": true + }, + "packages": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>debug": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>extend-shallow": true, + "gulp>gulp-cli>liftoff>fined>parse-filepath>map-cache": true, + "resolve-url-loader>rework>css>source-map-resolve": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>source-map": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>use": true } }, "source-map": { @@ -7698,134 +7761,152 @@ "fetch": true } }, - "string.prototype.matchall": { - "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>es-abstract": true, - "string.prototype.matchall>has-symbols": true, - "string.prototype.matchall>regexp.prototype.flags": true + "postcss>source-map-js": { + "globals": { + "console": true } }, - "string.prototype.matchall>call-bind": { + "gulp-sourcemaps>css>source-map-resolve": { + "builtin": { + "path.sep": true, + "url.resolve": true + }, + "globals": { + "TextDecoder": true, + "setImmediate": true + }, "packages": { - "browserify>has>function-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>call-bind>set-function-length": true, - "string.prototype.matchall>get-intrinsic": true + "gulp-sourcemaps>css>source-map-resolve>atob": true, + "gulp-sourcemaps>css>source-map-resolve>decode-uri-component": true } }, - "string.prototype.matchall>call-bind>es-define-property": { + "resolve-url-loader>rework>css>source-map-resolve": { + "builtin": { + "url.resolve": true + }, + "globals": { + "TextDecoder": true, + "setImmediate": true + }, "packages": { - "string.prototype.matchall>get-intrinsic": true + "gulp-sourcemaps>css>source-map-resolve>atob": true, + "gulp-sourcemaps>css>source-map-resolve>decode-uri-component": true, + "resolve-url-loader>rework>css>source-map-resolve>source-map-url": true, + "resolve-url-loader>rework>css>urix": true } }, - "string.prototype.matchall>call-bind>set-function-length": { + "terser>source-map-support": { + "builtin": { + "fs": true, + "path.dirname": true, + "path.resolve": true + }, + "globals": { + "XMLHttpRequest": true, + "console.error": true, + "process": true + }, "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>get-intrinsic": true + "terser>source-map-support>buffer-from": true, + "terser>source-map-support>source-map": true } }, - "string.prototype.matchall>define-properties": { - "packages": { - "@lavamoat/lavapack>json-stable-stringify>object-keys": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "resolve-url-loader>rework>css>source-map-resolve>source-map-url": { + "globals": { + "define": true } }, - "string.prototype.matchall>define-properties>define-data-property": { + "eslint-plugin-jsdoc>spdx-expression-parse": { "packages": { - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>gopd": true + "eslint-plugin-jsdoc>spdx-expression-parse>spdx-exceptions": true, + "eslint-plugin-jsdoc>spdx-expression-parse>spdx-license-ids": true } }, - "string.prototype.matchall>es-abstract": { - "packages": { - "depcheck>is-core-module>hasown": true, - "eslint-plugin-react>array-includes>is-string": true, - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-define-property": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>es-object-atoms": true, - "string.prototype.matchall>es-abstract>es-set-tostringtag": true, - "string.prototype.matchall>es-abstract>es-to-primitive": true, - "string.prototype.matchall>es-abstract>gopd": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>es-abstract>is-callable": true, - "string.prototype.matchall>es-abstract>is-regex": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>es-abstract>safe-regex-test": true, - "string.prototype.matchall>es-abstract>string.prototype.trim": true, - "string.prototype.matchall>get-intrinsic": true, - "string.prototype.matchall>has-symbols": true, - "string.prototype.matchall>internal-slot": true + "stylelint>specificity": { + "globals": { + "define": true } }, - "string.prototype.matchall>es-abstract>es-object-atoms": { + "gulp>gulp-cli>matchdep>micromatch>braces>split-string": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true + "gulp-zip>plugin-error>extend-shallow": true } }, - "string.prototype.matchall>es-abstract>es-set-tostringtag": { + "gulp-livereload>event-stream>split": { + "builtin": { + "string_decoder.StringDecoder": true + }, "packages": { - "depcheck>is-core-module>hasown": true, - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>get-intrinsic": true + "debounce-stream>through": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend": { + "builtin": { + "util.inherits": true + }, "packages": { - "@metamask/eth-token-tracker>deep-equal>is-date-object": true, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": true, - "string.prototype.matchall>es-abstract>is-callable": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>define-property": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>class-utils>static-extend>object-copy": true } }, - "string.prototype.matchall>es-abstract>es-to-primitive>is-symbol": { + "browserify>module-deps>stream-combiner2": { "packages": { - "string.prototype.matchall>has-symbols": true + "browserify>duplexer2": true, + "browserify>module-deps>stream-combiner2>readable-stream": true } }, - "string.prototype.matchall>es-abstract>gopd": { + "gulp-livereload>event-stream>stream-combiner": { "packages": { - "string.prototype.matchall>get-intrinsic": true + "debounce-stream>duplexer": true } }, - "string.prototype.matchall>es-abstract>has-property-descriptors": { - "packages": { - "string.prototype.matchall>call-bind>es-define-property": true + "gulp>glob-watcher>async-done>stream-exhaust": { + "builtin": { + "stream.Writable": true, + "util.inherits": true + }, + "globals": { + "setImmediate": true } }, - "string.prototype.matchall>es-abstract>is-callable": { + "labeled-stream-splicer>stream-splicer": { "globals": { - "document": true + "process.nextTick": true, + "setImmediate": true + }, + "packages": { + "pumpify>inherits": true, + "labeled-stream-splicer>stream-splicer>readable-stream": true } }, - "string.prototype.matchall>es-abstract>is-regex": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width": { "packages": { - "koa>is-generator-function>has-tostringtag": true, - "string.prototype.matchall>call-bind": true + "gulp>gulp-cli>yargs>string-width>code-point-at": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": true } }, - "string.prototype.matchall>es-abstract>object-inspect": { - "builtin": { - "util.inspect": true - }, - "globals": { - "HTMLElement": true, - "WeakRef": true + "stylelint>table>string-width": { + "packages": { + "stylelint>table>string-width>emoji-regex": true, + "stylelint>table>slice-ansi>is-fullwidth-code-point": true, + "stylelint>table>string-width>strip-ansi": true } }, - "string.prototype.matchall>es-abstract>safe-regex-test": { + "yargs>string-width": { + "packages": { + "yargs>string-width>emoji-regex": true, + "yargs>string-width>is-fullwidth-code-point": true, + "eslint>strip-ansi": true + } + }, + "string.prototype.matchall": { "packages": { "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>is-regex": true + "string.prototype.matchall>define-properties": true, + "string.prototype.matchall>es-abstract": true, + "string.prototype.matchall>has-symbols": true, + "string.prototype.matchall>regexp.prototype.flags": true } }, "string.prototype.matchall>es-abstract>string.prototype.trim": { @@ -7836,821 +7917,684 @@ "string.prototype.matchall>es-abstract>es-object-atoms": true } }, - "string.prototype.matchall>get-intrinsic": { - "globals": { - "AggregateError": true, - "FinalizationRegistry": true, - "WeakRef": true - }, + "browserify>string_decoder": { "packages": { - "browserify>has>function-bind": true, - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>es-abstract>has-proto": true, - "string.prototype.matchall>has-symbols": true + "koa>content-disposition>safe-buffer": true } }, - "string.prototype.matchall>internal-slot": { + "gulp-livereload>tiny-lr>body>raw-body>string_decoder": { + "builtin": { + "buffer.Buffer": true + } + }, + "vinyl-buffer>bl>readable-stream>string_decoder": { "packages": { - "depcheck>is-core-module>hasown": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>side-channel": true + "vinyl-buffer>bl>readable-stream>string_decoder>safe-buffer": true } }, - "string.prototype.matchall>regexp.prototype.flags": { + "browserify>readable-stream>string_decoder": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties": true, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": true + "browserify>readable-stream>safe-buffer": true } }, - "string.prototype.matchall>regexp.prototype.flags>set-function-name": { + "browserify>concat-stream>readable-stream>string_decoder": { "packages": { - "string.prototype.matchall>call-bind>es-errors": true, - "string.prototype.matchall>define-properties>define-data-property": true, - "string.prototype.matchall>es-abstract>function.prototype.name>functions-have-names": true, - "string.prototype.matchall>es-abstract>has-property-descriptors": true + "browserify>concat-stream>readable-stream>safe-buffer": true } }, - "string.prototype.matchall>side-channel": { + "browserify>duplexer2>readable-stream>string_decoder": { "packages": { - "string.prototype.matchall>call-bind": true, - "string.prototype.matchall>es-abstract>object-inspect": true, - "string.prototype.matchall>get-intrinsic": true + "browserify>duplexer2>readable-stream>safe-buffer": true } }, - "stylelint": { - "builtin": { - "fs.lstatSync": true, - "fs.readFile": true, - "fs.readFileSync": true, - "fs.stat": true, - "os.EOL": true, - "path.dirname": true, - "path.isAbsolute": true, - "path.join": true, - "path.normalize": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true, - "url.URL": true - }, - "globals": { - "__dirname": true, - "assert": true, - "console.warn": true, - "process.cwd": true, - "process.env.NODE_ENV": true, - "process.stdout.columns": true, - "process.stdout.isTTY": true - }, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>string_decoder": { + "packages": { + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream>readable-stream>safe-buffer": true + } + }, + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>string_decoder": { "packages": { - "chalk": true, - "del>slash": true, - "eslint>ignore": true, - "eslint>imurmurhash": true, - "fast-glob>micromatch": true, - "globby": true, - "lodash": true, - "mocha>log-symbols": true, - "nock>debug": true, - "nyc>resolve-from": true, - "stylelint>@stylelint/postcss-css-in-js": true, - "stylelint>@stylelint/postcss-markdown": true, - "stylelint>autoprefixer": true, - "stylelint>balanced-match": true, - "stylelint>cosmiconfig": true, - "stylelint>execall": true, - "stylelint>file-entry-cache": true, - "stylelint>global-modules": true, - "stylelint>globjoin": true, - "stylelint>html-tags": true, - "stylelint>import-lazy": true, - "stylelint>known-css-properties": true, - "stylelint>leven": true, - "stylelint>mathml-tag-names": true, - "stylelint>normalize-selector": true, - "stylelint>postcss": true, - "stylelint>postcss-html": true, - "stylelint>postcss-less": true, - "stylelint>postcss-media-query-parser": true, - "stylelint>postcss-reporter": true, - "stylelint>postcss-resolve-nested-selector": true, - "stylelint>postcss-safe-parser": true, - "stylelint>postcss-sass": true, - "stylelint>postcss-scss": true, - "stylelint>postcss-selector-parser": true, - "stylelint>postcss-syntax": true, - "stylelint>postcss-value-parser": true, - "stylelint>specificity": true, - "stylelint>style-search": true, - "stylelint>sugarss": true, - "stylelint>svg-tags": true, - "stylelint>table": true, - "stylelint>write-file-atomic": true, - "yargs>string-width": true + "gulp>vinyl-fs>lead>flush-write-stream>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-css-in-js": { - "globals": { - "__dirname": true - }, + "gulp>vinyl-fs>glob-stream>readable-stream>string_decoder": { "packages": { - "@babel/core": true, - "stylelint>postcss": true, - "stylelint>postcss-syntax": true + "gulp>vinyl-fs>glob-stream>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown": { + "gulp-watch>readable-stream>string_decoder": { "packages": { - "stylelint>@stylelint/postcss-markdown>remark": true, - "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after": true, - "stylelint>postcss-html": true, - "stylelint>postcss-syntax": true + "gulp-watch>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark": { + "gulp>vinyl-fs>lazystream>readable-stream>string_decoder": { "packages": { - "react-markdown>unified": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify": true + "gulp>vinyl-fs>lazystream>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse": { + "browserify>module-deps>readable-stream>string_decoder": { "packages": { - "react-syntax-highlighter>refractor>parse-entities": true, - "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>ccount": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>collapse-white-space": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-alphabetical": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-whitespace-character": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-word-character": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>markdown-escapes": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>state-toggle": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>trim": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>trim-trailing-lines": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unist-util-remove-position": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>vfile-location": true, - "watchify>xtend": true + "browserify>module-deps>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": { + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>string_decoder": { "packages": { - "pumpify>inherits": true, - "watchify>xtend": true + "gulp>vinyl-fs>glob-stream>ordered-read-streams>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unist-util-remove-position": { + "browserify>read-only-stream>readable-stream>string_decoder": { "packages": { - "react-markdown>unist-util-visit": true + "browserify>read-only-stream>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify": { + "browserify>module-deps>stream-combiner2>readable-stream>string_decoder": { "packages": { - "react-syntax-highlighter>refractor>parse-entities": true, - "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>ccount": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>is-whitespace-character": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>markdown-escapes": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>state-toggle": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>is-alphanumeric": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>longest-streak": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>markdown-table": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>mdast-util-compact": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities": true, - "watchify>xtend": true + "browserify>module-deps>stream-combiner2>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>markdown-table": { + "labeled-stream-splicer>stream-splicer>readable-stream>string_decoder": { "packages": { - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true + "labeled-stream-splicer>stream-splicer>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>mdast-util-compact": { + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>string_decoder": { "packages": { - "react-markdown>unist-util-visit": true + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities": { + "browserify>browser-pack>through2>readable-stream>string_decoder": { "packages": { - "react-syntax-highlighter>refractor>parse-entities>character-entities-legacy": true, - "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": true, - "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, - "react-syntax-highlighter>refractor>parse-entities>is-hexadecimal": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities>character-entities-html4": true + "browserify>browser-pack>through2>readable-stream>string_decoder>safe-buffer": true } }, - "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after": { + "vinyl>cloneable-readable>through2>readable-stream>string_decoder": { "packages": { - "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after>unist-util-is": true + "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": true } }, - "stylelint>autoprefixer": { - "globals": { - "console": true, - "process.cwd": true, - "process.env.AUTOPREFIXER_GRID": true - }, + "browserify>deps-sort>through2>readable-stream>string_decoder": { "packages": { - "autoprefixer>caniuse-lite": true, - "autoprefixer>normalize-range": true, - "browserslist": true, - "stylelint>autoprefixer>num2fraction": true, - "stylelint>postcss": true, - "stylelint>postcss-value-parser": true, - "stylelint>postcss>picocolors": true + "browserify>deps-sort>through2>readable-stream>safe-buffer": true } }, - "stylelint>cosmiconfig": { - "builtin": { - "fs": true, - "os": true, - "path": true - }, - "globals": { - "process.cwd": true - }, + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>string_decoder": { "packages": { - "depcheck>cosmiconfig>parse-json": true, - "eslint>@eslint/eslintrc>import-fresh": true, - "globby>dir-glob>path-type": true, - "stylelint>cosmiconfig>yaml": true + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream>safe-buffer": true } }, - "stylelint>cosmiconfig>yaml": { - "globals": { - "Buffer": true, - "YAML_SILENCE_DEPRECATION_WARNINGS": true, - "YAML_SILENCE_WARNINGS": true, - "atob": true, - "btoa": true, - "console.warn": true, - "process": true + "gulp-sort>through2>readable-stream>string_decoder": { + "packages": { + "gulp-sort>through2>readable-stream>safe-buffer": true } }, - "stylelint>execall": { + "gulp-sourcemaps>through2>readable-stream>string_decoder": { "packages": { - "stylelint>execall>clone-regexp": true + "gulp-sourcemaps>through2>readable-stream>safe-buffer": true } }, - "stylelint>execall>clone-regexp": { + "browserify>insert-module-globals>through2>readable-stream>string_decoder": { "packages": { - "stylelint>execall>clone-regexp>is-regexp": true + "browserify>insert-module-globals>through2>readable-stream>safe-buffer": true } }, - "stylelint>file-entry-cache": { - "builtin": { - "crypto.createHash": true, - "fs.readFileSync": true, - "fs.statSync": true, - "path.basename": true, - "path.dirname": true - }, + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder": { "packages": { - "stylelint>file-entry-cache>flat-cache": true + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream>string_decoder>safe-buffer": true } }, - "stylelint>file-entry-cache>flat-cache": { - "builtin": { - "fs.existsSync": true, - "fs.readFileSync": true, - "path.basename": true, - "path.dirname": true, - "path.resolve": true - }, - "globals": { - "__dirname": true - }, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>string_decoder": { "packages": { - "stylelint>file-entry-cache>flat-cache>flatted": true, - "stylelint>file-entry-cache>flat-cache>rimraf": true, - "stylelint>file-entry-cache>flat-cache>write": true + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream>safe-buffer": true } }, - "stylelint>file-entry-cache>flat-cache>rimraf": { - "builtin": { - "assert": true, - "fs": true, - "path.join": true - }, - "globals": { - "process.platform": true, - "setTimeout": true - }, + "gulp>vinyl-fs>to-through>through2>readable-stream>string_decoder": { "packages": { - "nyc>glob": true + "gulp>vinyl-fs>to-through>through2>readable-stream>safe-buffer": true } }, - "stylelint>file-entry-cache>flat-cache>write": { - "builtin": { - "fs.createWriteStream": true, - "fs.writeFile": true, - "fs.writeFileSync": true, - "path.dirname": true - }, + "vinyl-source-stream>through2>readable-stream>string_decoder": { "packages": { - "mockttp>portfinder>mkdirp": true + "vinyl-source-stream>through2>readable-stream>safe-buffer": true } }, - "stylelint>global-modules": { - "builtin": { - "path.resolve": true - }, - "globals": { - "process.env.OSTYPE": true, - "process.platform": true - }, + "gulp>vinyl-fs>readable-stream>string_decoder": { "packages": { - "stylelint>global-modules>global-prefix": true + "gulp>vinyl-fs>readable-stream>safe-buffer": true } }, - "stylelint>global-modules>global-prefix": { - "builtin": { - "fs.readFileSync": true, - "fs.realpathSync": true, - "os.homedir": true, - "path.dirname": true, - "path.join": true, - "path.resolve": true - }, - "globals": { - "process.env.APPDATA": true, - "process.env.DESTDIR": true, - "process.env.OSTYPE": true, - "process.env.PREFIX": true, - "process.execPath": true, - "process.platform": true - }, + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities": { "packages": { - "stylelint>global-modules>global-prefix>ini": true, - "stylelint>global-modules>global-prefix>which": true + "stylelint>@stylelint/postcss-markdown>remark>remark-stringify>stringify-entities>character-entities-html4": true, + "react-syntax-highlighter>refractor>parse-entities>character-entities-legacy": true, + "react-syntax-highlighter>refractor>parse-entities>is-alphanumerical": true, + "react-syntax-highlighter>refractor>parse-entities>is-decimal": true, + "react-syntax-highlighter>refractor>parse-entities>is-hexadecimal": true } }, - "stylelint>global-modules>global-prefix>ini": { - "globals": { - "process": true + "postcss-discard-font-face>postcss>chalk>strip-ansi": { + "packages": { + "postcss-discard-font-face>postcss>chalk>strip-ansi>ansi-regex": true } }, - "stylelint>global-modules>global-prefix>which": { - "builtin": { - "path.join": true - }, - "globals": { - "process.cwd": true, - "process.env.OSTYPE": true, - "process.env.PATH": true, - "process.env.PATHEXT": true, - "process.platform": true - }, + "eslint>strip-ansi": { "packages": { - "@sentry/cli>which>isexe": true + "eslint>strip-ansi>ansi-regex": true } }, - "stylelint>globjoin": { - "builtin": { - "path.join": true + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi": { + "packages": { + "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge>strip-ansi>ansi-regex": true } }, - "stylelint>normalize-selector": { - "globals": { - "define": true + "stylelint>table>string-width>strip-ansi": { + "packages": { + "stylelint>table>string-width>strip-ansi>ansi-regex": true } }, - "stylelint>postcss": { - "builtin": { - "fs": true, - "path": true - }, - "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true - }, + "gulp-watch>vinyl-file>strip-bom-stream": { "packages": { - "stylelint>postcss>picocolors": true, - "stylelint>postcss>source-map": true + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true, + "gulp-watch>vinyl-file>strip-bom": true } }, - "stylelint>postcss-html": { + "gulp-watch>vinyl-file>strip-bom": { "globals": { - "__dirname": true + "Buffer.isBuffer": true }, "packages": { - "stylelint>postcss-html>htmlparser2": true, - "stylelint>postcss-syntax": true + "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true } }, - "stylelint>postcss-html>htmlparser2": { + "stylelint": { "builtin": { - "buffer.Buffer": true, - "events.EventEmitter": true, - "string_decoder.StringDecoder": true + "fs.lstatSync": true, + "fs.readFile": true, + "fs.readFileSync": true, + "fs.stat": true, + "os.EOL": true, + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "path.normalize": true, + "path.relative": true, + "path.resolve": true, + "path.sep": true, + "url.URL": true + }, + "globals": { + "__dirname": true, + "assert": true, + "console.warn": true, + "process.cwd": true, + "process.env.NODE_ENV": true, + "process.stdout.columns": true, + "process.stdout.isTTY": true }, "packages": { - "pumpify>inherits": true, - "readable-stream": true, - "stylelint>postcss-html>htmlparser2>domelementtype": true, - "stylelint>postcss-html>htmlparser2>domhandler": true, - "stylelint>postcss-html>htmlparser2>domutils": true, - "stylelint>postcss-html>htmlparser2>entities": true - } - }, - "stylelint>postcss-html>htmlparser2>domhandler": { - "packages": { - "stylelint>postcss-html>htmlparser2>domelementtype": true + "stylelint>@stylelint/postcss-css-in-js": true, + "stylelint>@stylelint/postcss-markdown": true, + "stylelint>autoprefixer": true, + "stylelint>balanced-match": true, + "chalk": true, + "stylelint>cosmiconfig": true, + "nock>debug": true, + "stylelint>execall": true, + "stylelint>file-entry-cache": true, + "stylelint>global-modules": true, + "globby": true, + "stylelint>globjoin": true, + "stylelint>html-tags": true, + "eslint>ignore": true, + "stylelint>import-lazy": true, + "eslint>imurmurhash": true, + "stylelint>known-css-properties": true, + "stylelint>leven": true, + "lodash": true, + "mocha>log-symbols": true, + "stylelint>mathml-tag-names": true, + "fast-glob>micromatch": true, + "stylelint>normalize-selector": true, + "stylelint>postcss-html": true, + "stylelint>postcss-less": true, + "stylelint>postcss-media-query-parser": true, + "stylelint>postcss-reporter": true, + "stylelint>postcss-resolve-nested-selector": true, + "stylelint>postcss-safe-parser": true, + "stylelint>postcss-sass": true, + "stylelint>postcss-scss": true, + "stylelint>postcss-selector-parser": true, + "stylelint>postcss-syntax": true, + "stylelint>postcss-value-parser": true, + "stylelint>postcss": true, + "nyc>resolve-from": true, + "del>slash": true, + "stylelint>specificity": true, + "yargs>string-width": true, + "stylelint>style-search": true, + "stylelint>sugarss": true, + "stylelint>svg-tags": true, + "stylelint>table": true, + "stylelint>write-file-atomic": true } }, - "stylelint>postcss-html>htmlparser2>domutils": { + "stylelint>sugarss": { "packages": { - "stylelint>postcss-html>htmlparser2>domelementtype": true, - "stylelint>postcss-html>htmlparser2>domutils>dom-serializer": true + "stylelint>sugarss>postcss": true } }, - "stylelint>postcss-html>htmlparser2>domutils>dom-serializer": { - "packages": { - "stylelint>postcss-html>htmlparser2>domelementtype": true, - "stylelint>postcss-html>htmlparser2>entities": true + "superstruct": { + "globals": { + "console.warn": true, + "define": true } }, - "stylelint>postcss-less": { + "chalk>supports-color": { + "builtin": { + "os.release": true, + "tty.isatty": true + }, + "globals": { + "process.env": true, + "process.platform": true + }, "packages": { - "stylelint>postcss-less>postcss": true + "chalk>supports-color>has-flag": true } }, - "stylelint>postcss-less>postcss": { + "gulp-livereload>chalk>supports-color": { "builtin": { - "fs": true, - "path": true + "os.release": true }, "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "process.env": true, + "process.platform": true, + "process.stderr": true, + "process.stdout": true, + "process.versions.node.split": true }, "packages": { - "stylelint>postcss-less>postcss>picocolors": true, - "stylelint>postcss-less>postcss>source-map": true + "gulp-livereload>chalk>supports-color>has-flag": true } }, - "stylelint>postcss-less>postcss>picocolors": { + "postcss-discard-font-face>postcss>chalk>supports-color": { + "globals": { + "process.argv": true, + "process.env": true, + "process.platform": true, + "process.stdout": true + } + }, + "mocha>supports-color": { "builtin": { + "os.release": true, "tty.isatty": true }, "globals": { - "process.argv.includes": true, "process.env": true, "process.platform": true + }, + "packages": { + "chalk>supports-color>has-flag": true } }, - "stylelint>postcss-reporter": { + "postcss-discard-font-face>postcss>supports-color": { + "globals": { + "process": true + }, "packages": { - "lodash": true + "postcss-discard-font-face>postcss>supports-color>has-flag": true } }, - "stylelint>postcss-safe-parser": { + "browserify>syntax-error": { "packages": { - "stylelint>postcss-safe-parser>postcss": true + "browserify>syntax-error>acorn-node": true } }, - "stylelint>postcss-safe-parser>postcss": { - "builtin": { - "fs": true, - "path": true + "stylelint>table": { + "globals": { + "process.stdout.write": true }, + "packages": { + "eslint>ajv": true, + "lodash": true, + "stylelint>table>slice-ansi": true, + "stylelint>table>string-width": true + } + }, + "terser": { "globals": { "Buffer": true, "atob": true, "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "console.log": true, + "console.warn": true, + "define": true, + "process": true }, "packages": { - "stylelint>postcss-safe-parser>postcss>picocolors": true, - "stylelint>postcss-safe-parser>postcss>source-map": true - } - }, - "stylelint>postcss-safe-parser>postcss>picocolors": { - "builtin": { - "tty.isatty": true - }, - "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true + "terser>@jridgewell/source-map": true, + "jsdom>acorn": true } }, - "stylelint>postcss-sass": { + "through2": { "packages": { - "stylelint>postcss-sass>gonzales-pe": true, - "stylelint>postcss-sass>postcss": true + "readable-stream": true } }, - "stylelint>postcss-sass>gonzales-pe": { - "globals": { - "console.error": true, - "define": true + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter": { + "packages": { + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2": true, + "watchify>xtend": true } }, - "stylelint>postcss-sass>postcss": { + "gulp-sourcemaps>@gulp-sourcemaps/identity-map>through2": { "builtin": { - "fs": true, - "path": true + "util.inherits": true }, "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "process.nextTick": true }, "packages": { - "stylelint>postcss-sass>postcss>picocolors": true, - "stylelint>postcss-sass>postcss>source-map": true + "readable-stream": true } }, - "stylelint>postcss-sass>postcss>picocolors": { + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2": { "builtin": { - "tty.isatty": true + "util.inherits": true }, "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true - } - }, - "stylelint>postcss-scss": { + "process.nextTick": true + }, "packages": { - "stylelint>postcss-scss>postcss": true + "gulp-sourcemaps>@gulp-sourcemaps/map-sources>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>postcss-scss>postcss": { + "bify-module-groups>through2": { "builtin": { - "fs": true, - "path": true + "util.inherits": true }, "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "process.nextTick": true }, "packages": { - "stylelint>postcss-scss>postcss>picocolors": true, - "stylelint>postcss-scss>postcss>source-map": true + "readable-stream": true } }, - "stylelint>postcss-scss>postcss>picocolors": { + "browserify>browser-pack>through2": { "builtin": { - "tty.isatty": true + "util.inherits": true }, "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true - } - }, - "stylelint>postcss-selector-parser": { + "process.nextTick": true + }, "packages": { - "readable-stream>util-deprecate": true, - "stylelint>postcss-selector-parser>cssesc": true + "browserify>browser-pack>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>postcss-syntax": { + "browserify>through2": { "builtin": { - "path.isAbsolute": true, - "path.resolve": true, - "path.sep": true + "util.inherits": true + }, + "globals": { + "process.nextTick": true }, "packages": { - "stylelint>postcss": true + "browserify>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>postcss>picocolors": { + "vinyl>cloneable-readable>through2": { "builtin": { - "tty.isatty": true + "util.inherits": true }, "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true + "process.nextTick": true + }, + "packages": { + "vinyl>cloneable-readable>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>specificity": { + "browserify>deps-sort>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "define": true - } - }, - "stylelint>sugarss": { + "process.nextTick": true + }, "packages": { - "stylelint>sugarss>postcss": true + "browserify>deps-sort>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>sugarss>postcss": { + "gulp>vinyl-fs>fs-mkdirp-stream>through2": { "builtin": { - "fs": true, - "path": true + "util.inherits": true }, "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console": true, - "process.env.NODE_ENV": true + "process.nextTick": true }, "packages": { - "stylelint>sugarss>postcss>picocolors": true, - "stylelint>sugarss>postcss>source-map": true + "gulp>vinyl-fs>fs-mkdirp-stream>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>sugarss>postcss>picocolors": { + "gulp-sort>through2": { "builtin": { - "tty.isatty": true + "util.inherits": true }, "globals": { - "process.argv.includes": true, - "process.env": true, - "process.platform": true + "process.nextTick": true + }, + "packages": { + "gulp-sort>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>table": { + "gulp-sourcemaps>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "process.stdout.write": true + "process.nextTick": true }, "packages": { - "eslint>ajv": true, - "lodash": true, - "stylelint>table>slice-ansi": true, - "stylelint>table>string-width": true + "gulp-sourcemaps>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>table>slice-ansi": { + "gulp-stylelint>through2": { + "builtin": { + "util.inherits": true + }, + "globals": { + "process.nextTick": true + }, "packages": { - "stylelint>table>slice-ansi>ansi-styles": true, - "stylelint>table>slice-ansi>astral-regex": true, - "stylelint>table>slice-ansi>is-fullwidth-code-point": true + "readable-stream": true } }, - "stylelint>table>slice-ansi>ansi-styles": { + "gulp-zip>through2": { + "builtin": { + "util.inherits": true + }, + "globals": { + "process.nextTick": true + }, "packages": { - "@metamask/jazzicon>color>color-convert": true + "readable-stream": true } }, - "stylelint>table>string-width": { + "browserify>insert-module-globals>through2": { + "builtin": { + "util.inherits": true + }, + "globals": { + "process.nextTick": true + }, "packages": { - "stylelint>table>slice-ansi>is-fullwidth-code-point": true, - "stylelint>table>string-width>emoji-regex": true, - "stylelint>table>string-width>strip-ansi": true + "browserify>insert-module-globals>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>table>string-width>strip-ansi": { + "browserify>module-deps>through2": { + "builtin": { + "util.inherits": true + }, + "globals": { + "process.nextTick": true + }, "packages": { - "stylelint>table>string-width>strip-ansi>ansi-regex": true + "browserify>module-deps>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>write-file-atomic": { + "gulp>vinyl-fs>remove-bom-stream>through2": { "builtin": { - "fs.chmod": true, - "fs.chmodSync": true, - "fs.chown": true, - "fs.chownSync": true, - "fs.close": true, - "fs.closeSync": true, - "fs.fsync": true, - "fs.fsyncSync": true, - "fs.open": true, - "fs.openSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.rename": true, - "fs.renameSync": true, - "fs.stat": true, - "fs.statSync": true, - "fs.unlink": true, - "fs.unlinkSync": true, - "fs.write": true, - "fs.writeSync": true, - "path.resolve": true, - "util.promisify": true, - "worker_threads.threadId": true + "util.inherits": true }, "globals": { - "Buffer.isBuffer": true, - "__filename": true, - "process.getuid": true, - "process.pid": true + "process.nextTick": true }, "packages": { - "eslint>imurmurhash": true, - "nyc>signal-exit": true, - "stylelint>write-file-atomic>is-typedarray": true, - "stylelint>write-file-atomic>typedarray-to-buffer": true + "gulp>vinyl-fs>remove-bom-stream>through2>readable-stream": true, + "watchify>xtend": true } }, - "stylelint>write-file-atomic>typedarray-to-buffer": { + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "Buffer.from": true + "process.nextTick": true }, "packages": { - "stylelint>write-file-atomic>is-typedarray": true + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter>through2>readable-stream": true, + "watchify>xtend": true } }, - "superstruct": { + "gulp>vinyl-fs>to-through>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "console.warn": true, - "define": true + "process.nextTick": true + }, + "packages": { + "gulp>vinyl-fs>to-through>through2>readable-stream": true, + "watchify>xtend": true } }, - "terser": { + "vinyl-buffer>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "Buffer": true, - "atob": true, - "btoa": true, - "console.log": true, - "console.warn": true, - "define": true, - "process": true + "process.nextTick": true }, "packages": { - "jsdom>acorn": true, - "terser>@jridgewell/source-map": true + "vinyl-buffer>bl>readable-stream": true, + "watchify>xtend": true } }, - "terser-webpack-plugin>@jridgewell/trace-mapping": { + "gulp>vinyl-fs>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "define": true + "process.nextTick": true }, "packages": { - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": true, - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true + "gulp>vinyl-fs>readable-stream": true, + "watchify>xtend": true } }, - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": { + "vinyl-source-stream>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "define": true + "process.nextTick": true + }, + "packages": { + "vinyl-source-stream>through2>readable-stream": true, + "watchify>xtend": true } }, - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": { + "debounce-stream>through": { + "builtin": { + "stream": true + }, "globals": { - "Buffer": true, - "TextDecoder": true, - "define": true + "process.nextTick": true } }, - "terser>@jridgewell/source-map": { + "gulp-sourcemaps>debug-fabulous>memoizee>timers-ext": { "packages": { - "terser-webpack-plugin>@jridgewell/trace-mapping": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping": true + "resolve-url-loader>es6-iterator>es5-ext": true } }, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping": { + "gulp-livereload>tiny-lr": { + "builtin": { + "events": true, + "fs": true, + "http": true, + "https": true, + "url.parse": true + }, "globals": { - "define": true + "console.error": true }, "packages": { - "terser-webpack-plugin>@jridgewell/trace-mapping": true, - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/set-array": true - } - }, - "terser>@jridgewell/source-map>@jridgewell/gen-mapping>@jridgewell/set-array": { - "globals": { - "define": true + "gulp-livereload>tiny-lr>body": true, + "gulp-livereload>tiny-lr>debug": true, + "gulp-livereload>tiny-lr>faye-websocket": true, + "react>object-assign": true, + "@storybook/addon-knobs>qs": true } }, - "terser>source-map-support": { + "gulp>vinyl-fs>glob-stream>to-absolute-glob": { "builtin": { - "fs": true, - "path.dirname": true, "path.resolve": true }, "globals": { - "XMLHttpRequest": true, - "console.error": true, - "process": true + "process.cwd": true, + "process.platform": true }, "packages": { - "terser>source-map-support>buffer-from": true, - "terser>source-map-support>source-map": true + "gulp>gulp-cli>replace-homedir>is-absolute": true, + "gulp>glob-watcher>is-negated-glob": true } }, - "terser>source-map-support>buffer-from": { - "globals": { - "Buffer": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>to-object-path>kind-of": true } }, - "through2": { + "chokidar>braces>fill-range>to-regex-range": { "packages": { - "readable-stream": true + "chokidar>braces>fill-range>to-regex-range>is-number": true + } + }, + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>to-regex-range": { + "packages": { + "gulp>glob-watcher>anymatch>micromatch>braces>fill-range>is-number": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>to-regex": { + "packages": { + "gulp>gulp-cli>matchdep>micromatch>to-regex>define-property": true, + "gulp-zip>plugin-error>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true, + "gulp>gulp-cli>matchdep>micromatch>to-regex>safe-regex": true + } + }, + "gulp>vinyl-fs>to-through": { + "packages": { + "gulp>vinyl-fs>to-through>through2": true } }, "ts-node": { @@ -8683,13 +8627,13 @@ "value": true }, "packages": { - "jsdom>acorn": true, "ts-node>@cspotcode/source-map-support": true, "ts-node>@tsconfig/node10": true, "ts-node>@tsconfig/node12": true, "ts-node>@tsconfig/node14": true, "ts-node>@tsconfig/node16": true, "ts-node>acorn-walk": true, + "jsdom>acorn": true, "ts-node>arg": true, "ts-node>create-require": true, "ts-node>diff": true, @@ -8698,63 +8642,195 @@ "ts-node>yn": true } }, - "ts-node>@cspotcode/source-map-support": { - "builtin": { - "fs": true, - "path.isAbsolute": true, - "path.join": true, - "path.normalize": true, - "path.resolve": true, - "url.fileURLToPath": true, - "url.pathToFileURL": true, - "util.inspect": true - }, - "globals": { - "Buffer.from": true, - "URL": true, - "XMLHttpRequest": true, - "console.error": true, - "process": true - }, + "eslint-plugin-import>tsconfig-paths": { + "builtin": { + "fs.existsSync": true, + "fs.lstatSync": true, + "fs.readFile": true, + "fs.readFileSync": true, + "fs.stat": true, + "fs.statSync": true, + "module._resolveFilename": true, + "module.builtinModules": true, + "path.dirname": true, + "path.isAbsolute": true, + "path.join": true, + "path.resolve": true + }, + "globals": { + "console.warn": true, + "process.argv.slice": true, + "process.cwd": true, + "process.env": true + }, + "packages": { + "eslint-plugin-import>tsconfig-paths>json5": true, + "wait-on>minimist": true, + "eslint-plugin-import>tsconfig-paths>strip-bom": true + } + }, + "tsutils": { + "packages": { + "tslib": true, + "typescript": true + } + }, + "eslint>levn>type-check": { + "packages": { + "eslint>levn>prelude-ls": true + } + }, + "stylelint>write-file-atomic>typedarray-to-buffer": { + "globals": { + "Buffer.from": true + }, + "packages": { + "stylelint>write-file-atomic>is-typedarray": true + } + }, + "typescript": { + "builtin": { + "buffer.Buffer": true, + "crypto": true, + "fs": true, + "inspector": true, + "module.findPnpApi": true, + "os.EOL": true, + "os.platform": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true, + "perf_hooks.PerformanceObserver": true, + "perf_hooks.performance": true + }, + "globals": { + "Intl.Collator": true, + "PerformanceObserver": true, + "__dirname": true, + "__filename": true, + "clearTimeout": true, + "console": true, + "gc": true, + "globalThis": true, + "onProfilerEvent": true, + "performance": true, + "process": true, + "setTimeout": true + }, + "packages": { + "terser>source-map-support": true + } + }, + "browserify>insert-module-globals>undeclared-identifiers": { + "packages": { + "browserify>syntax-error>acorn-node": true, + "browserify>insert-module-globals>undeclared-identifiers>get-assigned-identifiers": true, + "watchify>xtend": true + } + }, + "gulp>undertaker": { + "builtin": { + "assert": true, + "events.EventEmitter": true, + "util.inherits": true + }, + "globals": { + "process.env.UNDERTAKER_SETTLE": true, + "process.env.UNDERTAKER_TIME_RESOLUTION": true, + "process.hrtime": true + }, + "packages": { + "gulp>undertaker>arr-flatten": true, + "gulp>undertaker>arr-map": true, + "gulp>undertaker>bach": true, + "gulp>undertaker>collection-map": true, + "gulp>undertaker>es6-weak-map": true, + "gulp>undertaker>last-run": true, + "gulp>undertaker>object.defaults": true, + "gulp>undertaker>object.reduce": true, + "gulp>undertaker>undertaker-registry": true + } + }, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unherit": { + "packages": { + "pumpify>inherits": true, + "watchify>xtend": true + } + }, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript": { + "packages": { + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript>unicode-canonical-property-names-ecmascript": true, + "@babel/preset-env>@babel/plugin-transform-dotall-regex>@babel/helper-create-regexp-features-plugin>regexpu-core>unicode-match-property-ecmascript>unicode-property-aliases-ecmascript": true + } + }, + "react-markdown>unified": { + "packages": { + "react-markdown>unified>bail": true, + "react-markdown>unified>extend": true, + "react-markdown>unified>is-buffer": true, + "mocha>yargs-unparser>is-plain-obj": true, + "react-markdown>unified>trough": true, + "react-markdown>vfile": true + } + }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>union-value": { + "packages": { + "gulp-zip>plugin-error>arr-union": true, + "gulp>gulp-cli>array-sort>get-value": true, + "gulp-watch>anymatch>micromatch>object.omit>is-extendable": true, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>set-value": true + } + }, + "gulp>vinyl-fs>glob-stream>unique-stream": { + "packages": { + "@lavamoat/lavapack>json-stable-stringify": true, + "gulp>vinyl-fs>glob-stream>unique-stream>through2-filter": true + } + }, + "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after": { + "packages": { + "stylelint>@stylelint/postcss-markdown>unist-util-find-all-after>unist-util-is": true + } + }, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>unist-util-remove-position": { + "packages": { + "react-markdown>unist-util-visit": true + } + }, + "react-markdown>unist-util-visit>unist-util-visit-parents": { + "packages": { + "react-markdown>unist-util-visit>unist-util-is": true + } + }, + "react-markdown>unist-util-visit": { "packages": { - "ts-node>@cspotcode/source-map-support>@jridgewell/trace-mapping": true + "react-markdown>unist-util-visit>unist-util-visit-parents": true } }, - "ts-node>@cspotcode/source-map-support>@jridgewell/trace-mapping": { - "globals": { - "define": true - }, + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value": { "packages": { - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/resolve-uri": true, - "terser-webpack-plugin>@jridgewell/trace-mapping>@jridgewell/sourcemap-codec": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>base>cache-base>unset-value>has-value": true, + "gulp>gulp-cli>isobject": true } }, - "ts-node>acorn-walk": { + "uri-js": { "globals": { "define": true } }, - "ts-node>arg": { - "globals": { - "process.argv.slice": true + "resolve-url-loader>rework>css>urix": { + "builtin": { + "path.sep": true } }, - "ts-node>create-require": { - "builtin": { - "fs.lstatSync": true, - "module.Module": true, - "module.createRequire": true, - "module.createRequireFromPath": true, - "path.dirname": true, - "path.join": true - }, - "globals": { - "process.cwd": true + "gulp>gulp-cli>matchdep>micromatch>snapdragon>use": { + "packages": { + "@babel/register>clone-deep>kind-of": true } }, - "ts-node>diff": { - "globals": { - "setTimeout": true + "readable-stream>util-deprecate": { + "builtin": { + "util.deprecate": true } }, "ts-node>v8-compile-cache-lib": { @@ -8782,48 +8858,26 @@ "process": true } }, - "tsutils": { + "react-markdown>vfile>vfile-message": { "packages": { - "tslib": true, - "typescript": true + "react-markdown>vfile>unist-util-stringify-position": true } }, - "typescript": { + "react-markdown>vfile": { "builtin": { - "buffer.Buffer": true, - "crypto": true, - "fs": true, - "inspector": true, - "module.findPnpApi": true, - "os.EOL": true, - "os.platform": true, + "path.basename": true, "path.dirname": true, + "path.extname": true, "path.join": true, - "path.resolve": true, - "perf_hooks.PerformanceObserver": true, - "perf_hooks.performance": true + "path.sep": true }, "globals": { - "Intl.Collator": true, - "PerformanceObserver": true, - "__dirname": true, - "__filename": true, - "clearTimeout": true, - "console": true, - "gc": true, - "globalThis": true, - "onProfilerEvent": true, - "performance": true, - "process": true, - "setTimeout": true + "process.cwd": true }, "packages": { - "terser>source-map-support": true - } - }, - "uri-js": { - "globals": { - "define": true + "react-markdown>vfile>is-buffer": true, + "react-markdown>vfile>replace-ext": true, + "react-markdown>vfile>vfile-message": true } }, "vinyl": { @@ -8841,9 +8895,9 @@ "process.cwd": true }, "packages": { - "vinyl>clone": true, "vinyl>clone-buffer": true, "vinyl>clone-stats": true, + "vinyl>clone": true, "vinyl>cloneable-readable": true, "vinyl>remove-trailing-separator": true, "vinyl>replace-ext": true @@ -8855,67 +8909,7 @@ "vinyl-buffer>through2": true } }, - "vinyl-buffer>bl": { - "builtin": { - "util.inherits": true - }, - "packages": { - "koa>content-disposition>safe-buffer": true, - "vinyl-buffer>bl>readable-stream": true - } - }, - "vinyl-buffer>bl>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true, - "vinyl-buffer>bl>readable-stream>isarray": true, - "vinyl-buffer>bl>readable-stream>safe-buffer": true, - "vinyl-buffer>bl>readable-stream>string_decoder": true - } - }, - "vinyl-buffer>bl>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "vinyl-buffer>bl>readable-stream>string_decoder": { - "packages": { - "vinyl-buffer>bl>readable-stream>string_decoder>safe-buffer": true - } - }, - "vinyl-buffer>bl>readable-stream>string_decoder>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "vinyl-buffer>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, - "packages": { - "vinyl-buffer>bl>readable-stream": true, - "watchify>xtend": true - } - }, - "vinyl-source-stream": { + "gulp-watch>vinyl-file": { "builtin": { "path.resolve": true }, @@ -8923,163 +8917,103 @@ "process.cwd": true }, "packages": { - "vinyl": true, - "vinyl-source-stream>through2": true + "del>graceful-fs": true, + "gulp-watch>vinyl-file>pify": true, + "gh-pages>globby>pinkie-promise": true, + "gulp-watch>vinyl-file>strip-bom-stream": true, + "gulp-watch>vinyl-file>strip-bom": true, + "gulp-watch>vinyl-file>vinyl": true } }, - "vinyl-source-stream>through2": { + "gulp>vinyl-fs": { "builtin": { + "os.platform": true, + "path.relative": true, + "path.resolve": true, "util.inherits": true }, "globals": { + "Buffer.isBuffer": true, + "process.cwd": true, + "process.geteuid": true, + "process.getuid": true, "process.nextTick": true }, "packages": { - "vinyl-source-stream>through2>readable-stream": true, - "watchify>xtend": true - } - }, - "vinyl-source-stream>through2>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream-2>process-nextick-args": true, - "readable-stream>util-deprecate": true, - "vinyl-source-stream>through2>readable-stream>isarray": true, - "vinyl-source-stream>through2>readable-stream>safe-buffer": true, - "vinyl-source-stream>through2>readable-stream>string_decoder": true - } - }, - "vinyl-source-stream>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true - } - }, - "vinyl-source-stream>through2>readable-stream>string_decoder": { - "packages": { - "vinyl-source-stream>through2>readable-stream>safe-buffer": true - } - }, - "vinyl-sourcemaps-apply": { - "packages": { - "vinyl-sourcemaps-apply>source-map": true - } - }, - "vinyl>clone": { - "globals": { - "Buffer": true - } - }, - "vinyl>clone-buffer": { - "builtin": { - "buffer.Buffer": true - } - }, - "vinyl>clone-stats": { - "builtin": { - "fs.Stats": true - } - }, - "vinyl>cloneable-readable": { - "packages": { - "pumpify>inherits": true, - "vinyl>cloneable-readable>process-nextick-args": true, - "vinyl>cloneable-readable>through2": true - } - }, - "vinyl>cloneable-readable>process-nextick-args": { - "globals": { - "process.nextTick": true, - "process.version": true + "gulp>vinyl-fs>fs-mkdirp-stream": true, + "gulp>vinyl-fs>glob-stream": true, + "del>graceful-fs": true, + "gulp>vinyl-fs>is-valid-glob": true, + "gulp>vinyl-fs>lazystream": true, + "gulp>vinyl-fs>lead": true, + "gulp>vinyl-fs>object.assign": true, + "gulp>vinyl-fs>pumpify": true, + "gulp>vinyl-fs>readable-stream": true, + "gulp>vinyl-fs>remove-bom-buffer": true, + "gulp>vinyl-fs>remove-bom-stream": true, + "gulp>vinyl-fs>resolve-options": true, + "gulp>vinyl-fs>through2": true, + "gulp>vinyl-fs>to-through": true, + "gulp>vinyl-fs>value-or-function": true, + "vinyl": true, + "gulp>vinyl-fs>vinyl-sourcemap": true } }, - "vinyl>cloneable-readable>through2": { + "vinyl-source-stream": { "builtin": { - "util.inherits": true + "path.resolve": true }, "globals": { - "process.nextTick": true + "process.cwd": true }, "packages": { - "vinyl>cloneable-readable>through2>readable-stream": true, - "watchify>xtend": true + "vinyl-source-stream>through2": true, + "vinyl": true } }, - "vinyl>cloneable-readable>through2>readable-stream": { + "gulp>vinyl-fs>vinyl-sourcemap": { "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true + "path.dirname": true, + "path.join": true, + "path.relative": true, + "path.resolve": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "Buffer": true }, "packages": { - "pumpify>inherits": true, - "readable-stream-2>core-util-is": true, - "readable-stream>util-deprecate": true, - "vinyl>cloneable-readable>through2>readable-stream>isarray": true, - "vinyl>cloneable-readable>through2>readable-stream>process-nextick-args": true, - "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": true, - "vinyl>cloneable-readable>through2>readable-stream>string_decoder": true - } - }, - "vinyl>cloneable-readable>through2>readable-stream>process-nextick-args": { - "globals": { - "process": true - } - }, - "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": { - "builtin": { - "buffer": true + "gulp>vinyl-fs>vinyl-sourcemap>append-buffer": true, + "nyc>convert-source-map": true, + "del>graceful-fs": true, + "gulp-watch>anymatch>normalize-path": true, + "gulp>vinyl-fs>vinyl-sourcemap>now-and-later": true, + "gulp>vinyl-fs>remove-bom-buffer": true, + "vinyl": true } }, - "vinyl>cloneable-readable>through2>readable-stream>string_decoder": { + "vinyl-sourcemaps-apply": { "packages": { - "vinyl>cloneable-readable>through2>readable-stream>safe-buffer": true - } - }, - "vinyl>remove-trailing-separator": { - "globals": { - "process.platform": true + "vinyl-sourcemaps-apply>source-map": true } }, - "vinyl>replace-ext": { + "gulp-watch>vinyl-file>vinyl": { "builtin": { + "buffer.Buffer": true, "path.basename": true, "path.dirname": true, "path.extname": true, "path.join": true, - "path.sep": true - } - }, - "wait-on>rxjs": { + "path.relative": true, + "stream.PassThrough": true, + "stream.Stream": true + }, "globals": { - "cancelAnimationFrame": true, - "clearInterval": true, - "clearTimeout": true, - "performance": true, - "requestAnimationFrame": true, - "setInterval.apply": true, - "setTimeout.apply": true + "process.cwd": true + }, + "packages": { + "gulp-watch>vinyl-file>vinyl>clone-stats": true, + "@metamask/jazzicon>color>clone": true, + "gulp-watch>vinyl-file>vinyl>replace-ext": true } }, "watchify": { @@ -9091,8 +9025,8 @@ "setTimeout": true }, "packages": { - "chokidar": true, "chokidar>anymatch": true, + "chokidar": true, "through2": true, "watchify>xtend": true } @@ -9110,20 +9044,93 @@ "process.version": true }, "packages": { - "koa>content-disposition>safe-buffer": true, "webpack-dev-server>sockjs>websocket-driver>http-parser-js": true, + "koa>content-disposition>safe-buffer": true, "webpack-dev-server>sockjs>websocket-driver>websocket-extensions": true } }, - "webpack-dev-server>sockjs>websocket-driver>http-parser-js": { + "stylelint>global-modules>global-prefix>which": { "builtin": { - "assert.equal": true, - "assert.ok": true + "path.join": true + }, + "globals": { + "process.cwd": true, + "process.env.OSTYPE": true, + "process.env.PATH": true, + "process.env.PATHEXT": true, + "process.platform": true + }, + "packages": { + "@sentry/cli>which>isexe": true } }, - "webpack>json-parse-even-better-errors": { + "@storybook/react>@storybook/node-logger>npmlog>gauge>wide-align": { + "packages": { + "yargs>string-width": true + } + }, + "yargs>cliui>wrap-ansi": { + "packages": { + "chalk>ansi-styles": true, + "yargs>string-width": true, + "eslint>strip-ansi": true + } + }, + "stylelint>write-file-atomic": { + "builtin": { + "fs.chmod": true, + "fs.chmodSync": true, + "fs.chown": true, + "fs.chownSync": true, + "fs.close": true, + "fs.closeSync": true, + "fs.fsync": true, + "fs.fsyncSync": true, + "fs.open": true, + "fs.openSync": true, + "fs.realpath": true, + "fs.realpathSync": true, + "fs.rename": true, + "fs.renameSync": true, + "fs.stat": true, + "fs.statSync": true, + "fs.unlink": true, + "fs.unlinkSync": true, + "fs.write": true, + "fs.writeSync": true, + "path.resolve": true, + "util.promisify": true, + "worker_threads.threadId": true + }, "globals": { - "Buffer.isBuffer": true + "Buffer.isBuffer": true, + "__filename": true, + "process.getuid": true, + "process.pid": true + }, + "packages": { + "eslint>imurmurhash": true, + "stylelint>write-file-atomic>is-typedarray": true, + "nyc>signal-exit": true, + "stylelint>write-file-atomic>typedarray-to-buffer": true + } + }, + "stylelint>file-entry-cache>flat-cache>write": { + "builtin": { + "fs.createWriteStream": true, + "fs.writeFile": true, + "fs.writeFileSync": true, + "path.dirname": true + }, + "packages": { + "mockttp>portfinder>mkdirp": true + } + }, + "yargs>y18n": { + "builtin": { + "fs": true, + "path": true, + "util": true } }, "yaml": { @@ -9137,6 +9144,28 @@ "process": true } }, + "stylelint>cosmiconfig>yaml": { + "globals": { + "Buffer": true, + "YAML_SILENCE_DEPRECATION_WARNINGS": true, + "YAML_SILENCE_WARNINGS": true, + "atob": true, + "btoa": true, + "console.warn": true, + "process": true + } + }, + "gulp-postcss>postcss-load-config>yaml": { + "globals": { + "Buffer": true, + "YAML_SILENCE_DEPRECATION_WARNINGS": true, + "YAML_SILENCE_WARNINGS": true, + "atob": true, + "btoa": true, + "console.warn": true, + "process": true + } + }, "yargs": { "builtin": { "assert": true, @@ -9151,13 +9180,13 @@ "process": true }, "packages": { - "yargs-parser": true, "yargs>cliui": true, "yargs>escalade": true, "yargs>get-caller-file": true, "yargs>require-directory": true, "yargs>string-width": true, - "yargs>y18n": true + "yargs>y18n": true, + "yargs-parser": true } }, "yargs-parser": { @@ -9171,62 +9200,34 @@ "process": true } }, - "yargs>cliui": { - "globals": { - "process": true - }, - "packages": { - "eslint>strip-ansi": true, - "yargs>cliui>wrap-ansi": true, - "yargs>string-width": true - } - }, - "yargs>cliui>wrap-ansi": { - "packages": { - "chalk>ansi-styles": true, - "eslint>strip-ansi": true, - "yargs>string-width": true - } - }, - "yargs>escalade": { - "builtin": { - "fs.readdirSync": true, - "fs.statSync": true, - "path.dirname": true, - "path.resolve": true - } - }, - "yargs>require-directory": { - "builtin": { - "fs.readdirSync": true, - "fs.statSync": true, - "path.dirname": true, - "path.join": true, - "path.resolve": true - } - }, - "yargs>string-width": { - "packages": { - "eslint>strip-ansi": true, - "yargs>string-width>emoji-regex": true, - "yargs>string-width>is-fullwidth-code-point": true - } - }, - "yargs>y18n": { + "yargs>yargs-parser": { "builtin": { "fs": true, "path": true, "util": true + }, + "globals": { + "process": true } }, - "yargs>yargs-parser": { + "gulp-zip>yazl": { "builtin": { - "fs": true, - "path": true, - "util": true + "events.EventEmitter": true, + "fs.createReadStream": true, + "fs.stat": true, + "stream.PassThrough": true, + "stream.Transform": true, + "util.inherits": true, + "zlib.DeflateRaw": true, + "zlib.deflateRaw": true }, "globals": { - "process": true + "Buffer": true, + "setImmediate": true, + "utf8FileName.length": true + }, + "packages": { + "gulp-zip>yazl>buffer-crc32": true } } } diff --git a/offscreen/scripts/ledger.ts b/offscreen/scripts/ledger.ts index c08fdc6ac85a..4e03def36068 100644 --- a/offscreen/scripts/ledger.ts +++ b/offscreen/scripts/ledger.ts @@ -96,7 +96,7 @@ function setupMessageListeners(iframe: HTMLIFrameElement) { export default async function init() { return new Promise((resolve) => { const iframe = document.createElement('iframe'); - iframe.src = 'https://metamask.github.io/eth-ledger-bridge-keyring'; + iframe.src = 'https://metamask.github.io/ledger-iframe-bridge/8.0.3/'; iframe.allow = 'hid'; iframe.onload = () => { setupMessageListeners(iframe); diff --git a/package.json b/package.json index b4449b398c64..3a772189095c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "12.10.4", + "version": "12.11.0", "private": true, "repository": { "type": "git", @@ -28,7 +28,7 @@ "start:test:mv2:flask": "ENABLE_MV3=false yarn start:test:flask --apply-lavamoat=false --snow=false", "start:test:mv2": "ENABLE_MV3=false BLOCKAID_FILE_CDN=static.cx.metamask.io/api/v1/confirmations/ppom yarn start:test --apply-lavamoat=false --snow=false", "benchmark:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/benchmark.js", - "mv3:stats:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/mv3-perf-stats/index.js", + "bundle-size": "SELENIUM_BROWSER=chrome ts-node test/e2e/mv3-perf-stats/bundle-size.js", "user-actions-benchmark:chrome": "SELENIUM_BROWSER=chrome ts-node test/e2e/user-actions-benchmark.js", "benchmark:firefox": "SELENIUM_BROWSER=firefox ts-node test/e2e/benchmark.js", "build:test": "yarn env:e2e build test", @@ -174,8 +174,6 @@ "await-semaphore@^0.1.1": "patch:await-semaphore@npm%3A0.1.3#./.yarn/patches/await-semaphore-npm-0.1.3-b7a0001fab.patch", "await-semaphore@^0.1.3": "patch:await-semaphore@npm%3A0.1.3#./.yarn/patches/await-semaphore-npm-0.1.3-b7a0001fab.patch", "eslint@npm:^8.7.0": "patch:eslint@npm%3A8.57.0#~/.yarn/patches/eslint-npm-8.57.0-4286e12a3a.patch", - "eth-query@^2.1.2": "patch:eth-query@npm%3A2.1.2#./.yarn/patches/eth-query-npm-2.1.2-7c6adc825f.patch", - "eth-query@^2.1.0": "patch:eth-query@npm%3A2.1.2#./.yarn/patches/eth-query-npm-2.1.2-7c6adc825f.patch", "ethereumjs-util@^7.0.10": "patch:ethereumjs-util@npm%3A7.1.5#./.yarn/patches/ethereumjs-util-npm-7.1.5-5bb4d00000.patch", "ethereumjs-util@^7.1.5": "patch:ethereumjs-util@npm%3A7.1.5#./.yarn/patches/ethereumjs-util-npm-7.1.5-5bb4d00000.patch", "ethereumjs-util@^7.1.4": "patch:ethereumjs-util@npm%3A7.1.5#./.yarn/patches/ethereumjs-util-npm-7.1.5-5bb4d00000.patch", @@ -207,8 +205,6 @@ "watchify@^4.0.0": "patch:watchify@npm%3A4.0.0#./.yarn/patches/watchify-npm-4.0.0-4fd965dd49.patch", "undeclared-identifiers@^1.1.2": "patch:undeclared-identifiers@npm%3A1.1.2#./.yarn/patches/undeclared-identifiers-npm-1.1.2-13d6792e9e.patch", "stylelint@^13.6.1": "patch:stylelint@npm%3A13.6.1#./.yarn/patches/stylelint-npm-13.6.1-47aaddf62b.patch", - "luxon@^3.0.1": "patch:luxon@npm%3A3.2.1#./.yarn/patches/luxon-npm-3.2.1-56f8d97395.patch", - "luxon@^3.2.1": "patch:luxon@npm%3A3.2.1#./.yarn/patches/luxon-npm-3.2.1-56f8d97395.patch", "symbol-observable": "^2.0.3", "async-done@~1.3.2": "patch:async-done@npm%3A1.3.2#./.yarn/patches/async-done-npm-1.3.2-1f0a4a8997.patch", "async-done@^1.2.0": "patch:async-done@npm%3A1.3.2#./.yarn/patches/async-done-npm-1.3.2-1f0a4a8997.patch", @@ -225,7 +221,8 @@ "semver@7.3.8": "^7.5.4", "@trezor/schema-utils@npm:1.0.2": "patch:@trezor/schema-utils@npm%3A1.0.2#~/.yarn/patches/@trezor-schema-utils-npm-1.0.2-7dd48689b2.patch", "lavamoat-core@npm:^15.1.1": "patch:lavamoat-core@npm%3A15.1.1#~/.yarn/patches/lavamoat-core-npm-15.1.1-51fbe39988.patch", - "@metamask/snaps-sdk": "^6.13.0", + "lavamoat-core@npm:^16.2.2": "patch:lavamoat-core@npm%3A16.2.2#~/.yarn/patches/lavamoat-core-npm-16.2.2-e361ff1f8a.patch", + "@metamask/snaps-sdk": "^6.15.0", "@swc/types@0.1.5": "^0.1.6", "@babel/core": "patch:@babel/core@npm%3A7.25.9#~/.yarn/patches/@babel-core-npm-7.25.9-4ae3bff7f3.patch", "@babel/runtime": "patch:@babel/runtime@npm%3A7.25.9#~/.yarn/patches/@babel-runtime-npm-7.25.9-fe8c62510a.patch", @@ -236,21 +233,28 @@ "@expo/config/glob": "^10.3.10", "@expo/config-plugins/glob": "^10.3.10", "@solana/web3.js/rpc-websockets": "^8.0.1", - "@metamask/nonce-tracker@npm:^5.0.0": "patch:@metamask/nonce-tracker@npm%3A5.0.0#~/.yarn/patches/@metamask-nonce-tracker-npm-5.0.0-d81478218e.patch", - "@metamask/network-controller@npm:^22.0.0": "patch:@metamask/network-controller@npm%3A22.1.0#~/.yarn/patches/@metamask-network-controller-npm-22.1.0-621c281f70.patch", + "@metamask/network-controller@npm:^22.0.2": "patch:@metamask/network-controller@npm%3A22.1.1#~/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch", "path-to-regexp": "1.9.0", "@ledgerhq/cryptoassets-evm-signatures/axios": "^0.28.0", "@ledgerhq/domain-service/axios": "^0.28.0", "@ledgerhq/evm-tools/axios": "^0.28.0", "@ledgerhq/hw-app-eth/axios": "^0.28.0", - "@ledgerhq/hw-app-eth@npm:^6.39.0": "patch:@ledgerhq/hw-app-eth@npm%3A6.39.0#~/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.39.0-866309bbbe.patch", - "@ledgerhq/evm-tools@npm:^1.2.3": "patch:@ledgerhq/evm-tools@npm%3A1.2.3#~/.yarn/patches/@ledgerhq-evm-tools-npm-1.2.3-414f44baa9.patch", "cross-spawn@npm:^5.0.1": "^7.0.6", "@solana/web3.js@npm:^1.95.0": "^1.95.8", "secp256k1@npm:^4.0.0": "4.0.4", "secp256k1@npm:^4.0.1": "4.0.4", "secp256k1@npm:4.0.2": "4.0.4", "secp256k1@npm:4.0.3": "4.0.4", + "tslib@npm:^2.0.0": "~2.6.0", + "tslib@npm:^2.0.1": "~2.6.0", + "tslib@npm:^2.0.3": "~2.6.0", + "tslib@npm:^2.1.0": "~2.6.0", + "tslib@npm:^2.3.0": "~2.6.0", + "tslib@npm:^2.3.1": "~2.6.0", + "tslib@npm:^2.4.0": "~2.6.0", + "tslib@npm:^2.6.2": "~2.6.0", + "@ledgerhq/hw-app-eth@npm:^6.42.0": "patch:@ledgerhq/hw-app-eth@npm%3A6.42.2#~/.yarn/patches/@ledgerhq-hw-app-eth-npm-6.42.2-46a44bfbf5.patch", + "@ledgerhq/evm-tools@npm:^1.3.0": "patch:@ledgerhq/evm-tools@npm%3A1.3.0#~/.yarn/patches/@ledgerhq-evm-tools-npm-1.3.0-57435278f6.patch", "undici@npm:5.28.4": "5.28.5", "@metamask/providers@npm:^18.3.1": "patch:@metamask/providers@npm%3A19.0.0#~/.yarn/patches/@metamask-providers-npm-19.0.0-3d962c6f1a.patch" }, @@ -284,7 +288,7 @@ "@metamask-institutional/types": "^1.2.0", "@metamask/abi-utils": "^2.0.2", "@metamask/account-watcher": "^4.1.2", - "@metamask/accounts-controller": "^20.0.0", + "@metamask/accounts-controller": "^20.0.2", "@metamask/address-book-controller": "^6.0.0", "@metamask/announcement-controller": "^7.0.0", "@metamask/approval-controller": "^7.0.0", @@ -298,30 +302,28 @@ "@metamask/ens-controller": "^15.0.0", "@metamask/ens-resolver-snap": "^0.1.2", "@metamask/eth-json-rpc-filters": "^9.0.0", - "@metamask/eth-json-rpc-middleware": "^15.0.0", - "@metamask/eth-ledger-bridge-keyring": "^5.0.1", - "@metamask/eth-query": "^4.0.0", + "@metamask/eth-json-rpc-middleware": "^15.1.2", + "@metamask/eth-ledger-bridge-keyring": "^8.0.3", "@metamask/eth-sig-util": "^7.0.1", - "@metamask/eth-snap-keyring": "^5.0.1", + "@metamask/eth-snap-keyring": "^7.0.0", "@metamask/eth-token-tracker": "^9.0.0", - "@metamask/eth-trezor-keyring": "^3.1.3", + "@metamask/eth-trezor-keyring": "^6.0.0", "@metamask/etherscan-link": "^3.0.0", - "@metamask/ethjs": "^0.6.0", - "@metamask/ethjs-contract": "^0.4.1", - "@metamask/ethjs-query": "^0.7.1", "@metamask/gas-fee-controller": "^22.0.1", "@metamask/jazzicon": "^2.0.0", "@metamask/json-rpc-engine": "^10.0.0", "@metamask/json-rpc-middleware-stream": "^8.0.4", - "@metamask/keyring-api": "^10.1.0", - "@metamask/keyring-controller": "^19.0.0", + "@metamask/keyring-api": "^12.0.0", + "@metamask/keyring-controller": "^19.0.2", + "@metamask/keyring-internal-api": "^1.0.0", + "@metamask/keyring-snap-client": "^1.0.0", "@metamask/logging-controller": "^6.0.0", "@metamask/logo": "^3.1.2", "@metamask/message-manager": "^11.0.0", "@metamask/message-signing-snap": "^0.6.0", "@metamask/metamask-eth-abis": "^3.1.1", "@metamask/name-controller": "^8.0.0", - "@metamask/network-controller": "patch:@metamask/network-controller@npm%3A22.1.0#~/.yarn/patches/@metamask-network-controller-npm-22.1.0-621c281f70.patch", + "@metamask/network-controller": "patch:@metamask/network-controller@npm%3A22.1.1#~/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch", "@metamask/notification-services-controller": "^0.15.0", "@metamask/object-multiplex": "^2.0.0", "@metamask/obs-store": "^9.0.0", @@ -329,28 +331,28 @@ "@metamask/permission-log-controller": "^3.0.1", "@metamask/phishing-controller": "^12.3.0", "@metamask/polling-controller": "^12.0.1", - "@metamask/post-message-stream": "^8.0.0", + "@metamask/post-message-stream": "^9.0.0", "@metamask/ppom-validator": "0.36.0", - "@metamask/preinstalled-example-snap": "^0.2.0", - "@metamask/profile-sync-controller": "^3.1.1", + "@metamask/preinstalled-example-snap": "^0.3.0", + "@metamask/profile-sync-controller": "^4.1.0", "@metamask/providers": "patch:@metamask/providers@npm%3A19.0.0#~/.yarn/patches/@metamask-providers-npm-19.0.0-3d962c6f1a.patch", "@metamask/queued-request-controller": "^7.0.1", "@metamask/rate-limit-controller": "^6.0.0", - "@metamask/remote-feature-flag-controller": "^1.1.0", + "@metamask/remote-feature-flag-controller": "^1.3.0", "@metamask/rpc-errors": "^7.0.0", "@metamask/safe-event-emitter": "^3.1.1", "@metamask/scure-bip39": "^2.0.3", "@metamask/selected-network-controller": "^19.0.0", "@metamask/signature-controller": "^23.1.0", - "@metamask/smart-transactions-controller": "^15.0.0", - "@metamask/snaps-controllers": "^9.15.0", - "@metamask/snaps-execution-environments": "^6.10.0", - "@metamask/snaps-rpc-methods": "^11.7.0", - "@metamask/snaps-sdk": "^6.13.0", - "@metamask/snaps-utils": "^8.6.1", + "@metamask/smart-transactions-controller": "^16.0.1", + "@metamask/snaps-controllers": "^9.17.0", + "@metamask/snaps-execution-environments": "^6.12.0", + "@metamask/snaps-rpc-methods": "^11.9.1", + "@metamask/snaps-sdk": "^6.15.0", + "@metamask/snaps-utils": "^8.8.0", "@metamask/solana-wallet-snap": "^1.0.4", - "@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A42.0.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.0.0-9e6d74c3e2.patch", - "@metamask/user-operation-controller": "^19.0.0", + "@metamask/transaction-controller": "patch:@metamask/transaction-controller@npm%3A42.1.0#~/.yarn/patches/@metamask-transaction-controller-npm-42.1.0-5e103c5a07.patch", + "@metamask/user-operation-controller": "^21.0.0", "@metamask/utils": "^10.0.1", "@ngraveio/bc-ur": "^1.1.12", "@noble/hashes": "^1.3.3", @@ -433,6 +435,7 @@ "simple-git": "^3.20.0", "single-call-balance-checker-abi": "^1.0.0", "ts-mixer": "patch:ts-mixer@npm%3A6.0.4#~/.yarn/patches/ts-mixer-npm-6.0.4-5d9747bdf5.patch", + "tslib": "~2.6.0", "unicode-confusables": "^0.1.1", "uri-js": "^4.4.1", "uuid": "^8.3.2", @@ -452,9 +455,9 @@ "@babel/preset-typescript": "^7.25.9", "@babel/register": "^7.25.9", "@jest/globals": "^29.7.0", - "@lavamoat/allow-scripts": "^3.0.4", + "@lavamoat/allow-scripts": "^3.3.1", "@lavamoat/lavadome-core": "0.0.10", - "@lavamoat/lavapack": "^6.1.0", + "@lavamoat/lavapack": "^7.0.5", "@lgbot/madge": "^6.2.0", "@lydell/node-pty": "^1.0.1", "@metamask/api-specs": "^0.9.3", @@ -611,8 +614,8 @@ "jsdom": "^16.7.0", "json-schema-to-ts": "^3.0.1", "koa": "^2.7.0", - "lavamoat": "^8.0.2", - "lavamoat-browserify": "^17.0.4", + "lavamoat": "^9.0.5", + "lavamoat-browserify": "^18.1.2", "lavamoat-viz": "^7.0.5", "level": "^8.0.1", "lockfile-lint": "^4.10.6", @@ -762,7 +765,8 @@ "resolve-url-loader>es6-iterator>d>es5-ext>esniff>es5-ext": false, "level>classic-level": false, "jest-preview": false, - "@metamask/solana-wallet-snap>@solana/web3.js>bigint-buffer": false + "@metamask/solana-wallet-snap>@solana/web3.js>bigint-buffer": false, + "@lavamoat/allow-scripts>@lavamoat/preinstall-always-fail": false } }, "packageManager": "yarn@4.5.1" diff --git a/privacy-snapshot.json b/privacy-snapshot.json index 24c6e9ae27da..1cfb47fe73b8 100644 --- a/privacy-snapshot.json +++ b/privacy-snapshot.json @@ -13,6 +13,7 @@ "bafkreifvhjdf6ve4jfv6qytqtux5nd4nwnelioeiqx5x2ez5yrgrzk7ypi.ipfs.dweb.link", "bafybeidxfmwycgzcp4v2togflpqh2gnibuexjy4m4qqwxp7nh3jx5zlh4y.ipfs.dweb.link", "bridge.api.cx.metamask.io", + "bridge.dev-api.cx.metamask.io", "cdn.segment.com", "cdn.segment.io", "cdnjs.cloudflare.com", @@ -35,6 +36,7 @@ "linea-sepolia.infura.io", "localhost:8000", "localhost:8545", + "mainnet.helius-rpc.com", "mainnet.infura.io", "metamask-sdk.api.cx.metamask.io", "metamask.eth", diff --git a/shared/constants/alerts.ts b/shared/constants/alerts.ts index bbf6318f448e..71b246db2fb2 100644 --- a/shared/constants/alerts.ts +++ b/shared/constants/alerts.ts @@ -2,6 +2,7 @@ export enum AlertTypes { unconnectedAccount = 'unconnectedAccount', web3ShimUsage = 'web3ShimUsage', invalidCustomNetwork = 'invalidCustomNetwork', + smartTransactionsMigration = 'smartTransactionsMigration', } /** @@ -10,6 +11,7 @@ export enum AlertTypes { export const TOGGLEABLE_ALERT_TYPES = [ AlertTypes.unconnectedAccount, AlertTypes.web3ShimUsage, + AlertTypes.smartTransactionsMigration, ]; export enum Web3ShimUsageAlertStates { diff --git a/shared/constants/bridge.ts b/shared/constants/bridge.ts index ef7cb7f8a785..fc5ecb157016 100644 --- a/shared/constants/bridge.ts +++ b/shared/constants/bridge.ts @@ -27,7 +27,7 @@ export const ETH_USDT_ADDRESS = '0xdac17f958d2ee523a2206206994597c13d831ec7'; export const METABRIDGE_ETHEREUM_ADDRESS = '0x0439e60F02a8900a951603950d8D4527f400C3f1'; export const BRIDGE_QUOTE_MAX_ETA_SECONDS = 60 * 60; // 1 hour -export const BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE = 0.8; // if a quote returns in x times less return than the best quote, ignore it +export const BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE = 0.5; // if a quote returns in x times less return than the best quote, ignore it export const BRIDGE_PREFERRED_GAS_ESTIMATE = 'high'; export const BRIDGE_DEFAULT_SLIPPAGE = 0.5; @@ -47,3 +47,5 @@ export const NETWORK_TO_SHORT_NETWORK_NAME_MAP: Record< [CHAIN_IDS.BASE]: 'Base', }; export const BRIDGE_MM_FEE_RATE = 0.875; +export const REFRESH_INTERVAL_MS = 30 * 1000; +export const DEFAULT_MAX_REFRESH_COUNT = 5; diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts index a65c349963ec..8b59e95e650c 100644 --- a/shared/constants/metametrics.ts +++ b/shared/constants/metametrics.ts @@ -645,6 +645,9 @@ export enum MetaMetricsEventName { AppUnlockedFailed = 'App Unlocked Failed', AppLocked = 'App Locked', AppWindowExpanded = 'App Window Expanded', + BannerDisplay = 'Banner Display', + BannerCloseAll = 'Banner Close All', + BannerSelect = 'Banner Select', BridgeLinkClicked = 'Bridge Link Clicked', BitcoinSupportToggled = 'Bitcoin Support Toggled', BitcoinTestnetSupportToggled = 'Bitcoin Testnet Support Toggled', @@ -766,6 +769,7 @@ export enum MetaMetricsEventName { TokenAdded = 'Token Added', TokenRemoved = 'Token Removed', TokenSortPreference = 'Token Sort Preference', + TokenListRefreshed = 'Token List Refreshed', NFTRemoved = 'NFT Removed', TokenDetected = 'Token Detected', TokenHidden = 'Token Hidden', @@ -911,6 +915,7 @@ export enum MetaMetricsEventCategory { App = 'App', Auth = 'Auth', Background = 'Background', + Banner = 'Banner', // The TypeScript ESLint rule is incorrectly marking this line. /* eslint-disable-next-line @typescript-eslint/no-shadow */ Error = 'Error', diff --git a/shared/constants/network.ts b/shared/constants/network.ts index 30f59c156dda..a33fec836b20 100644 --- a/shared/constants/network.ts +++ b/shared/constants/network.ts @@ -169,6 +169,10 @@ export const CHAIN_IDS = { B3_TESTNET: '0x7c9', GRAVITY_ALPHA_MAINNET: '0x659', GRAVITY_ALPHA_TESTNET_SEPOLIA: '0x34c1', + LISK: '0x46f', + LISK_SEPOLIA: '0x106a', + INK_SEPOLIA: '0xba5eD', + INK: '0xdef1', } as const; export const CHAINLIST_CHAIN_IDS_MAP = { @@ -201,7 +205,7 @@ export const CHAINLIST_CHAIN_IDS_MAP = { HAQQ_NETWORK: '0x2be3', IOTEX_MAINNET: '0x1251', KCC_MAINNET: '0x141', - KLAYTN_MAINNET_CYPRESS: '0x2019', + KAIA_MAINNET: '0x2019', KROMA_MAINNET: '0xff', LIGHTLINK_PHOENIX_MAINNET: '0x762', MANTA_PACIFIC_MAINNET: '0xa9', @@ -229,6 +233,10 @@ export const CHAINLIST_CHAIN_IDS_MAP = { APE: '0x8173', GRAVITY_ALPHA_MAINNET: '0x659', GRAVITY_ALPHA_TESTNET_SEPOLIA: '0x34c1', + INK_SEPOLIA: '0xba5ed', + INK: '0xdef1', + SONEIUM_MAINNET: '0x74c', + SONEIUM_TESTNET: '0x79a', } as const; // To add a deprecation warning to a network, add it to the array @@ -278,7 +286,11 @@ export const SCROLL_SEPOLIA_DISPLAY_NAME = 'Scroll Sepolia'; export const OP_BNB_DISPLAY_NAME = 'opBNB'; export const BERACHAIN_DISPLAY_NAME = 'Berachain Artio'; export const METACHAIN_ONE_DISPLAY_NAME = 'Metachain One Mainnet'; - +export const LISK_DISPLAY_NAME = 'Lisk'; +export const LISK_SEPOLIA_DISPLAY_NAME = 'Lisk Sepolia'; +export const INK_SEPOLIA_DISPLAY_NAME = 'Ink Sepolia'; +export const INK_DISPLAY_NAME = 'Ink Mainnet'; +export const SONEIUM_DISPLAY_NAME = 'Soneium Mainnet'; export const infuraProjectId = process.env.INFURA_PROJECT_ID; export const getRpcUrl = ({ network, @@ -369,7 +381,7 @@ const CHAINLIST_CURRENCY_SYMBOLS_MAP = { NEAR_AURORA_MAINNET: 'ETH', KROMA_MAINNET: 'ETH', NEBULA_MAINNET: 'sFUEL', - KLAYTN_MAINNET_CYPRESS: 'KLAY', + KAIA_MAINNET: 'KAIA', ENDURANCE_SMART_CHAIN_MAINNET: 'ACE', CRONOS_MAINNET_BETA: 'CRO', FLARE_MAINNET: 'FLR', @@ -400,6 +412,9 @@ const CHAINLIST_CURRENCY_SYMBOLS_MAP = { ACALA_NETWORK: 'ACA', IOTEX_MAINNET: 'IOTX', APE: 'APE', + LISK: 'ETH', + SONEIUM_MAINNET: 'ETH', + SONEIUM_TESTNET: 'ETH', } as const; export const CHAINLIST_CURRENCY_SYMBOLS_MAP_NETWORK_COLLISION = { @@ -447,7 +462,7 @@ export const IOTEX_MAINNET_IMAGE_URL = './images/iotex.svg'; export const IOTEX_TOKEN_IMAGE_URL = './images/iotex-token.svg'; export const APE_TOKEN_IMAGE_URL = './images/ape-token.svg'; export const KCC_MAINNET_IMAGE_URL = './images/kcc-mainnet.svg'; -export const KLAYTN_MAINNET_IMAGE_URL = './images/klaytn.svg'; +export const KAIA_MAINNET_IMAGE_URL = './images/kaia.svg'; export const KROMA_MAINNET_IMAGE_URL = './images/kroma.svg'; export const LIGHT_LINK_IMAGE_URL = './images/lightlink.svg'; export const MANTA_PACIFIC_MAINNET_IMAGE_URL = './images/manta.svg'; @@ -483,6 +498,11 @@ export const B3_IMAGE_URL = './images/b3.svg'; export const APE_IMAGE_URL = './images/ape.svg'; export const GRAVITY_ALPHA_MAINNET_IMAGE_URL = './images/gravity.svg'; export const GRAVITY_ALPHA_TESTNET_SEPOLIA_IMAGE_URL = './images/gravity.svg'; +export const LISK_IMAGE_URL = './images/lisk.svg'; +export const LISK_SEPOLIA_IMAGE_URL = './images/lisk_sepolia.svg'; +export const INK_SEPOLIA_IMAGE_URL = './images/ink-sepolia.svg'; +export const INK_IMAGE_URL = './images/ink.svg'; +export const SONEIUM_IMAGE_URL = './images/soneium.svg'; export const INFURA_PROVIDER_TYPES = [ NETWORK_TYPES.MAINNET, @@ -593,6 +613,8 @@ export const NETWORK_TO_NAME_MAP = { [CHAIN_IDS.ZKSYNC_ERA]: ZK_SYNC_ERA_DISPLAY_NAME, [CHAIN_IDS.BERACHAIN]: BERACHAIN_DISPLAY_NAME, [CHAIN_IDS.METACHAIN_ONE]: METACHAIN_ONE_DISPLAY_NAME, + [CHAIN_IDS.LISK]: LISK_DISPLAY_NAME, + [CHAIN_IDS.LISK_SEPOLIA]: LISK_SEPOLIA_DISPLAY_NAME, } as const; export const CHAIN_ID_TO_CURRENCY_SYMBOL_MAP = { @@ -655,8 +677,8 @@ export const CHAIN_ID_TO_CURRENCY_SYMBOL_MAP = { CHAINLIST_CURRENCY_SYMBOLS_MAP.KROMA_MAINNET, [CHAINLIST_CHAIN_IDS_MAP.NEBULA_MAINNET]: CHAINLIST_CURRENCY_SYMBOLS_MAP.NEBULA_MAINNET, - [CHAINLIST_CHAIN_IDS_MAP.KLAYTN_MAINNET_CYPRESS]: - CHAINLIST_CURRENCY_SYMBOLS_MAP.KLAYTN_MAINNET_CYPRESS, + [CHAINLIST_CHAIN_IDS_MAP.KAIA_MAINNET]: + CHAINLIST_CURRENCY_SYMBOLS_MAP.KAIA_MAINNET, [CHAINLIST_CHAIN_IDS_MAP.MOONRIVER]: CHAINLIST_CURRENCY_SYMBOLS_MAP.MOONRIVER, [CHAINLIST_CHAIN_IDS_MAP.ENDURANCE_SMART_CHAIN_MAINNET]: CHAINLIST_CURRENCY_SYMBOLS_MAP.ENDURANCE_SMART_CHAIN_MAINNET, @@ -710,6 +732,10 @@ export const CHAIN_ID_TO_CURRENCY_SYMBOL_MAP = { CHAINLIST_CURRENCY_SYMBOLS_MAP.ACALA_NETWORK, [CHAINLIST_CHAIN_IDS_MAP.IOTEX_MAINNET]: CHAINLIST_CURRENCY_SYMBOLS_MAP.IOTEX_MAINNET, + [CHAINLIST_CHAIN_IDS_MAP.SONEIUM_MAINNET]: + CHAINLIST_CURRENCY_SYMBOLS_MAP.SONEIUM_MAINNET, + [CHAINLIST_CHAIN_IDS_MAP.SONEIUM_TESTNET]: + CHAINLIST_CURRENCY_SYMBOLS_MAP.SONEIUM_TESTNET, } as const; /** @@ -790,7 +816,7 @@ export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP = { [CHAINLIST_CHAIN_IDS_MAP.IOTEX_MAINNET]: IOTEX_MAINNET_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.HAQQ_NETWORK]: HAQQ_NETWORK_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.KCC_MAINNET]: KCC_MAINNET_IMAGE_URL, - [CHAINLIST_CHAIN_IDS_MAP.KLAYTN_MAINNET_CYPRESS]: KLAYTN_MAINNET_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.KAIA_MAINNET]: KAIA_MAINNET_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.KROMA_MAINNET]: KROMA_MAINNET_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.LIGHTLINK_PHOENIX_MAINNET]: LIGHT_LINK_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.MANTA_PACIFIC_MAINNET]: @@ -827,6 +853,12 @@ export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP = { GRAVITY_ALPHA_MAINNET_IMAGE_URL, [CHAINLIST_CHAIN_IDS_MAP.GRAVITY_ALPHA_TESTNET_SEPOLIA]: GRAVITY_ALPHA_TESTNET_SEPOLIA_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.LISK]: LISK_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.LISK_SEPOLIA]: LISK_SEPOLIA_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.INK_SEPOLIA]: INK_SEPOLIA_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.INK]: INK_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.SONEIUM_MAINNET]: SONEIUM_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.SONEIUM_TESTNET]: SONEIUM_IMAGE_URL, } as const; export const CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP = { @@ -867,6 +899,8 @@ export const CHAIN_ID_TOKEN_IMAGE_MAP = { [CHAIN_IDS.GRAVITY_ALPHA_MAINNET]: GRAVITY_ALPHA_MAINNET_IMAGE_URL, [CHAIN_IDS.GRAVITY_ALPHA_TESTNET_SEPOLIA]: GRAVITY_ALPHA_TESTNET_SEPOLIA_IMAGE_URL, + [CHAINLIST_CHAIN_IDS_MAP.ZORA_MAINNET]: ETH_TOKEN_IMAGE_URL, + [CHAIN_IDS.INK]: ETH_TOKEN_IMAGE_URL, } as const; export const INFURA_BLOCKED_KEY = 'countryBlocked'; diff --git a/shared/constants/snaps/permissions.ts b/shared/constants/snaps/permissions.ts index 837beea4d9ff..e08afdf46421 100644 --- a/shared/constants/snaps/permissions.ts +++ b/shared/constants/snaps/permissions.ts @@ -7,6 +7,7 @@ export const EndowmentPermissions = Object.freeze({ 'endowment:webassembly': 'endowment:webassembly', 'endowment:lifecycle-hooks': 'endowment:lifecycle-hooks', 'endowment:page-home': 'endowment:page-home', + 'endowment:page-settings': 'endowment:page-settings', 'endowment:signature-insight': 'endowment:signature-insight', 'endowment:name-lookup': 'endowment:name-lookup', ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) diff --git a/shared/lib/confirmation.utils.test.ts b/shared/lib/confirmation.utils.test.ts index add03a95813d..bce20ec4f4db 100644 --- a/shared/lib/confirmation.utils.test.ts +++ b/shared/lib/confirmation.utils.test.ts @@ -21,41 +21,6 @@ describe('confirmation.utils', () => { const unsupportedTransactionType = TransactionType.swap; - describe('when user setting is enabled', () => { - it('should return true for supported transaction types', () => { - supportedTransactionTypes.forEach((transactionType) => { - expect( - shouldUseRedesignForTransactions({ - transactionMetadataType: transactionType, - isRedesignedTransactionsUserSettingEnabled: true, // user setting enabled - isRedesignedConfirmationsDeveloperEnabled: false, // developer mode disabled - }), - ).toBe(true); - }); - }); - - it('should return false for unsupported transaction types', () => { - expect( - shouldUseRedesignForTransactions({ - transactionMetadataType: unsupportedTransactionType, - isRedesignedTransactionsUserSettingEnabled: true, // user setting enabled - isRedesignedConfirmationsDeveloperEnabled: false, // developer mode disabled - }), - ).toBe(false); - }); - - it('should return false if decoding is disabled', () => { - expect( - shouldUseRedesignForTransactions({ - transactionMetadataType: unsupportedTransactionType, - isRedesignedTransactionsUserSettingEnabled: true, // user setting enabled - isRedesignedConfirmationsDeveloperEnabled: false, // developer mode disabled - isDecodingEnabled: false, - }), - ).toBe(false); - }); - }); - describe('when developer mode is enabled', () => { const originalEnv = process.env; @@ -74,7 +39,6 @@ describe('confirmation.utils', () => { expect( shouldUseRedesignForTransactions({ transactionMetadataType: transactionType, - isRedesignedTransactionsUserSettingEnabled: false, // user setting disabled isRedesignedConfirmationsDeveloperEnabled: false, // developer setting disabled }), ).toBe(true); @@ -86,7 +50,6 @@ describe('confirmation.utils', () => { expect( shouldUseRedesignForTransactions({ transactionMetadataType: transactionType, - isRedesignedTransactionsUserSettingEnabled: false, // user setting disabled isRedesignedConfirmationsDeveloperEnabled: true, // developer setting enabled }), ).toBe(true); @@ -99,49 +62,10 @@ describe('confirmation.utils', () => { expect( shouldUseRedesignForTransactions({ transactionMetadataType: unsupportedTransactionType, - isRedesignedTransactionsUserSettingEnabled: false, // user setting disabled isRedesignedConfirmationsDeveloperEnabled: true, // developer setting enabled }), ).toBe(false); }); - - it('should return false if decoding is disabled', () => { - expect( - shouldUseRedesignForTransactions({ - transactionMetadataType: unsupportedTransactionType, - isRedesignedTransactionsUserSettingEnabled: false, // user setting disabled - isRedesignedConfirmationsDeveloperEnabled: true, // developer mode enabled - isDecodingEnabled: false, - }), - ).toBe(false); - }); - }); - - describe('when both user setting and developer mode are disabled', () => { - const originalEnv = process.env; - - beforeEach(() => { - process.env = { ...originalEnv }; - process.env.ENABLE_CONFIRMATION_REDESIGN = 'false'; - }); - - afterEach(() => { - process.env = originalEnv; - }); - - it('should return false for all transaction types', () => { - [...supportedTransactionTypes, unsupportedTransactionType].forEach( - (transactionType) => { - expect( - shouldUseRedesignForTransactions({ - transactionMetadataType: transactionType, - isRedesignedTransactionsUserSettingEnabled: false, // user setting disabled - isRedesignedConfirmationsDeveloperEnabled: false, // developer setting disabled - }), - ).toBe(false); - }, - ); - }); }); }); diff --git a/shared/lib/confirmation.utils.ts b/shared/lib/confirmation.utils.ts index 1813211582be..380845c396f3 100644 --- a/shared/lib/confirmation.utils.ts +++ b/shared/lib/confirmation.utils.ts @@ -30,29 +30,17 @@ const REDESIGN_DEV_TRANSACTION_TYPES = [...REDESIGN_USER_TRANSACTION_TYPES]; * based on user settings and developer mode * * @param opts.transactionMetadataType - The type of transaction to check - * @param opts.isRedesignedTransactionsUserSettingEnabled - Whether the user has enabled the redesigned flow * @param opts.isRedesignedConfirmationsDeveloperEnabled - Whether developer mode is enabled */ export function shouldUseRedesignForTransactions({ transactionMetadataType, - isRedesignedTransactionsUserSettingEnabled, isRedesignedConfirmationsDeveloperEnabled, - isDecodingEnabled, }: { transactionMetadataType?: TransactionType; - isRedesignedTransactionsUserSettingEnabled: boolean; isRedesignedConfirmationsDeveloperEnabled: boolean; - isDecodingEnabled?: boolean; }): boolean { - if (isDecodingEnabled === false) { - return false; - } - return ( - shouldUseRedesignForTransactionsUserMode( - isRedesignedTransactionsUserSettingEnabled, - transactionMetadataType, - ) || + shouldUseRedesignForTransactionsUserMode(transactionMetadataType) || shouldUseRedesignForTransactionsDeveloperMode( isRedesignedConfirmationsDeveloperEnabled, transactionMetadataType, @@ -161,15 +149,10 @@ function shouldUseRedesignForTransactionsDeveloperMode( * Determines if the redesigned confirmation flow should be used for transactions * when in user mode * - * @param isRedesignedTransactionsUserSettingEnabled - Whether the user has enabled the redesigned flow * @param transactionMetadataType - The type of transaction to check */ function shouldUseRedesignForTransactionsUserMode( - isRedesignedTransactionsUserSettingEnabled: boolean, transactionMetadataType?: TransactionType, ): boolean { - return ( - isRedesignedTransactionsUserSettingEnabled && - isCorrectUserTransactionType(transactionMetadataType) - ); + return isCorrectUserTransactionType(transactionMetadataType); } diff --git a/shared/lib/four-byte.test.ts b/shared/lib/four-byte.test.ts index 77271c4aeba3..2909bc169279 100644 --- a/shared/lib/four-byte.test.ts +++ b/shared/lib/four-byte.test.ts @@ -1,4 +1,4 @@ -import { HttpProvider } from '@metamask/ethjs'; +import { JsonRpcProvider } from '@ethersproject/providers'; import nock from 'nock'; import { @@ -68,10 +68,10 @@ describe('Four Byte', () => { }); describe('getMethodDataAsync', () => { - global.ethereumProvider = new HttpProvider( - 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', - ); it('returns a valid signature for setApprovalForAll when use4ByteResolution privacy setting is ON', async () => { + const provider = new JsonRpcProvider({ + url: 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', + }); nock('https://www.4byte.directory:443', { encodedQueryParams: true }) .get('/api/v1/signatures/') .query({ hex_signature: '0xa22cb465' }) @@ -96,7 +96,9 @@ describe('Four Byte', () => { }, ], }); - expect(await getMethodDataAsync('0xa22cb465', true)).toStrictEqual({ + expect( + await getMethodDataAsync('0xa22cb465', true, provider), + ).toStrictEqual({ name: 'Set Approval For All', params: [{ type: 'address' }, { type: 'bool' }], }); diff --git a/shared/lib/index.d.ts b/shared/lib/index.d.ts deleted file mode 100644 index 03952d5a6c3d..000000000000 --- a/shared/lib/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module '@metamask/ethjs'; diff --git a/shared/lib/multichain.ts b/shared/lib/multichain.ts index 26111a0970a2..49dc1add445b 100644 --- a/shared/lib/multichain.ts +++ b/shared/lib/multichain.ts @@ -6,7 +6,8 @@ import { } from '@metamask/utils'; import { validate, Network } from 'bitcoin-address-validation'; import { isAddress } from '@solana/addresses'; -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; /** * Returns whether an address is on the Bitcoin mainnet. diff --git a/shared/lib/token-util.ts b/shared/lib/token-util.ts index 18591b550ec7..37969287fd45 100644 --- a/shared/lib/token-util.ts +++ b/shared/lib/token-util.ts @@ -1,6 +1,7 @@ import { abiERC20, abiERC1155 } from '@metamask/metamask-eth-abis'; import { Contract } from '@ethersproject/contracts'; import { Web3Provider } from '@ethersproject/providers'; +import type { Provider } from '@metamask/network-controller'; /** * Gets the '_value' parameter of the given token transaction data @@ -28,9 +29,7 @@ export function getTokenIdParam(tokenData: any = {}): string | undefined { export async function fetchTokenBalance( address: string, userAddress: string, - // TODO: Replace `any` with type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - provider: any, + provider: Provider, // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Promise { diff --git a/shared/modules/bridge-utils/balance.test.ts b/shared/modules/bridge-utils/balance.test.ts index 15cf1f246c8b..03bd0c9500f1 100644 --- a/shared/modules/bridge-utils/balance.test.ts +++ b/shared/modules/bridge-utils/balance.test.ts @@ -25,8 +25,7 @@ describe('balance', () => { chainId: CHAIN_IDS.MAINNET, }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - global.ethereumProvider = provider as any; + global.ethereumProvider = provider; }); describe('calcLatestSrcBalance', () => { diff --git a/shared/modules/bridge-utils/balance.ts b/shared/modules/bridge-utils/balance.ts index 2ba5834d8df9..3900ac9400bd 100644 --- a/shared/modules/bridge-utils/balance.ts +++ b/shared/modules/bridge-utils/balance.ts @@ -1,13 +1,13 @@ import { Web3Provider } from '@ethersproject/providers'; +import type { Provider } from '@metamask/network-controller'; import { Hex } from '@metamask/utils'; import { zeroAddress } from 'ethereumjs-util'; import { getAddress } from 'ethers/lib/utils'; -import { HttpProvider } from '../../../types/global'; import { fetchTokenBalance } from '../../lib/token-util'; import { Numeric } from '../Numeric'; export const calcLatestSrcBalance = async ( - provider: HttpProvider, + provider: Provider, selectedAddress: string, tokenAddress: string, chainId: Hex, @@ -33,14 +33,14 @@ export const calcLatestSrcBalance = async ( }; export const hasSufficientBalance = async ( - provider: unknown, + provider: Provider, selectedAddress: string, tokenAddress: string, fromTokenAmount: string, chainId: Hex, ) => { const srcTokenBalance = await calcLatestSrcBalance( - provider as HttpProvider, + provider, selectedAddress, tokenAddress, chainId, diff --git a/ui/pages/bridge/bridge.util.test.ts b/shared/modules/bridge-utils/bridge.util.test.ts similarity index 96% rename from ui/pages/bridge/bridge.util.test.ts rename to shared/modules/bridge-utils/bridge.util.test.ts index f302cd44090c..b9fea3db1ea8 100644 --- a/ui/pages/bridge/bridge.util.test.ts +++ b/shared/modules/bridge-utils/bridge.util.test.ts @@ -1,8 +1,8 @@ -import fetchWithCache from '../../../shared/lib/fetch-with-cache'; -import { CHAIN_IDS } from '../../../shared/constants/network'; +import { zeroAddress } from 'ethereumjs-util'; +import fetchWithCache from '../../lib/fetch-with-cache'; +import { CHAIN_IDS } from '../../constants/network'; import mockBridgeQuotesErc20Erc20 from '../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../test/data/bridge/mock-quotes-native-erc20.json'; -import { zeroAddress } from '../../__mocks__/ethereumjs-util'; import { fetchBridgeFeatureFlags, fetchBridgeQuotes, @@ -149,7 +149,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeFeatureFlags()).rejects.toThrowError(mockError); + await expect(fetchBridgeFeatureFlags()).rejects.toThrow(mockError); }); }); @@ -223,7 +223,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeTokens('0xa')).rejects.toThrowError(mockError); + await expect(fetchBridgeTokens('0xa')).rejects.toThrow(mockError); }); }); diff --git a/ui/pages/bridge/bridge.util.ts b/shared/modules/bridge-utils/bridge.util.ts similarity index 87% rename from ui/pages/bridge/bridge.util.ts rename to shared/modules/bridge-utils/bridge.util.ts index 534ea3418219..b7da42ba9cc6 100644 --- a/ui/pages/bridge/bridge.util.ts +++ b/shared/modules/bridge-utils/bridge.util.ts @@ -1,36 +1,25 @@ import { Contract } from '@ethersproject/contracts'; import { Hex, add0x } from '@metamask/utils'; import { abiERC20 } from '@metamask/metamask-eth-abis'; -import { - BridgeFeatureFlagsKey, - BridgeFeatureFlags, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; import { BRIDGE_API_BASE_URL, BRIDGE_CLIENT_ID, ETH_USDT_ADDRESS, METABRIDGE_ETHEREUM_ADDRESS, -} from '../../../shared/constants/bridge'; -import { MINUTE } from '../../../shared/constants/time'; -import fetchWithCache from '../../../shared/lib/fetch-with-cache'; -import { - decimalToHex, - hexToDecimal, -} from '../../../shared/modules/conversion.utils'; + REFRESH_INTERVAL_MS, +} from '../../constants/bridge'; +import { MINUTE } from '../../constants/time'; +import fetchWithCache from '../../lib/fetch-with-cache'; +import { decimalToHex, hexToDecimal } from '../conversion.utils'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP, SwapsTokenObject, -} from '../../../shared/constants/swaps'; +} from '../../constants/swaps'; import { isSwapsDefaultTokenAddress, isSwapsDefaultTokenSymbol, -} from '../../../shared/modules/swaps.utils'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { REFRESH_INTERVAL_MS } from '../../../app/scripts/controllers/bridge/constants'; -import { CHAIN_IDS } from '../../../shared/constants/network'; +} from '../swaps.utils'; +import { CHAIN_IDS } from '../../constants/network'; import { BridgeAsset, BridgeFlag, @@ -41,7 +30,9 @@ import { QuoteRequest, QuoteResponse, TxData, -} from './types'; + BridgeFeatureFlagsKey, + BridgeFeatureFlags, +} from '../../types/bridge'; import { FEATURE_FLAG_VALIDATORS, QUOTE_VALIDATORS, @@ -50,7 +41,7 @@ import { validateResponse, QUOTE_RESPONSE_VALIDATORS, FEE_DATA_VALIDATORS, -} from './utils/validators'; +} from './validators'; const CLIENT_ID_HEADER = { 'X-Client-Id': BRIDGE_CLIENT_ID }; const CACHE_REFRESH_TEN_MINUTES = 10 * MINUTE; diff --git a/shared/modules/bridge-utils/quote.ts b/shared/modules/bridge-utils/quote.ts new file mode 100644 index 000000000000..3fe4406fa333 --- /dev/null +++ b/shared/modules/bridge-utils/quote.ts @@ -0,0 +1,36 @@ +import type { QuoteRequest } from '../../types/bridge'; + +export const isValidQuoteRequest = ( + partialRequest: Partial, + requireAmount = true, +): partialRequest is QuoteRequest => { + const STRING_FIELDS = ['srcTokenAddress', 'destTokenAddress']; + if (requireAmount) { + STRING_FIELDS.push('srcTokenAmount'); + } + const NUMBER_FIELDS = ['srcChainId', 'destChainId', 'slippage']; + + return ( + STRING_FIELDS.every( + (field) => + field in partialRequest && + typeof partialRequest[field as keyof typeof partialRequest] === + 'string' && + partialRequest[field as keyof typeof partialRequest] !== undefined && + partialRequest[field as keyof typeof partialRequest] !== '' && + partialRequest[field as keyof typeof partialRequest] !== null, + ) && + NUMBER_FIELDS.every( + (field) => + field in partialRequest && + typeof partialRequest[field as keyof typeof partialRequest] === + 'number' && + partialRequest[field as keyof typeof partialRequest] !== undefined && + !isNaN(Number(partialRequest[field as keyof typeof partialRequest])) && + partialRequest[field as keyof typeof partialRequest] !== null, + ) && + (requireAmount + ? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\d*$/u)) + : true) + ); +}; diff --git a/ui/pages/bridge/utils/validators.ts b/shared/modules/bridge-utils/validators.ts similarity index 96% rename from ui/pages/bridge/utils/validators.ts rename to shared/modules/bridge-utils/validators.ts index 08fc3519ef52..edfbabdafaa3 100644 --- a/ui/pages/bridge/utils/validators.ts +++ b/shared/modules/bridge-utils/validators.ts @@ -1,10 +1,7 @@ import { isStrictHexString } from '@metamask/utils'; import { isValidHexAddress as isValidHexAddress_ } from '@metamask/controller-utils'; -import { - truthyDigitString, - validateData, -} from '../../../../shared/lib/swaps-utils'; -import { BridgeFlag, FeatureFlagResponse } from '../types'; +import { truthyDigitString, validateData } from '../../lib/swaps-utils'; +import { BridgeFlag, FeatureFlagResponse } from '../../types/bridge'; type Validator = { property: keyof ExpectedResponse | string; diff --git a/shared/modules/contract-utils.test.js b/shared/modules/contract-utils.test.js index 622f76d62948..eeac97c02dfc 100644 --- a/shared/modules/contract-utils.test.js +++ b/shared/modules/contract-utils.test.js @@ -1,27 +1,29 @@ +import { createTestProviderTools } from '../../test/stub/provider'; + const { readAddressAsContract } = require('./contract-utils'); describe('Contract Utils', () => { it('checks is an address is a contract address or not', async () => { - let mockEthQuery = { - getCode: (_, cb) => { - cb(null, '0xa'); + let mockProvider = createTestProviderTools({ + scaffold: { + eth_getCode: '0xa', }, - }; + }).provider; const { isContractAddress } = await readAddressAsContract( - mockEthQuery, + mockProvider, '0x76B4aa9Fc4d351a0062c6af8d186DF959D564A84', ); expect(isContractAddress).toStrictEqual(true); - mockEthQuery = { - getCode: (_, cb) => { - cb(null, '0x'); + mockProvider = createTestProviderTools({ + scaffold: { + eth_getCode: '0x', }, - }; + }).provider; const { isContractAddress: isNotContractAddress } = await readAddressAsContract( - mockEthQuery, + mockProvider, '0x76B4aa9Fc4d351a0062c6af8d186DF959D564A84', ); expect(isNotContractAddress).toStrictEqual(false); diff --git a/shared/modules/contract-utils.ts b/shared/modules/contract-utils.ts index 43e608150a1b..5faf6b9d1339 100644 --- a/shared/modules/contract-utils.ts +++ b/shared/modules/contract-utils.ts @@ -1,5 +1,6 @@ import pify from 'pify'; -import type EthQuery from '@metamask/eth-query'; +import type { Provider } from '@metamask/network-controller'; +import { addHexPrefix, padToEven } from 'ethereumjs-util'; export type Contract = { contractCode: string | null; @@ -7,14 +8,16 @@ export type Contract = { }; export const readAddressAsContract = async ( - ethQuery: EthQuery, + provider: Provider, address: string, ): Promise => { let contractCode: string | null = null; try { - if (ethQuery && 'getCode' in ethQuery) { - contractCode = await pify(ethQuery.getCode.bind(ethQuery))(address); - } + const { result } = await pify(provider.sendAsync.bind(provider))({ + method: 'eth_getCode', + params: [address, 'latest'], + }); + contractCode = addHexPrefix(padToEven(result.slice(2))); } catch (err) { // TODO(@dbrans): Dangerous to swallow errors here. contractCode = null; diff --git a/shared/modules/metametrics.test.ts b/shared/modules/metametrics.test.ts index b6fe2f8ac0a2..a77afb4132d3 100644 --- a/shared/modules/metametrics.test.ts +++ b/shared/modules/metametrics.test.ts @@ -41,7 +41,6 @@ const createTransactionMetricsRequest = (customProps = {}) => { trackEvent: jest.fn(), getIsSmartTransaction: jest.fn(), getSmartTransactionByMinedTxHash: jest.fn(), - getRedesignedTransactionsEnabled: jest.fn(), getMethodData: jest.fn(), getIsRedesignedConfirmationsDeveloperEnabled: jest.fn(), getIsConfirmationAdvancedDetailsOpen: jest.fn(), diff --git a/shared/modules/selectors/smart-transactions.ts b/shared/modules/selectors/smart-transactions.ts index 9367c24853c6..f3f7bb922711 100644 --- a/shared/modules/selectors/smart-transactions.ts +++ b/shared/modules/selectors/smart-transactions.ts @@ -17,6 +17,7 @@ type SmartTransactionsMetaMaskState = { metamask: { preferences: { smartTransactionsOptInStatus?: boolean; + smartTransactionsMigrationApplied?: boolean; }; internalAccounts: { selectedAccount: string; @@ -72,6 +73,25 @@ export const getSmartTransactionsOptInStatusInternal = createSelector( }, ); +/** + * Returns whether the smart transactions migration has been applied to the user's settings. + * This specifically tracks if Migration 135 has been run, which enables Smart Transactions + * by default for users who have never interacted with the feature or who previously opted out + * with no STX activity. + * + * This should only be used for internal checks of the migration status, and not + * for determining overall Smart Transactions availability. + * + * @param state - The state object. + * @returns true if the migration has been applied to the user's settings, false if not or if unset. + */ +export const getSmartTransactionsMigrationAppliedInternal = createSelector( + getPreferences, + (preferences: { smartTransactionsMigrationApplied?: boolean }): boolean => { + return preferences?.smartTransactionsMigrationApplied ?? false; + }, +); + /** * Returns the user's explicit opt-in status for the smart transactions feature. * This should only be used for metrics collection, and not for determining if the diff --git a/shared/modules/transaction.utils.test.js b/shared/modules/transaction.utils.test.js index 28bfaaa34ed7..c501491fce6f 100644 --- a/shared/modules/transaction.utils.test.js +++ b/shared/modules/transaction.utils.test.js @@ -1,4 +1,3 @@ -import EthQuery from '@metamask/ethjs-query'; import { TransactionType } from '@metamask/transaction-controller'; import { createTestProviderTools } from '../../test/stub/provider'; @@ -111,8 +110,7 @@ describe('Transaction.utils', function () { }); describe('determineTransactionType', function () { - const genericProvider = createTestProviderTools().provider; - const query = new EthQuery(genericProvider); + const { provider: genericProvider } = createTestProviderTools(); it('should return a simple send type when to is truthy and is not a contract address', async function () { const _providerResultStub = { @@ -121,16 +119,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0x', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0xabcabcabcabcabcabcabcabcabcabcabcabcabca', data: '', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.simpleSend, @@ -145,16 +143,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xab', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.tokenMethodTransfer, @@ -172,9 +170,9 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xab', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const resultWithEmptyValue = await determineTransactionType( { @@ -182,7 +180,7 @@ describe('Transaction.utils', function () { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', }, - new EthQuery(_provider), + provider, ); expect(resultWithEmptyValue).toMatchObject({ type: TransactionType.tokenMethodTransfer, @@ -195,7 +193,7 @@ describe('Transaction.utils', function () { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', }, - new EthQuery(_provider), + provider, ); expect(resultWithEmptyValue2).toMatchObject({ @@ -209,7 +207,7 @@ describe('Transaction.utils', function () { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', }, - new EthQuery(_provider), + provider, ); expect(resultWithValue).toMatchObject({ type: TransactionType.contractInteraction, @@ -225,16 +223,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0x', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.simpleSend, @@ -249,16 +247,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xab', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.tokenMethodApprove, @@ -272,7 +270,7 @@ describe('Transaction.utils', function () { to: '', data: '0xabd', }, - query, + genericProvider, ); expect(result).toMatchObject({ type: TransactionType.deployContract, @@ -286,7 +284,7 @@ describe('Transaction.utils', function () { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xabd', }, - query, + genericProvider, ); expect(result).toMatchObject({ type: TransactionType.simpleSend, @@ -301,16 +299,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: null, }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '0xabd', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.simpleSend, @@ -325,16 +323,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xa', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: 'abd', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.contractInteraction, @@ -349,16 +347,16 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xa', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9', data: '', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.contractInteraction, @@ -373,9 +371,9 @@ describe('Transaction.utils', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0xa', }; - const _provider = createTestProviderTools({ + const { provider } = createTestProviderTools({ scaffold: _providerResultStub, - }).provider; + }); const result = await determineTransactionType( { @@ -383,7 +381,7 @@ describe('Transaction.utils', function () { value: '0x5af3107a4000', data: '0x095ea7b30000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C9700000000000000000000000000000000000000000000000000000000000000005', }, - new EthQuery(_provider), + provider, ); expect(result).toMatchObject({ type: TransactionType.contractInteraction, diff --git a/shared/modules/transaction.utils.ts b/shared/modules/transaction.utils.ts index 910fe9b6d4be..728edbca87c2 100644 --- a/shared/modules/transaction.utils.ts +++ b/shared/modules/transaction.utils.ts @@ -6,13 +6,13 @@ import { abiERC1155, abiFiatTokenV2, } from '@metamask/metamask-eth-abis'; -import type EthQuery from '@metamask/eth-query'; import log from 'loglevel'; import { TransactionMeta, TransactionType, } from '@metamask/transaction-controller'; import type { TransactionParams } from '@metamask/transaction-controller'; +import type { Provider } from '@metamask/network-controller'; import { Hex } from '@metamask/utils'; import { AssetType, TokenStandard } from '../constants/transaction'; @@ -141,12 +141,12 @@ export function parseStandardTokenTransactionData(data: string) { * at transaction creation. * * @param txParams - Parameters for the transaction - * @param query - EthQuery instance + * @param provider - Provider instance * @returns InferTransactionTypeResult */ export async function determineTransactionType( txParams: TransactionParams, - query: EthQuery, + provider: Provider, ): Promise { const { data, to } = txParams; let contractCode: string | null | undefined; @@ -159,7 +159,7 @@ export async function determineTransactionType( } if (to) { const { contractCode: resultCode, isContractAddress } = - await readAddressAsContract(query, to); + await readAddressAsContract(provider, to); contractCode = resultCode; @@ -211,13 +211,13 @@ type GetTokenStandardAndDetails = (to: string | undefined) => Promise<{ * is a token transaction. * * @param txMeta - transaction meta object - * @param query - EthQuery instance + * @param provider - Provider instance * @param getTokenStandardAndDetails - function to get token standards and details. * @returns assetType: AssetType, tokenStandard: TokenStandard */ export async function determineTransactionAssetType( txMeta: TransactionMeta, - query: EthQuery, + provider: Provider, getTokenStandardAndDetails: GetTokenStandardAndDetails, ): Promise<{ assetType: AssetType; @@ -230,7 +230,7 @@ export async function determineTransactionAssetType( // Because we will deal with all types of transactions (including swaps) // we want to get an inferrable type of transaction that isn't special cased // that way we can narrow the number of logic gates required. - const result = await determineTransactionType(txMeta.txParams, query); + const result = await determineTransactionType(txMeta.txParams, provider); inferrableType = result.type; } @@ -294,10 +294,10 @@ function extractLargeMessageValue(dataToParse: string): string | undefined { } /** - * JSON.parse has a limitation which coerces values to scientific notation if numbers are greator than + * JSON.parse has a limitation which coerces values to scientific notation if numbers are greater than * Number.MAX_SAFE_INTEGER. This can cause a loss in precision. * - * Aside from precision concerns, if the value returned was a large number greator than 15 digits, + * Aside from precision concerns, if the value returned was a large number greater than 15 digits, * e.g. 3.000123123123121e+26, passing the value to BigNumber will throw the error: * Error: new BigNumber() number type has more than 15 significant digits * diff --git a/shared/types/bridge-status.ts b/shared/types/bridge-status.ts index fc9357ef968a..bd892eac82dc 100644 --- a/shared/types/bridge-status.ts +++ b/shared/types/bridge-status.ts @@ -1,12 +1,5 @@ import { TransactionMeta } from '@metamask/transaction-controller'; -// TODO fix this -import { - ChainId, - Quote, - QuoteMetadata, - QuoteResponse, - // eslint-disable-next-line import/no-restricted-paths -} from '../../ui/pages/bridge/types'; +import type { ChainId, Quote, QuoteMetadata, QuoteResponse } from './bridge'; // All fields need to be types not interfaces, same with their children fields // o/w you get a type error @@ -153,9 +146,8 @@ export enum BridgeStatusAction { GET_STATE = 'getState', } -// The BigNumber values are serialized to strings export type QuoteMetadataSerialized = { - sentAmount: { amount: string; fiat: string | null }; + sentAmount: { amount: string; valueInCurrency: string | null }; }; export type StartPollingForBridgeTxStatusArgs = { @@ -168,6 +160,11 @@ export type StartPollingForBridgeTxStatusArgs = { targetContractAddress?: BridgeHistoryItem['targetContractAddress']; }; +/** + * Chrome: The BigNumber values are automatically serialized to strings when sent to the background + * Firefox: The BigNumber values are not serialized to strings when sent to the background, + * so we force the ui to do it manually, by using StartPollingForBridgeTxStatusArgsSerialized type on the startPollingForBridgeTxStatus action + */ export type StartPollingForBridgeTxStatusArgsSerialized = Omit< StartPollingForBridgeTxStatusArgs, 'quoteResponse' diff --git a/shared/types/bridge.ts b/shared/types/bridge.ts index 6cfab93f47ed..763c2670abad 100644 --- a/shared/types/bridge.ts +++ b/shared/types/bridge.ts @@ -1,4 +1,202 @@ +import type { Hex } from '@metamask/utils'; +import type { BigNumber } from 'bignumber.js'; +import type { AssetType } from '../constants/transaction'; +import type { SwapsTokenObject } from '../constants/swaps'; + export type ChainConfiguration = { isActiveSrc: boolean; isActiveDest: boolean; }; + +export type L1GasFees = { + l1GasFeesInHexWei?: string; // l1 fees for approval and trade in hex wei, appended by controller +}; +// Values derived from the quote response +// valueInCurrency values are calculated based on the user's selected currency + +export type QuoteMetadata = { + gasFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; + totalNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // estimatedGasFees + relayerFees + totalMaxNetworkFee: { amount: BigNumber; valueInCurrency: BigNumber | null }; // maxGasFees + relayerFees + toTokenAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; + adjustedReturn: { valueInCurrency: BigNumber | null }; // destTokenAmount - totalNetworkFee + sentAmount: { amount: BigNumber; valueInCurrency: BigNumber | null }; // srcTokenAmount + metabridgeFee + swapRate: BigNumber; // destTokenAmount / sentAmount + cost: { valueInCurrency: BigNumber | null }; // sentAmount - adjustedReturn +}; +// Sort order set by the user + +export enum SortOrder { + COST_ASC = 'cost_ascending', + ETA_ASC = 'time_descending', +} + +export type BridgeToken = { + type: AssetType.native | AssetType.token; + address: string; + symbol: string; + image: string; + decimals: number; + chainId: Hex; + balance: string; // raw balance + string: string | undefined; // normalized balance as a stringified number + tokenFiatAmount?: number | null; +} | null; +// Types copied from Metabridge API + +export enum BridgeFlag { + EXTENSION_CONFIG = 'extension-config', +} +type DecimalChainId = string; +export type GasMultiplierByChainId = Record; + +export type FeatureFlagResponse = { + [BridgeFlag.EXTENSION_CONFIG]: { + refreshRate: number; + maxRefreshCount: number; + support: boolean; + chains: Record; + }; +}; + +export type BridgeAsset = { + chainId: ChainId; + address: string; + symbol: string; + name: string; + decimals: number; + icon?: string; +}; + +export type QuoteRequest = { + walletAddress: string; + destWalletAddress?: string; + srcChainId: ChainId; + destChainId: ChainId; + srcTokenAddress: string; + destTokenAddress: string; + srcTokenAmount: string; // This is the amount sent + slippage: number; + aggIds?: string[]; + bridgeIds?: string[]; + insufficientBal?: boolean; + resetApproval?: boolean; + refuel?: boolean; +}; +type Protocol = { + name: string; + displayName?: string; + icon?: string; +}; +enum ActionTypes { + BRIDGE = 'bridge', + SWAP = 'swap', + REFUEL = 'refuel', +} +type Step = { + action: ActionTypes; + srcChainId: ChainId; + destChainId?: ChainId; + srcAsset: BridgeAsset; + destAsset: BridgeAsset; + srcAmount: string; + destAmount: string; + protocol: Protocol; +}; +type RefuelData = Step; + +export type Quote = { + requestId: string; + srcChainId: ChainId; + srcAsset: BridgeAsset; + // Some tokens have a fee of 0, so sometimes it's equal to amount sent + srcTokenAmount: string; // Atomic amount, the amount sent - fees + destChainId: ChainId; + destAsset: BridgeAsset; + destTokenAmount: string; // Atomic amount, the amount received + feeData: Record & + Partial>; + bridgeId: string; + bridges: string[]; + steps: Step[]; + refuel?: RefuelData; +}; + +export type QuoteResponse = { + quote: Quote; + approval: TxData | null; + trade: TxData; + estimatedProcessingTimeInSeconds: number; +}; + +export enum ChainId { + ETH = 1, + OPTIMISM = 10, + BSC = 56, + POLYGON = 137, + ZKSYNC = 324, + BASE = 8453, + ARBITRUM = 42161, + AVALANCHE = 43114, + LINEA = 59144, +} + +export enum FeeType { + METABRIDGE = 'metabridge', + REFUEL = 'refuel', +} +export type FeeData = { + amount: string; + asset: BridgeAsset; +}; +export type TxData = { + chainId: ChainId; + to: string; + from: string; + value: string; + data: string; + gasLimit: number | null; +}; +export enum BridgeFeatureFlagsKey { + EXTENSION_CONFIG = 'extensionConfig', +} + +export type BridgeFeatureFlags = { + [BridgeFeatureFlagsKey.EXTENSION_CONFIG]: { + refreshRate: number; + maxRefreshCount: number; + support: boolean; + chains: Record; + }; +}; +export enum RequestStatus { + LOADING, + FETCHED, + ERROR, +} +export enum BridgeUserAction { + SELECT_SRC_NETWORK = 'selectSrcNetwork', + SELECT_DEST_NETWORK = 'selectDestNetwork', + UPDATE_QUOTE_PARAMS = 'updateBridgeQuoteRequestParams', +} +export enum BridgeBackgroundAction { + SET_FEATURE_FLAGS = 'setBridgeFeatureFlags', + RESET_STATE = 'resetState', + GET_BRIDGE_ERC20_ALLOWANCE = 'getBridgeERC20Allowance', +} +export type BridgeControllerState = { + bridgeFeatureFlags: BridgeFeatureFlags; + srcTokens: Record; + srcTopAssets: { address: string }[]; + srcTokensLoadingStatus?: RequestStatus; + destTokensLoadingStatus?: RequestStatus; + destTokens: Record; + destTopAssets: { address: string }[]; + quoteRequest: Partial; + quotes: (QuoteResponse & L1GasFees)[]; + quotesInitialLoadTime?: number; + quotesLastFetched?: number; + quotesLoadingStatus?: RequestStatus; + quoteFetchError?: string; + quotesRefreshCount: number; +}; diff --git a/test/data/bridge/dummy-quotes.ts b/test/data/bridge/dummy-quotes.ts index 3328960a9b73..8b3e907d7df2 100644 --- a/test/data/bridge/dummy-quotes.ts +++ b/test/data/bridge/dummy-quotes.ts @@ -1,6 +1,10 @@ export const DummyQuotesNoApproval = { OP_0_005_ETH_TO_ARB: [ { + sentAmount: { + amount: '0.005', + valueInCurrency: null, + }, quote: { requestId: 'be448070-7849-4d14-bb35-8dcdaf7a4d69', srcChainId: 10, @@ -392,6 +396,10 @@ export const DummyQuotesNoApproval = { export const DummyQuotesWithApproval = { ETH_11_USDC_TO_ARB: [ { + sentAmount: { + amount: '1.0903750', + valueInCurrency: null, + }, quote: { requestId: '0cd5caf6-9844-465b-89ad-9c89b639f432', srcChainId: 1, @@ -812,6 +820,10 @@ export const DummyQuotesWithApproval = { ], ARB_11_USDC_TO_ETH: [ { + sentAmount: { + amount: '1.0903750', + valueInCurrency: null, + }, quote: { requestId: 'edbef62a-d3e6-4b33-aad5-9cdb81f85f53', srcChainId: 42161, @@ -911,6 +923,10 @@ export const DummyQuotesWithApproval = { ], ARB_11_USDC_TO_OP: [ { + sentAmount: { + amount: '1.0903750', + valueInCurrency: null, + }, quote: { requestId: 'dc63e7e6-dc9b-4aa8-80bb-714192ecd801', srcChainId: 42161, @@ -2461,6 +2477,10 @@ export const DummyQuotesWithApproval = { ], OP_11_USDC_TO_ARB: [ { + sentAmount: { + amount: '1.1000000', + valueInCurrency: null, + }, quote: { requestId: '01fa78fd-ed49-42b3-ab0e-94c7108feea9', srcChainId: 10, diff --git a/test/data/confirmations/helper.ts b/test/data/confirmations/helper.ts index b8bd8a634588..e4f0d58ea29d 100644 --- a/test/data/confirmations/helper.ts +++ b/test/data/confirmations/helper.ts @@ -29,7 +29,6 @@ export const getMockTypedSignConfirmState = ( ...args.metamask, preferences: { ...mockState.metamask.preferences, - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, @@ -56,7 +55,6 @@ export const getMockTypedSignConfirmStateForRequest = ( ...args.metamask, preferences: { ...mockState.metamask.preferences, - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, @@ -82,7 +80,6 @@ export const getMockPersonalSignConfirmState = ( ...args.metamask, preferences: { ...mockState.metamask.preferences, - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, @@ -109,7 +106,6 @@ export const getMockPersonalSignConfirmStateForRequest = ( ...args.metamask, preferences: { ...mockState.metamask.preferences, - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, @@ -134,7 +130,6 @@ export const getMockConfirmState = (args: RootState = { metamask: {} }) => ({ preferences: { ...mockState.metamask.preferences, ...(args.metamask?.preferences as Record), - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, diff --git a/test/data/mock-accounts.ts b/test/data/mock-accounts.ts index b956dbadd6bb..eab4cd4aa74d 100644 --- a/test/data/mock-accounts.ts +++ b/test/data/mock-accounts.ts @@ -1,6 +1,6 @@ import { KeyringTypes } from '@metamask/keyring-controller'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { - InternalAccount, EthAccountType, BtcMethod, BtcAccountType, diff --git a/test/data/mock-send-state.json b/test/data/mock-send-state.json index 0b7cc237547f..124487281ca9 100644 --- a/test/data/mock-send-state.json +++ b/test/data/mock-send-state.json @@ -13,7 +13,6 @@ "networkDropdownOpen": false, "importNftsModal": { "open": false }, "showPermittedNetworkToastOpen": false, - "gasIsLoading": false, "isLoading": false, "importTokensModalOpen": false, "modal": { @@ -133,7 +132,7 @@ } } }, - "snaps": [{}], + "snaps": {}, "preferences": { "hideZeroBalanceTokens": false, "showFiatInTestnets": false, diff --git a/test/data/mock-state.json b/test/data/mock-state.json index 3131b8335287..01d5fc107155 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -10,12 +10,17 @@ "url": "https://metamask.github.io/test-dapp/" }, "appState": { + "isAccountMenuOpen": false, + "confirmationExchangeRates": {}, + "nextNonce": 71, + "welcomeScreenSeen": false, + "pendingTokens": {}, + "customTokenAmount": "10", "networkDropdownOpen": false, "importNftsModal": { "open": false }, "showPermittedNetworkToastOpen": false, - "gasIsLoading": false, "isLoading": false, "modal": { "open": false, @@ -27,8 +32,7 @@ "name": null } }, - "warning": null, - "customTokenAmount": "10" + "warning": null }, "confirmAlerts": { "alerts": [], @@ -40,7 +44,8 @@ "gas": "0x153e2", "value": "0x0" } - } + }, + "maxValueMode": {} }, "history": { "mostRecentOverviewPage": "/mostRecentOverviewPage" @@ -370,6 +375,39 @@ "version": "5.1.2" } ] + }, + "local:snap-id": { + "id": "local:snap-id", + "origin": "local:snap-id", + "version": "5.1.2", + "iconUrl": null, + "initialPermissions": {}, + "manifest": { + "description": "mock snap description", + "proposedName": "mock snap name", + "repository": { + "type": "git", + "url": "https://127.0.0.1" + }, + "source": { + "location": { + "npm": { + "filePath": "dist/bundle.js", + "packageName": "@metamask/test-snap-dialog", + "registry": "https://registry.npmjs.org" + } + }, + "shasum": "L1k+dT9Q+y3KfIqzaH09MpDZVPS9ZowEh9w01ZMTWMU=" + }, + "version": "5.1.2" + }, + "versionHistory": [ + { + "date": 1680686075921, + "origin": "https://metamask.github.io", + "version": "5.1.2" + } + ] } }, "preferences": { @@ -386,11 +424,9 @@ "key": "tokenFiatAmount", "order": "dsc", "sortCallback": "stringNumeric" - }, - "tokenNetworkFilter": {} + } }, "ensResolutionsByAddress": {}, - "isAccountMenuOpen": false, "isUnlocked": true, "alertEnabledness": { "unconnectedAccount": true @@ -541,7 +577,7 @@ }, "snap": { "enabled": true, - "id": "snap-id", + "id": "local:snap-id", "name": "snap-name" } }, @@ -1891,6 +1927,7 @@ "watchEthereumAccountEnabled": false, "bitcoinSupportEnabled": false, "bitcoinTestnetSupportEnabled": false, + "solanaSupportEnabled": false, "pendingApprovals": { "testApprovalId": { "id": "testApprovalId", diff --git a/test/e2e/constants.ts b/test/e2e/constants.ts index 7123d3e4114a..2826200dc293 100644 --- a/test/e2e/constants.ts +++ b/test/e2e/constants.ts @@ -57,6 +57,9 @@ export const DEFAULT_BTC_FEES_RATE = 0.00001; // BTC /* Default BTC conversion rate to USD */ export const DEFAULT_BTC_CONVERSION_RATE = 62000; // USD +/* Default SOL conversion rate to USD */ +export const DEFAULT_SOL_CONVERSION_RATE = 226; // USD + /* Default BTC transaction ID */ export const DEFAULT_BTC_TRANSACTION_ID = 'e4111a707317da67d49a71af4cbcf6c0546f900ca32c3842d2254e315d1fca18'; @@ -70,3 +73,17 @@ export const DEFAULT_SOLANA_ACCOUNT = /* Default (mocked) SOLANA balance used by the Solana RPC provider */ export const DEFAULT_SOLANA_BALANCE = 1; // SOL + +/* Title of Portfolio page */ +export const PORTFOLIO_PAGE_TITLE = 'MetaMask Portfolio'; + +/* Account types */ +export enum ACCOUNT_TYPE { + Ethereum, + Bitcoin, + Solana, +} + +/* Meta metricsId generated by generateMetaMetricsId */ +export const MOCK_META_METRICS_ID = + '0x86bacb9b2bf9a7e8d2b147eadb95ac9aaa26842327cd24afc8bd4b3c1d136420'; diff --git a/test/e2e/default-fixture.js b/test/e2e/default-fixture.js index 5bb2a24d0c5c..51338fd3eea8 100644 --- a/test/e2e/default-fixture.js +++ b/test/e2e/default-fixture.js @@ -244,7 +244,6 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) { useTokenDetection: false, useCurrencyRateCheck: true, useMultiAccountBalanceChecker: true, - useRequestQueue: true, isMultiAccountBalancesEnabled: true, showIncomingTransactions: { [ETHERSCAN_SUPPORTED_CHAIN_IDS.MAINNET]: true, diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index 020c4db1c64b..3c1128331ba6 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -16,7 +16,6 @@ const { DAPP_URL_LOCALHOST, DAPP_ONE_URL, DEFAULT_FIXTURE_ACCOUNT, - ERC_4337_ACCOUNT, } = require('./constants'); const { defaultFixture, @@ -95,7 +94,6 @@ function onboardingFixture() { useTokenDetection: false, useCurrencyRateCheck: true, useMultiAccountBalanceChecker: true, - useRequestQueue: true, isMultiAccountBalancesEnabled: true, showIncomingTransactions: { [ETHERSCAN_SUPPORTED_CHAIN_IDS.MAINNET]: true, @@ -487,7 +485,6 @@ class FixtureBuilder { value: [ selectedAccount.toLowerCase(), '0x09781764c08de8ca82e156bbf156a3ca217c7950', - ERC_4337_ACCOUNT.toLowerCase(), ], }, ], @@ -499,6 +496,34 @@ class FixtureBuilder { }); } + withPermissionControllerConnectedToTestDappWithTwoAccounts() { + const subjects = { + [DAPP_URL]: { + origin: DAPP_URL, + permissions: { + eth_accounts: { + id: 'ZaqPEWxyhNCJYACFw93jE', + parentCapability: 'eth_accounts', + invoker: DAPP_URL, + caveats: [ + { + type: 'restrictReturnedAccounts', + value: [ + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + '0x09781764c08de8ca82e156bbf156a3ca217c7950', + ], + }, + ], + date: 1664388714636, + }, + }, + }, + }; + return this.withPermissionController({ + subjects, + }); + } + withPermissionControllerSnapAccountConnectedToTestDapp( restrictReturnedAccounts = true, ) { @@ -697,11 +722,6 @@ class FixtureBuilder { }); } - withPreferencesControllerAndFeatureFlag(flags) { - merge(this.fixture.data.PreferencesController, flags); - return this; - } - withAccountsController(data) { merge(this.fixture.data.AccountsController, data); return this; @@ -845,15 +865,7 @@ class FixtureBuilder { [DAPP_ONE_URL]: '76e9cd59-d8e2-47e7-b369-9c205ccb602c', }, }), - this.withPreferencesControllerUseRequestQueueEnabled(), - ); - } - - withPreferencesControllerUseRequestQueueEnabled() { - return merge( - this.withPreferencesController({ - useRequestQueue: true, - }), + this, ); } diff --git a/test/e2e/flask/btc/btc-account-overview.spec.ts b/test/e2e/flask/btc/btc-account-overview.spec.ts index 418c9d736078..93ff6ef07ad3 100644 --- a/test/e2e/flask/btc/btc-account-overview.spec.ts +++ b/test/e2e/flask/btc/btc-account-overview.spec.ts @@ -1,63 +1,24 @@ +import { strict as assert } from 'assert'; import { Suite } from 'mocha'; import { DEFAULT_BTC_BALANCE } from '../../constants'; +import BitcoinHomepage from '../../page-objects/pages/home/bitcoin-homepage'; import { withBtcAccountSnap } from './common-btc'; describe('BTC Account - Overview', function (this: Suite) { - it('has portfolio button enabled for BTC accounts', async function () { + it('has balance displayed and has portfolio button enabled for BTC accounts', async function () { await withBtcAccountSnap( { title: this.test?.fullTitle() }, async (driver) => { - await driver.findElement({ - css: '[data-testid="account-menu-icon"]', - text: 'Bitcoin Account', - }); - - await driver.waitForSelector({ - text: 'Send', - tag: 'button', - css: '[data-testid="coin-overview-send"]', - }); - - await driver.waitForSelector({ - text: 'Swap', - tag: 'button', - css: '[disabled]', - }); - - await driver.waitForSelector({ - text: 'Bridge', - tag: 'button', - css: '[disabled]', - }); - - // buy sell button - await driver.findClickableElement('[data-testid="coin-overview-buy"]'); - - // receive button - await driver.findClickableElement( - '[data-testid="coin-overview-receive"]', + const homePage = new BitcoinHomepage(driver); + await homePage.check_pageIsLoaded(); + await homePage.headerNavbar.check_accountLabel('Bitcoin Account'); + await homePage.check_isExpectedBitcoinBalanceDisplayed( + DEFAULT_BTC_BALANCE, ); - }, - ); - }); - - it('has balance', async function () { - await withBtcAccountSnap( - { title: this.test?.fullTitle() }, - async (driver) => { - await driver.waitForSelector({ - testId: 'account-value-and-suffix', - text: `${DEFAULT_BTC_BALANCE}`, - }); - await driver.waitForSelector({ - css: '.currency-display-component__suffix', - text: 'BTC', - }); - - await driver.waitForSelector({ - tag: 'p', - text: `${DEFAULT_BTC_BALANCE} BTC`, - }); + assert.equal(await homePage.check_isBridgeButtonEnabled(), false); + assert.equal(await homePage.check_isSwapButtonEnabled(), false); + assert.equal(await homePage.check_isBuySellButtonEnabled(), true); + assert.equal(await homePage.check_isReceiveButtonEnabled(), true); }, ); }); diff --git a/test/e2e/flask/btc/btc-dapp-connection.spec.ts b/test/e2e/flask/btc/btc-dapp-connection.spec.ts index 2eb33a4b7d74..2a9b413f60b0 100644 --- a/test/e2e/flask/btc/btc-dapp-connection.spec.ts +++ b/test/e2e/flask/btc/btc-dapp-connection.spec.ts @@ -1,5 +1,6 @@ import { Suite } from 'mocha'; -import { openDapp, WINDOW_TITLES } from '../../helpers'; +import BitcoinHomepage from '../../page-objects/pages/home/bitcoin-homepage'; +import TestDapp from '../../page-objects/pages/test-dapp'; import { withBtcAccountSnap } from './common-btc'; describe('BTC Account - Dapp Connection', function (this: Suite) { @@ -7,14 +8,16 @@ describe('BTC Account - Dapp Connection', function (this: Suite) { await withBtcAccountSnap( { title: this.test?.fullTitle() }, async (driver) => { - await openDapp(driver); - await driver.clickElement('#connectButton'); - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const homePage = new BitcoinHomepage(driver); + await homePage.check_pageIsLoaded(); + await homePage.headerNavbar.check_accountLabel('Bitcoin Account'); - await driver.assertElementNotPresent( - '[data-testid="choose-account-list-1"]', - ); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_pageIsLoaded(); + await testDapp.connectAccount({ + connectAccountButtonEnabled: false, + }); }, ); }); diff --git a/test/e2e/flask/btc/btc-experimental-settings.spec.ts b/test/e2e/flask/btc/btc-experimental-settings.spec.ts index 45bc7d0d1701..10a183bf87bb 100644 --- a/test/e2e/flask/btc/btc-experimental-settings.spec.ts +++ b/test/e2e/flask/btc/btc-experimental-settings.spec.ts @@ -1,47 +1,45 @@ import { Suite } from 'mocha'; - -import messages from '../../../../app/_locales/en/messages.json'; import FixtureBuilder from '../../fixture-builder'; -import { - defaultGanacheOptions, - unlockWallet, - withFixtures, -} from '../../helpers'; +import { withFixtures } from '../../helpers'; import { Driver } from '../../webdriver/driver'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import ExperimentalSettings from '../../page-objects/pages/settings/experimental-settings'; +import HomePage from '../../page-objects/pages/home/homepage'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import SettingsPage from '../../page-objects/pages/settings/settings-page'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; describe('BTC Experimental Settings', function (this: Suite) { it('will show `Add a new Bitcoin account (Beta)` option when setting is enabled', async function () { await withFixtures( { fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { - await unlockWallet(driver); - await driver.clickElement( - '[data-testid="account-options-menu-button"]', - ); - await driver.clickElement({ text: 'Settings', tag: 'div' }); - await driver.clickElement({ text: 'Experimental', tag: 'div' }); + await loginWithBalanceValidation(driver); - await driver.waitForSelector({ - text: messages.bitcoinSupportToggleTitle.message, - tag: 'span', - }); + // go to experimental settings page and enable add new Bitcoin account toggle + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); - await driver.clickElement('[data-testid="bitcoin-support-toggle-div"]'); + await new HeaderNavbar(driver).openSettingsPage(); + const settingsPage = new SettingsPage(driver); + await settingsPage.check_pageIsLoaded(); + await settingsPage.goToExperimentalSettings(); - await driver.clickElement('button[aria-label="Close"]'); + const experimentalSettings = new ExperimentalSettings(driver); + await experimentalSettings.check_pageIsLoaded(); + await experimentalSettings.toggleBitcoinAccount(); + await settingsPage.closeSettingsPage(); - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.waitForSelector({ - text: messages.addNewBitcoinAccount.message, - tag: 'button', - }); + // check add new Bitcoin account button is displayed + await homePage.check_pageIsLoaded(); + await new HeaderNavbar(driver).openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_addBitcoinAccountAvailable(true); }, ); }); diff --git a/test/e2e/flask/btc/common-btc.ts b/test/e2e/flask/btc/common-btc.ts index 05f382281e29..a9b87f11499a 100644 --- a/test/e2e/flask/btc/common-btc.ts +++ b/test/e2e/flask/btc/common-btc.ts @@ -2,6 +2,7 @@ import { Mockttp } from 'mockttp'; import FixtureBuilder from '../../fixture-builder'; import { withFixtures } from '../../helpers'; import { + ACCOUNT_TYPE, DEFAULT_BTC_ACCOUNT, DEFAULT_BTC_BALANCE, DEFAULT_BTC_FEES_RATE, @@ -192,7 +193,7 @@ export async function withBtcAccountSnap( await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ bitcoinSupportEnabled: bitcoinSupportEnabled ?? true, }) .build(), @@ -217,7 +218,7 @@ export async function withBtcAccountSnap( await new HeaderNavbar(driver).openAccountMenu(); const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewBtcAccount(); + await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Bitcoin }); await test(driver, mockServer); }, ); diff --git a/test/e2e/flask/btc/create-btc-account.spec.ts b/test/e2e/flask/btc/create-btc-account.spec.ts index 0dfb24a8a931..68cdcd82caf5 100644 --- a/test/e2e/flask/btc/create-btc-account.spec.ts +++ b/test/e2e/flask/btc/create-btc-account.spec.ts @@ -1,12 +1,14 @@ import { strict as assert } from 'assert'; import { Suite } from 'mocha'; import { WALLET_PASSWORD } from '../../helpers'; +import AccountDetailsModal from '../../page-objects/pages/dialog/account-details-modal'; import AccountListPage from '../../page-objects/pages/account-list-page'; import HeaderNavbar from '../../page-objects/pages/header-navbar'; import LoginPage from '../../page-objects/pages/login-page'; import PrivacySettings from '../../page-objects/pages/settings/privacy-settings'; import ResetPasswordPage from '../../page-objects/pages/reset-password-page'; import SettingsPage from '../../page-objects/pages/settings/settings-page'; +import { ACCOUNT_TYPE } from '../../constants'; import { withBtcAccountSnap } from './common-btc'; describe('Create BTC Account', function (this: Suite) { @@ -34,14 +36,12 @@ describe('Create BTC Account', function (this: Suite) { await headerNavbar.openAccountMenu(); const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewBtcAccount({ - btcAccountCreationEnabled: false, - }); - - // check the number of available accounts is 2 - await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); await accountListPage.check_numberOfAvailableAccounts(2); + await accountListPage.openAddAccountModal(); + assert.equal( + await accountListPage.isBtcAccountCreationButtonEnabled(), + false, + ); }, ); }); @@ -83,23 +83,32 @@ describe('Create BTC Account', function (this: Suite) { await headerNavbar.openAccountMenu(); const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - const accountAddress = await accountListPage.getAccountAddress( - 'Bitcoin Account', - ); + await accountListPage.openAccountDetailsModal('Bitcoin Account'); + + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + const accountAddress = await accountDetailsModal.getAccountAddress(); await headerNavbar.openAccountMenu(); await accountListPage.removeAccount('Bitcoin Account'); // Recreate account and check that the address is the same await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewBtcAccount(); + await accountListPage.openAddAccountModal(); + assert.equal( + await accountListPage.isBtcAccountCreationButtonEnabled(), + true, + ); + await accountListPage.closeAccountModal(); + await headerNavbar.openAccountMenu(); + await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Bitcoin }); await headerNavbar.check_accountLabel('Bitcoin Account'); await headerNavbar.openAccountMenu(); await accountListPage.check_pageIsLoaded(); - const recreatedAccountAddress = await accountListPage.getAccountAddress( - 'Bitcoin Account', - ); + await accountListPage.openAccountDetailsModal('Bitcoin Account'); + await accountDetailsModal.check_pageIsLoaded(); + const recreatedAccountAddress = + await accountDetailsModal.getAccountAddress(); assert(accountAddress === recreatedAccountAddress); }, @@ -118,9 +127,10 @@ describe('Create BTC Account', function (this: Suite) { await headerNavbar.openAccountMenu(); const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - const accountAddress = await accountListPage.getAccountAddress( - 'Bitcoin Account', - ); + await accountListPage.openAccountDetailsModal('Bitcoin Account'); + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + const accountAddress = await accountDetailsModal.getAccountAddress(); // go to privacy settings page and get the SRP await headerNavbar.openSettingsPage(); @@ -146,14 +156,16 @@ describe('Create BTC Account', function (this: Suite) { await headerNavbar.check_pageIsLoaded(); await headerNavbar.openAccountMenu(); await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewBtcAccount(); + await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Bitcoin }); await headerNavbar.check_accountLabel('Bitcoin Account'); await headerNavbar.openAccountMenu(); await accountListPage.check_pageIsLoaded(); - const recreatedAccountAddress = await accountListPage.getAccountAddress( - 'Bitcoin Account', - ); + await accountListPage.openAccountDetailsModal('Bitcoin Account'); + await accountDetailsModal.check_pageIsLoaded(); + const recreatedAccountAddress = + await accountDetailsModal.getAccountAddress(); + assert(accountAddress === recreatedAccountAddress); }, ); diff --git a/test/e2e/flask/create-watch-account.spec.ts b/test/e2e/flask/create-watch-account.spec.ts index f25f38f0b2ce..6d0956ae4e72 100644 --- a/test/e2e/flask/create-watch-account.spec.ts +++ b/test/e2e/flask/create-watch-account.spec.ts @@ -1,97 +1,44 @@ import { strict as assert } from 'assert'; import { Suite } from 'mocha'; -import messages from '../../../app/_locales/en/messages.json'; import FixtureBuilder from '../fixture-builder'; -import { defaultGanacheOptions, unlockWallet, withFixtures } from '../helpers'; +import { withFixtures } from '../helpers'; import { Driver } from '../webdriver/driver'; +import AccountDetailsModal from '../page-objects/pages/dialog/account-details-modal'; +import AccountListPage from '../page-objects/pages/account-list-page'; +import ExperimentalSettings from '../page-objects/pages/settings/experimental-settings'; +import HeaderNavbar from '../page-objects/pages/header-navbar'; +import HomePage from '../page-objects/pages/home/homepage'; +import SettingsPage from '../page-objects/pages/settings/settings-page'; +import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; +import { watchEoaAddress } from '../page-objects/flows/watch-account.flow'; const ACCOUNT_1 = '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1'; const EOA_ADDRESS = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'; const SHORTENED_EOA_ADDRESS = '0xd8dA6...96045'; const DEFAULT_WATCHED_ACCOUNT_NAME = 'Watched Account 1'; -/** - * Start the flow to create a watch account by clicking the account menu and selecting the option to add a watch account. - * - * @param driver - The WebDriver instance used to control the browser. - * @param unlockWalletFirst - Whether to unlock the wallet before starting the flow. - */ -async function startCreateWatchAccountFlow( - driver: Driver, - unlockWalletFirst: boolean = true, -): Promise { - if (unlockWalletFirst) { - await unlockWallet(driver); - } - - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-watch-only-account"]', - ); -} - -/** - * Watches an EOA address. - * - * @param driver - The WebDriver instance used to control the browser. - * @param unlockWalletFirst - Whether to unlock the wallet before watching the address. - * @param address - The EOA address to watch. - */ -async function watchEoaAddress( - driver: Driver, - unlockWalletFirst: boolean = true, - address: string = EOA_ADDRESS, -): Promise { - await startCreateWatchAccountFlow(driver, unlockWalletFirst); - await driver.fill('input#address-input[type="text"]', address); - await driver.clickElement({ text: 'Watch account', tag: 'button' }); - await driver.clickElement('[data-testid="submit-add-account-with-name"]'); -} - -/** - * Removes the selected account. - * - * @param driver - The WebDriver instance used to control the browser. - */ -async function removeSelectedAccount(driver: Driver): Promise { - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '.multichain-account-list-item--selected [data-testid="account-list-item-menu-button"]', - ); - await driver.clickElement('[data-testid="account-list-menu-remove"]'); - await driver.clickElement({ text: 'Remove', tag: 'button' }); -} - describe('Account-watcher snap', function (this: Suite) { describe('Adding watched accounts', function () { it('adds watch account with valid EOA address', async function () { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { // watch an EOA address - await watchEoaAddress(driver); + await loginWithBalanceValidation(driver); + await watchEoaAddress(driver, EOA_ADDRESS); // new account should be displayed in the account list - await driver.findElement({ - css: '[data-testid="account-menu-icon"]', - text: DEFAULT_WATCHED_ACCOUNT_NAME, - }); - await driver.findElement({ - css: '.mm-text--ellipsis', - text: SHORTENED_EOA_ADDRESS, - }); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel(DEFAULT_WATCHED_ACCOUNT_NAME); + await headerNavbar.check_accountAddress(SHORTENED_EOA_ADDRESS); }, ); }); @@ -100,45 +47,34 @@ describe('Account-watcher snap', function (this: Suite) { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { // watch an EOA address - await watchEoaAddress(driver); + await loginWithBalanceValidation(driver); + await watchEoaAddress(driver, EOA_ADDRESS); + const homePage = new HomePage(driver); + await homePage.headerNavbar.check_accountLabel( + DEFAULT_WATCHED_ACCOUNT_NAME, + ); // 'Send' button should be disabled - await driver.findElement( - '[data-testid="eth-overview-send"][disabled]', - ); - await driver.findElement( - '[data-testid="eth-overview-send"].icon-button--disabled', - ); + assert.equal(await homePage.check_ifSendButtonIsClickable(), false); // 'Swap' button should be disabled - await driver.findElement( - '[data-testid="token-overview-button-swap"][disabled]', - ); - await driver.findElement( - '[data-testid="token-overview-button-swap"].icon-button--disabled', - ); + assert.equal(await homePage.check_ifSwapButtonIsClickable(), false); // 'Bridge' button should be disabled - await driver.findElement( - '[data-testid="eth-overview-bridge"][disabled]', - ); - await driver.findElement( - '[data-testid="eth-overview-bridge"].icon-button--disabled', - ); + assert.equal(await homePage.check_ifBridgeButtonIsClickable(), false); // check tooltips for disabled buttons - await driver.findElement( - '.icon-button--disabled [data-tooltipped][data-original-title="Not supported with this account."]', + await homePage.check_disabledButtonTooltip( + 'Not supported with this account.', ); }, ); @@ -177,25 +113,24 @@ describe('Account-watcher snap', function (this: Suite) { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { - await startCreateWatchAccountFlow(driver); - - await driver.fill('input#address-input[type="text"]', input); - await driver.clickElement({ text: 'Watch account', tag: 'button' }); - - // error message should be displayed by the snap - await driver.findElement({ - css: '.snap-ui-renderer__text', - text: message, - }); + await loginWithBalanceValidation(driver); + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + + // error message should be displayed by snap when try to watch an EOA with invalid input + await homePage.headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addEoaAccount(input, message); }, ); }); @@ -211,35 +146,28 @@ describe('Account-watcher snap', function (this: Suite) { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { // watch an EOA address for ACCOUNT_2 - await watchEoaAddress(driver, true, ACCOUNT_2); - - // try to import private key of watched ACCOUNT_2 address - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement({ text: 'Import account', tag: 'button' }); - await driver.findClickableElement('#private-key-box'); - await driver.fill('#private-key-box', PRIVATE_KEY_TWO); - await driver.clickElement( - '[data-testid="import-account-confirm-button"]', + await loginWithBalanceValidation(driver); + await watchEoaAddress(driver, ACCOUNT_2); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel(DEFAULT_WATCHED_ACCOUNT_NAME); + + // try to import private key of watched ACCOUNT_2 address and check error message + await headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addNewImportedAccount( + PRIVATE_KEY_TWO, + 'KeyringController - The account you are trying to import is a duplicate', ); - - // error message should be displayed - await driver.findElement({ - css: '.mm-box--color-error-default', - text: 'KeyringController - The account you are trying to import is a duplicate', - }); }, ); }); @@ -248,182 +176,117 @@ describe('Account-watcher snap', function (this: Suite) { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { // watch an EOA address - await watchEoaAddress(driver); - - // click to view account details - await driver.clickElement( - '[data-testid="account-options-menu-button"]', - ); - await driver.clickElement( - '[data-testid="account-list-menu-details"]', - ); - // 'Show private key' button should not be displayed - await driver.assertElementNotPresent({ - css: 'button', - text: 'Show private key', - }); + await loginWithBalanceValidation(driver); + await watchEoaAddress(driver, EOA_ADDRESS); + + // open account details modal in header navbar + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel(DEFAULT_WATCHED_ACCOUNT_NAME); + await headerNavbar.openAccountDetailsModal(); + + // check 'Show private key' button should not be displayed + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + await accountDetailsModal.check_showPrivateKeyButtonIsNotDisplayed(); }, ); }); - it('removes a watched account', async function () { + it('removes a watched account and recreate a watched account', async function () { await withFixtures( { fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ + .withPreferencesController({ watchEthereumAccountEnabled: true, }) .withNetworkControllerOnMainnet() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { // watch an EOA address - await watchEoaAddress(driver); - - // remove the selected watched account - await removeSelectedAccount(driver); - - // account should be removed from the account list - await driver.assertElementNotPresent({ - css: '[data-testid="account-menu-icon"]', - text: DEFAULT_WATCHED_ACCOUNT_NAME, - }); - await driver.assertElementNotPresent({ - css: '.mm-text--ellipsis', - text: SHORTENED_EOA_ADDRESS, - }); - }, - ); - }); - - it('can remove and recreate a watched account', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerAndFeatureFlag({ - watchEthereumAccountEnabled: true, - }) - .withNetworkControllerOnMainnet() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ driver }: { driver: Driver }) => { - // watch an EOA address - await watchEoaAddress(driver); + await loginWithBalanceValidation(driver); + await watchEoaAddress(driver, EOA_ADDRESS); + const homePage = new HomePage(driver); + await homePage.headerNavbar.check_accountLabel( + DEFAULT_WATCHED_ACCOUNT_NAME, + ); // remove the selected watched account - await removeSelectedAccount(driver); + await homePage.headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.removeAccount(DEFAULT_WATCHED_ACCOUNT_NAME); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); // account should be removed from the account list - await driver.assertElementNotPresent({ - css: '[data-testid="account-menu-icon"]', - text: DEFAULT_WATCHED_ACCOUNT_NAME, - }); - await driver.assertElementNotPresent({ - css: '.mm-text--ellipsis', - text: SHORTENED_EOA_ADDRESS, - }); - - // watch the same EOA address again - await watchEoaAddress(driver, false); - - // same account should be displayed in the account list - await driver.findElement({ - css: '[data-testid="account-menu-icon"]', - text: DEFAULT_WATCHED_ACCOUNT_NAME, - }); - await driver.findElement({ - css: '.mm-text--ellipsis', - text: SHORTENED_EOA_ADDRESS, - }); + await homePage.headerNavbar.openAccountMenu(); + await accountListPage.check_accountIsNotDisplayedInAccountList( + DEFAULT_WATCHED_ACCOUNT_NAME, + ); + await accountListPage.closeAccountModal(); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + + // watch the same EOA address again and check the account is recreated + await watchEoaAddress(driver, EOA_ADDRESS); + await homePage.headerNavbar.check_accountLabel( + DEFAULT_WATCHED_ACCOUNT_NAME, + ); + await homePage.headerNavbar.check_accountAddress( + SHORTENED_EOA_ADDRESS, + ); }, ); }); }); describe('Experimental toggle', function () { - const navigateToExperimentalSettings = async (driver: Driver) => { - await driver.clickElement('[data-testid="account-options-menu-button"]'); - await driver.clickElement({ text: 'Settings', tag: 'div' }); - await driver.clickElement({ text: 'Experimental', tag: 'div' }); - await driver.waitForSelector({ - text: messages.watchEthereumAccountsToggle.message, - tag: 'span', - }); - }; - - const getToggleState = async (driver: Driver): Promise => { - const toggleInput = await driver.findElement( - '[data-testid="watch-account-toggle"]', - ); - return toggleInput.isSelected(); - }; - - const toggleWatchAccountOptionAndCloseSettings = async (driver: Driver) => { - await driver.clickElement('[data-testid="watch-account-toggle-div"]'); - await driver.clickElement( - '.settings-page__header__title-container__close-button', - ); - }; - - const verifyWatchAccountOptionAndCloseMenu = async ( - driver: Driver, - shouldBePresent: boolean, - ) => { - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - if (shouldBePresent) { - await driver.waitForSelector({ - text: messages.addEthereumWatchOnlyAccount.message, - tag: 'button', - }); - } else { - await driver.assertElementNotPresent({ - text: messages.addEthereumWatchOnlyAccount.message, - tag: 'button', - }); - } - await driver.clickElement('header button[aria-label="Close"]'); - }; - it("will show the 'Watch an Ethereum account (Beta)' option when setting is enabled", async function () { await withFixtures( { fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }) => { - await unlockWallet(driver); - await navigateToExperimentalSettings(driver); - - // verify toggle is off by default + await loginWithBalanceValidation(driver); + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + + // navigate to experimental settings + await homePage.headerNavbar.openSettingsPage(); + const settingsPage = new SettingsPage(driver); + await settingsPage.check_pageIsLoaded(); + await settingsPage.goToExperimentalSettings(); + const experimentalSettings = new ExperimentalSettings(driver); + await experimentalSettings.check_pageIsLoaded(); + + // verify watch account toggle is off by default and enable the toggle assert.equal( - await getToggleState(driver), + await experimentalSettings.getWatchAccountToggleState(), false, 'Toggle should be off by default', ); - - // enable the toggle - await toggleWatchAccountOptionAndCloseSettings(driver); + await experimentalSettings.toggleWatchAccount(); + await settingsPage.closeSettingsPage(); // verify the 'Watch and Ethereum account (Beta)' option is available - await verifyWatchAccountOptionAndCloseMenu(driver, true); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + await homePage.headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_addWatchAccountAvailable(true); }, ); }); @@ -432,27 +295,49 @@ describe('Account-watcher snap', function (this: Suite) { await withFixtures( { fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }) => { - await unlockWallet(driver); - await navigateToExperimentalSettings(driver); - - // enable the toggle - await toggleWatchAccountOptionAndCloseSettings(driver); + await loginWithBalanceValidation(driver); + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + + // navigate to experimental settings and enable the toggle + await homePage.headerNavbar.openSettingsPage(); + const settingsPage = new SettingsPage(driver); + await settingsPage.check_pageIsLoaded(); + await settingsPage.goToExperimentalSettings(); + const experimentalSettings = new ExperimentalSettings(driver); + await experimentalSettings.check_pageIsLoaded(); + await experimentalSettings.toggleWatchAccount(); + await settingsPage.closeSettingsPage(); // verify the 'Watch and Ethereum account (Beta)' option is available - await verifyWatchAccountOptionAndCloseMenu(driver, true); - - // navigate back to experimental settings - await navigateToExperimentalSettings(driver); - - // disable the toggle - await toggleWatchAccountOptionAndCloseSettings(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + await homePage.headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_addWatchAccountAvailable(true); + await accountListPage.closeAccountModal(); + + // navigate back to experimental settings and disable the toggle + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + await homePage.headerNavbar.openSettingsPage(); + await settingsPage.check_pageIsLoaded(); + await settingsPage.goToExperimentalSettings(); + await experimentalSettings.check_pageIsLoaded(); + await experimentalSettings.toggleWatchAccount(); + await settingsPage.closeSettingsPage(); // verify the 'Watch and Ethereum account (Beta)' option is not available - await verifyWatchAccountOptionAndCloseMenu(driver, false); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + await homePage.headerNavbar.openAccountMenu(); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_addWatchAccountAvailable(false); }, ); }); diff --git a/test/e2e/flask/solana/check-balance.spec.ts b/test/e2e/flask/solana/check-balance.spec.ts new file mode 100644 index 000000000000..266c33b6de53 --- /dev/null +++ b/test/e2e/flask/solana/check-balance.spec.ts @@ -0,0 +1,61 @@ +import { Suite } from 'mocha'; +import NonEvmHomepage from '../../page-objects/pages/home/non-evm-homepage'; +import { withSolanaAccountSnap } from './common-solana'; + +describe('Check balance', function (this: Suite) { + this.timeout(300000); + it('Just created Solana account shows 0 SOL when native token is enabled', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle(), showNativeTokenAsMainBalance: true }, + async (driver) => { + await driver.refresh(); + const homePage = new NonEvmHomepage(driver); + await homePage.check_getBalance('0 SOL'); + }, + ); + }); + it.skip('Just created Solana account shows 0 USD when native token is not enabled', async function () { + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + solanaSupportEnabled: true, + showNativeTokenAsMainBalance: false, + }, + async (driver) => { + await driver.refresh(); + const homePage = new NonEvmHomepage(driver); + await homePage.check_getBalance(`0.00\nUSD`); + }, + ); + }); + it.skip('For a non 0 balance account - SOL balance', async function () { + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + solanaSupportEnabled: true, + showNativeTokenAsMainBalance: true, + mockCalls: true, + }, + async (driver) => { + await driver.refresh(); + const homePage = new NonEvmHomepage(driver); + await homePage.check_getBalance(`50\nSOL`); + }, + ); + }); + it.skip('For a non 0 balance account - USD balance', async function () { + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + solanaSupportEnabled: true, + showNativeTokenAsMainBalance: false, + mockCalls: true, + }, + async (driver) => { + await driver.refresh(); + const homePage = new NonEvmHomepage(driver); + await homePage.check_getBalance(`11294\nUSD`); + }, + ); + }); +}); diff --git a/test/e2e/flask/solana/common-solana.ts b/test/e2e/flask/solana/common-solana.ts new file mode 100644 index 000000000000..3c3390b55a31 --- /dev/null +++ b/test/e2e/flask/solana/common-solana.ts @@ -0,0 +1,283 @@ +import { Mockttp } from 'mockttp'; +import { withFixtures } from '../../helpers'; +import { Driver } from '../../webdriver/driver'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import FixtureBuilder from '../../fixture-builder'; +import { ACCOUNT_TYPE } from '../../constants'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +const SOLANA_URL_REGEX = /.*/u; +// const SOLANA_RPC_PROVIDER = 'https://api.devnet.solana.com/'; +const SOLANA_PRICE_REGEX = + /^https:\/\/price-api\.metamask-institutional\.io\/v2\/chains\/solana:/u; +const SOLANA_BITCOIN_MIN_API = + /^https:\/\/min-api\.cryptocompare\.com\/data\/pricemulti/u; +export enum SendFlowPlaceHolders { + AMOUNT = 'Enter amount to send', + RECIPIENT = 'Enter receiving address', + LOADING = 'Preparing transaction', +} + +export const SOL_BALANCE = 50000000000; + +export const SOL_TO_USD_RATE = 225.88; + +export const USD_BALANCE = SOL_BALANCE * SOL_TO_USD_RATE; + +export const LAMPORTS_PER_SOL = 1_000_000_000; + +export async function mockMultiCoinPrice(mockServer: Mockttp) { + return await mockServer.forGet(SOLANA_BITCOIN_MIN_API).thenCallback(() => { + return { + statusCode: 200, + json: { + BTC: { + USD: 96155.06, + }, + SOL: { + USD: 180.5, + }, + }, + }; + }); +} + +export async function mockSolanaBalanceQuote(mockServer: Mockttp) { + const response = { + statusCode: 200, + json: { + result: { + context: { + apiVersion: '2.0.18', + slot: 308460925, + }, + value: SOL_BALANCE, + }, + id: 1337, + }, + }; + return await mockServer + .forPost(SOLANA_URL_REGEX) + .withJsonBodyIncluding({ + method: 'getBalance', + }) + .thenCallback(() => { + return response; + }); +} + +export async function mockGetLatestBlockhash(mockServer: Mockttp) { + const response = { + statusCode: 200, + json: { + result: { + context: { + apiVersion: '2.0.18', + slot: 308460925, + }, + value: { + blockhash: '6E9FiVcuvavWyKTfYC7N9ezJWkNgJVQsroDTHvqApncg', + lastValidBlockHeight: 341034515, + }, + }, + id: 1337, + }, + }; + return await mockServer + .forPost(SOLANA_URL_REGEX) + .withJsonBodyIncluding({ + method: 'getLatestBlockhash', + }) + .thenCallback(() => { + return response; + }); +} +export async function mockGetSignaturesForAddress(mockServer: Mockttp) { + return await mockServer + .forPost(SOLANA_URL_REGEX) + .withBodyIncluding('getSignaturesForAddress') + .thenCallback(() => { + return { + statusCode: 200, + json: { + result: [ + { + blockTime: 1734620122, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '5THAXC3pHCRwwwrMHR6PJiSqFfgSkZrBhn59C7YEbTMVbiAnjZhqpPvJYs4v5aRcqUiokunfbdTgo9HLfv6bogNR', + slot: 348093552, + }, + { + blockTime: 1734619950, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '5KHuDsTMjre6rWU5Qkf8ugG31PjWoZ8NbV21ThY8RwcHpn3dKbTafdizUkEj4sU2AfrRzVxgyGkX8MLxK5nWHJ6J', + slot: 348093088, + }, + { + blockTime: 1734619916, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '2RcW9iJCGnYuGVbDbaDi93t2f2347a6gzjoQf9idDdfFTjHsC7yMYcUvGqNzouKgA8T8tdYqjNUtDf4vR4e9iUoF', + slot: 348092996, + }, + { + blockTime: 1734619899, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '2kCcoXZxe14384c8JTvq1g63pSjmmyuDnye9y3ReBMEiaZeGWspsmooEdC4RoyzP6uTfaDyFpCupBAKXnZwXCKMg', + slot: 348092952, + }, + { + blockTime: 1734619885, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '4fzwGY4Tw5C4nYMaVAY7e3ZMwz691CbT7By4F4YFdukzBxd7yspmZEHhBtuPhFrqLj1yBn6zpc4kh1GLzgcovEbx', + slot: 348092914, + }, + { + blockTime: 1734619758, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '2vgL59tfVa2VJkf7kmsGhbdBFjHdspLa1wfL72zZqHfJuzhmKfqS4YoLofpMTnZzzZfiA6712pwURheMUh5S2RXd', + slot: 348092568, + }, + { + blockTime: 1734619697, + confirmationStatus: 'finalized', + err: null, + memo: null, + signature: + '32fqeHudeNBuDmyCrmRemFppVPpWmXwT4cbfai5D7G2Vzah1BvVguLqkNuk9Pdu4xVyBD32dhnSV8AN9k4qnffSB', + slot: 348092404, + }, + ], + }, + }; + }); +} + +export async function mockSendSolanaTransaction(mockServer: Mockttp) { + const response = { + statusCode: 200, + json: { + result: + '3nqGKH1ef8WkTgKXZ8q3xKsvjktWmHHhJpZMSdbB6hBqy5dA7aLVSAUjw5okezZjKMHiNg2MF5HAqtpmsesQtnpj', + id: 1337, + }, + }; + return await mockServer + .forPost(SOLANA_URL_REGEX) + .withJsonBodyIncluding({ + method: 'sendTransaction', + }) + .thenCallback(() => { + return response; + }); +} + +export async function mockSolanaRatesCall(mockServer: Mockttp) { + return await mockServer + .forGet(SOLANA_PRICE_REGEX) + .withQuery({ vsCurrency: 'usd' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { + id: 'wrapped-solana', + price: 210.57, + marketCap: 0, + allTimeHigh: 263.68, + allTimeLow: 8.11, + totalVolume: 3141761864, + high1d: 218.26, + low1d: 200.85, + circulatingSupply: 0, + dilutedMarketCap: 124394527657, + marketCapPercentChange1d: 0, + priceChange1d: -7.68288033909846, + pricePercentChange1h: 0.5794201955743261, + pricePercentChange1d: -3.520101943578202, + pricePercentChange7d: -8.192700158252544, + pricePercentChange14d: -12.477367449577399, + pricePercentChange30d: -14.588630064677465, + pricePercentChange200d: 28.111509321033513, + pricePercentChange1y: 181.48381055890258, + }, + }; + }); +} + +export async function withSolanaAccountSnap( + { + title, + solanaSupportEnabled, + showNativeTokenAsMainBalance, + mockCalls, + mockSendTransaction, + }: { + title?: string; + solanaSupportEnabled?: boolean; + showNativeTokenAsMainBalance?: boolean; + mockCalls?: boolean; + mockSendTransaction?: boolean; + }, + test: (driver: Driver, mockServer: Mockttp) => Promise, +) { + console.log('Starting withSolanaAccountSnap'); + let fixtures = new FixtureBuilder().withPreferencesController({ + solanaSupportEnabled: solanaSupportEnabled ?? true, + }); + if (!showNativeTokenAsMainBalance) { + fixtures = + fixtures.withPreferencesControllerShowNativeTokenAsMainBalanceDisabled(); + } + await withFixtures( + { + fixtures: fixtures.build(), + title, + dapp: true, + testSpecificMock: async (mockServer: Mockttp) => { + const mockList = []; + if (mockCalls) { + mockList.push([ + await mockSolanaBalanceQuote(mockServer), + await mockSolanaRatesCall(mockServer), + await mockGetSignaturesForAddress(mockServer), + await mockMultiCoinPrice(mockServer), + await mockGetLatestBlockhash(mockServer), + ]); + } + if (mockSendTransaction) { + mockList.push(await mockSendSolanaTransaction(mockServer)); + } + return mockList; + }, + }, + async ({ driver, mockServer }: { driver: Driver; mockServer: Mockttp }) => { + await loginWithBalanceValidation(driver); + const headerComponen = new HeaderNavbar(driver); + await headerComponen.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Solana, + accountName: 'Solana 1', + }); + await test(driver, mockServer); + }, + ); +} diff --git a/test/e2e/flask/solana/create-solana-account.spec.ts b/test/e2e/flask/solana/create-solana-account.spec.ts new file mode 100644 index 000000000000..0cac9fab7375 --- /dev/null +++ b/test/e2e/flask/solana/create-solana-account.spec.ts @@ -0,0 +1,65 @@ +import { Suite } from 'mocha'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import { ACCOUNT_TYPE } from '../../constants'; +import { withSolanaAccountSnap } from './common-solana'; + +// Scenarios skipped due to https://consensyssoftware.atlassian.net/browse/SOL-87 +describe('Create Solana Account', function (this: Suite) { + it.skip('Creates 2 Solana accounts', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle() }, + async (driver) => { + // check that we have one Solana account + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.check_accountLabel('Solana 1'); + await headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_accountDisplayedInAccountList('Account 1'); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Solana, + accountName: 'Solana 2', + }); + await headerNavbar.check_accountLabel('Solana 2'); + await headerNavbar.openAccountMenu(); + await accountListPage.check_numberOfAvailableAccounts(3); + }, + ); + }); + it('Creates a Solana account from the menu', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle() }, + async (driver) => { + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.check_accountLabel('Solana 1'); + await headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_accountDisplayedInAccountList('Account 1'); + await accountListPage.check_accountDisplayedInAccountList('Solana 1'); + }, + ); + }); +}); +it.skip('Removes Solana account after creating it', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle() }, + async (driver) => { + // check that we have one Solana account + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel('Solana 1'); + // check user can cancel the removal of the Solana account + await headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_accountDisplayedInAccountList('Account 1'); + await accountListPage.removeAccount('Solana 1', true); + await headerNavbar.check_accountLabel('Account 1'); + await headerNavbar.openAccountMenu(); + await accountListPage.check_accountDisplayedInAccountList('Account 1'); + await accountListPage.check_accountIsNotDisplayedInAccountList( + 'Solana 1', + ); + }, + ); +}); diff --git a/test/e2e/flask/solana/send-flow.spec.ts b/test/e2e/flask/solana/send-flow.spec.ts new file mode 100644 index 000000000000..640667fcab38 --- /dev/null +++ b/test/e2e/flask/solana/send-flow.spec.ts @@ -0,0 +1,447 @@ +import { strict as assert } from 'assert'; +import { Suite } from 'mocha'; + +import SendSolanaPage from '../../page-objects/pages/send/solana-send-page'; +import ConfirmSolanaTxPage from '../../page-objects/pages/send/solana-confirm-tx-page'; +import SolanaTxresultPage from '../../page-objects/pages/send/solana-tx-result-page'; +import NonEvmHomepage from '../../page-objects/pages/home/non-evm-homepage'; +import { withSolanaAccountSnap } from './common-solana'; + +const commonSolanaAddress = 'GYP1hGem9HBkYKEWNUQUxEwfmu4hhjuujRgGnj5LrHna'; +describe.skip('Send flow', function (this: Suite) { + it('with some field validation', async function () { + this.timeout(120000); + await withSolanaAccountSnap( + { title: this.test?.fullTitle(), showNativeTokenAsMainBalance: true }, + async (driver) => { + await driver.refresh(); // workaround to not get an error due to https://consensyssoftware.atlassian.net/browse/SOL-87 + const homePage = new NonEvmHomepage(driver); + await homePage.check_pageIsLoaded(); + await homePage.clickOnSendButton(); + const sendSolanaPage = new SendSolanaPage(driver); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled and it shouldn`t', + ); + await sendSolanaPage.setToAddress('2433asd'); + assert.equal( + await sendSolanaPage.check_validationErrorAppears( + 'Invalid Solana address', + ), + true, + 'Invalid Solana address should appear and it does not', + ); + await sendSolanaPage.setToAddress(''); + assert.equal( + await sendSolanaPage.check_validationErrorAppears( + 'To address is required', + ), + true, + 'To address is required should appear and it does not', + ); + await sendSolanaPage.setToAddress(commonSolanaAddress); + await sendSolanaPage.setAmount('0.1'); + assert.equal( + await sendSolanaPage.check_validationErrorAppears( + 'Insufficient balance', + ), + true, + 'Insufficient balance text is not displayed', + ); + await sendSolanaPage.setAmount('0'); + assert.equal( + await sendSolanaPage.check_validationErrorAppears( + 'Amount must be greater than 0', + ), + true, + 'Amount must be greater than 0 text is not displayed', + ); + }, + ); + }); +}); +describe.skip('Send full flow of USD', function (this: Suite) { + it('with a positive balance account', async function () { + // skipped due tohttps://consensyssoftware.atlassian.net/browse/SOL-100 + this.timeout(120000); + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + showNativeTokenAsMainBalance: true, + mockCalls: true, + mockSendTransaction: true, + }, + async (driver) => { + await driver.refresh(); // workaround to not get an error due to https://consensyssoftware.atlassian.net/browse/SOL-87 + const homePage = new NonEvmHomepage(driver); + await homePage.check_pageIsLoaded(); + assert.equal( + await homePage.check_ifSendButtonIsClickable(), + true, + 'Send button is not enabled and it should', + ); + assert.equal( + await homePage.check_ifSwapButtonIsClickable(), + false, + 'Swap button is enabled and it shouldn`t', + ); + assert.equal( + await homePage.check_ifBridgeButtonIsClickable(), + false, + 'Bridge button is enabled and it should`t', + ); + await homePage.clickOnSendButton(); + const sendSolanaPage = new SendSolanaPage(driver); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled when no address nor amount', + ); + await sendSolanaPage.setToAddress(commonSolanaAddress); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled when no address', + ); + await sendSolanaPage.clickOnSwapCurrencyButton(); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled when no address nor amount', + ); + await sendSolanaPage.setAmount('0.1'); + const confirmSolanaPage = new ConfirmSolanaTxPage(driver); + await sendSolanaPage.clickOnContinue(); + assert.equal( + await confirmSolanaPage.checkAmountDisplayed('0.1', 'USD'), + true, + 'Check amount displayed is wrong', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('From'), + true, + 'From is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Amount'), + true, + 'Amount is not displayed and it should', + ); + + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Recipient'), + true, + 'Recipient is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Network'), + true, + 'Network is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed( + 'Transaction speed', + ), + true, + 'Transaction speed is not displayed and it should', + ); + + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Network fee'), + true, + 'Network fee is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Total'), + true, + 'Total is not displayed and it should', + ); + await confirmSolanaPage.clickOnSend(); + const sentTxPage = new SolanaTxresultPage(driver); + assert.equal( + await sentTxPage.check_TransactionStatusText('0.1', true), + true, + 'Transaction amount is not correct', + ); + assert.equal( + await sentTxPage.check_TransactionStatus(true), + true, + 'Transaction was not sent as expected', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('From'), + true, + 'From field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Amount'), + true, + 'Amount field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Recipient'), + true, + 'Recipient field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Network'), + true, + 'Network field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Transaction speed'), + true, + 'Transaction field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Network fee'), + true, + 'Network fee field not displayed', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Total'), + true, + 'Total field not displayed and it should', + ); + assert.equal( + await sentTxPage.check_isViewTransactionLinkDisplayed(), + true, + 'View transaction link is not displayed and it should', + ); + }, + ); + }); +}); +describe.skip('Send full flow of SOL', function (this: Suite) { + it('with a positive balance account', async function () { + this.timeout(120000); + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + showNativeTokenAsMainBalance: true, + mockCalls: true, + mockSendTransaction: true, + }, + async (driver) => { + await driver.refresh(); // workaround to not get an error due to https://consensyssoftware.atlassian.net/browse/SOL-87 + const homePage = new NonEvmHomepage(driver); + await homePage.check_pageIsLoaded(); + assert.equal( + await homePage.check_ifSendButtonIsClickable(), + true, + 'Send button is not enabled and it should', + ); + assert.equal( + await homePage.check_ifSwapButtonIsClickable(), + false, + 'Swap button is enabled and it shouldn`t', + ); + assert.equal( + await homePage.check_ifBridgeButtonIsClickable(), + false, + 'Bridge button is enabled and it should`t', + ); + await homePage.clickOnSendButton(); + const sendSolanaPage = new SendSolanaPage(driver); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled when no address nor amount', + ); + await sendSolanaPage.setToAddress(commonSolanaAddress); + assert.equal( + await sendSolanaPage.isContinueButtonEnabled(), + false, + 'Continue button is enabled when no address', + ); + await sendSolanaPage.setAmount('0.1'); + const confirmSolanaPage = new ConfirmSolanaTxPage(driver); + await sendSolanaPage.clickOnContinue(); + assert.equal( + await confirmSolanaPage.checkAmountDisplayed('0.1'), + true, + 'Check amount displayed is wrong', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('From'), + true, + 'From is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Amount'), + true, + 'Amount is not displayed and it should', + ); + + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Recipient'), + true, + 'Recipient is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Network'), + true, + 'Network is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed( + 'Transaction speed', + ), + true, + 'Transaction speed is not displayed and it should', + ); + + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Network fee'), + true, + 'Network fee is not displayed and it should', + ); + assert.equal( + await confirmSolanaPage.isTransactionDetailDisplayed('Total'), + true, + 'Total is not displayed and it should', + ); + await confirmSolanaPage.clickOnSend(); + const sentTxPage = new SolanaTxresultPage(driver); + assert.equal( + await sentTxPage.check_TransactionStatusText('0.1', true), + true, + 'Transaction amount is not correct', + ); + assert.equal( + await sentTxPage.check_TransactionStatus(true), + true, + 'Transaction was not sent as expected', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('From'), + true, + 'From field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Amount'), + true, + 'Amount field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Recipient'), + true, + 'Recipient field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Network'), + true, + 'Network field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Transaction speed'), + true, + 'Transaction field not displayed and it should', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Network fee'), + true, + 'Network fee field not displayed', + ); + assert.equal( + await sentTxPage.isTransactionDetailDisplayed('Total'), + true, + 'Total field not displayed and it should', + ); + assert.equal( + await sentTxPage.check_isViewTransactionLinkDisplayed(), + true, + 'View transaction link is not displayed and it should', + ); + }, + ); + }); +}); +describe.skip('Send flow flow', function (this: Suite) { + it('and Transaction fails', async function () { + this.timeout(120000); // there is a bug open for this big timeout https://consensyssoftware.atlassian.net/browse/SOL-90 + await withSolanaAccountSnap( + { + title: this.test?.fullTitle(), + showNativeTokenAsMainBalance: true, + mockCalls: true, + mockSendTransaction: false, + }, + async (driver) => { + await driver.refresh(); // workaround to not get an error due to https://consensyssoftware.atlassian.net/browse/SOL-87 + const homePage = new NonEvmHomepage(driver); + assert.equal( + await homePage.check_ifSendButtonIsClickable(), + true, + 'Send button is not enabled and it should', + ); + assert.equal( + await homePage.check_ifSwapButtonIsClickable(), + false, + 'Swap button is enabled and it should`t', + ); + assert.equal( + await homePage.check_ifBridgeButtonIsClickable(), + false, + 'Bridge button is enabled and it should`t', + ); + await homePage.clickOnSendButton(); + const sendSolanaPage = new SendSolanaPage(driver); + await sendSolanaPage.setToAddress(commonSolanaAddress); + await sendSolanaPage.setAmount('0.1'); + // assert.equal(await sendSolanaPage.isContinueButtonEnabled(), true, "Continue button is not enabled when address and amount are set"); + await sendSolanaPage.clickOnContinue(); + const confirmSolanaPage = new ConfirmSolanaTxPage(driver); + + await confirmSolanaPage.clickOnSend(); + const failedTxPage = new SolanaTxresultPage(driver); + assert.equal( + await failedTxPage.check_TransactionStatusText('0.1', false), + true, + 'Transaction amount is not correct', + ); + assert.equal( + await failedTxPage.check_TransactionStatus(false), + true, + 'Transaction did not fail as expected', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('From'), + true, + 'From field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Amount'), + true, + 'Amount field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Recipient'), + true, + 'Recipient field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Network'), + true, + 'Network field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Transaction speed'), + true, + 'Transaction field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Network fee'), + true, + 'Network fee field not displayed and it should', + ); + assert.equal( + await failedTxPage.isTransactionDetailDisplayed('Total'), + true, + 'Total field not displayed and it should', + ); + }, + ); + }); +}); diff --git a/test/e2e/flask/solana/solana-eth-networks.spec.ts b/test/e2e/flask/solana/solana-eth-networks.spec.ts new file mode 100644 index 000000000000..56a68135fad8 --- /dev/null +++ b/test/e2e/flask/solana/solana-eth-networks.spec.ts @@ -0,0 +1,24 @@ +import { Suite } from 'mocha'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import { withSolanaAccountSnap } from './common-solana'; + +describe('Solana/Evm accounts', function (this: Suite) { + it('Network picker is disabled when Solana account is selected', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle() }, + async (driver) => { + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.check_accountLabel('Solana 1'); + await headerNavbar.check_currentSelectedNetwork('Solana'); + await headerNavbar.check_ifNetworkPickerClickable(false); + await headerNavbar.openAccountMenu(); + const accountMenu = new AccountListPage(driver); + await accountMenu.switchToAccount('Account 1'); + await headerNavbar.check_currentSelectedNetwork('Localhost 8545'); + await headerNavbar.check_ifNetworkPickerClickable(true); + }, + ); + }); +}); diff --git a/test/e2e/flask/solana/switching-network-accounts.spec.ts b/test/e2e/flask/solana/switching-network-accounts.spec.ts new file mode 100644 index 000000000000..f630495ca705 --- /dev/null +++ b/test/e2e/flask/solana/switching-network-accounts.spec.ts @@ -0,0 +1,24 @@ +import { Suite } from 'mocha'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import { withSolanaAccountSnap } from './common-solana'; + +describe('Switching between account from different networks', function (this: Suite) { + it('Switch from Solana account to another Network account', async function () { + await withSolanaAccountSnap( + { title: this.test?.fullTitle() }, + async (driver) => { + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.check_accountLabel('Solana 1'); + await headerNavbar.check_ifNetworkPickerClickable(false); + await headerNavbar.check_currentSelectedNetwork('Solana'); + await headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.selectAccount('Account 1'); + await headerNavbar.check_ifNetworkPickerClickable(true); + await headerNavbar.check_currentSelectedNetwork('Localhost 8545'); + }, + ); + }); +}); diff --git a/test/e2e/flask/user-operations.spec.ts b/test/e2e/flask/user-operations.spec.ts index 7512e0b563c9..4e8b51043583 100644 --- a/test/e2e/flask/user-operations.spec.ts +++ b/test/e2e/flask/user-operations.spec.ts @@ -24,6 +24,7 @@ import { Driver } from '../webdriver/driver'; import { Bundler } from '../bundler'; import { SWAP_TEST_ETH_USDC_TRADES_MOCK } from '../../data/mock-data'; import { Mockttp } from '../mock-e2e'; +import TestDapp from '../page-objects/pages/test-dapp'; enum TransactionDetailRowIndex { Nonce = 0, @@ -204,9 +205,7 @@ async function withAccountSnap( ) { await withFixtures( { - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), + fixtures: new FixtureBuilder().build(), title, useBundler: true, usePaymaster: Boolean(paymaster), @@ -239,7 +238,10 @@ async function withAccountSnap( ERC_4337_ACCOUNT_SALT, ); - await driver.closeWindow(); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.connectAccount({ publicAddress: ERC_4337_ACCOUNT }); + await driver.switchToWindowWithTitle( WINDOW_TITLES.ExtensionInFullScreenView, ); diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 3b69d55fc122..080a473b6608 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -633,9 +633,9 @@ async function unlockWallet( await driver.navigate(); } + await driver.waitForSelector('#password', { state: 'enabled' }); await driver.fill('#password', password); await driver.press('#password', driver.Key.ENTER); - if (waitLoginSuccess) { await driver.assertElementNotPresent('[data-testid="unlock-page"]'); } @@ -722,9 +722,12 @@ async function clickSignOnSignatureConfirmation({ if (snapSigInsights) { // there is no condition we can wait for to know the snap is ready, // so we have to add a small delay as the last alternative to avoid flakiness. - await driver.delay(regularDelayMs); + await driver.delay(largeDelayMs); } - + await driver.waitForSelector( + { text: 'Sign', tag: 'button' }, + { state: 'enabled' }, + ); await driver.clickElement({ text: 'Sign', tag: 'button' }); } @@ -745,7 +748,7 @@ async function clickSignOnRedesignedSignatureConfirmation({ if (snapSigInsights) { // there is no condition we can wait for to know the snap is ready, // so we have to add a small delay as the last alternative to avoid flakiness. - await driver.delay(regularDelayMs); + await driver.delay(largeDelayMs); } await driver.clickElement({ text: 'Confirm', tag: 'button' }); @@ -925,46 +928,6 @@ async function tempToggleSettingRedesignedConfirmations(driver) { ); } -/** - * Rather than using the FixtureBuilder#withPreferencesController to set the setting - * we need to manually set the setting because the migration #132 overrides this. - * We should be able to remove this when we delete the redesignedTransactionsEnabled setting. - * - * @param driver - */ -async function tempToggleSettingRedesignedTransactionConfirmations(driver) { - // Ensure we are on the extension window - await driver.switchToWindowWithTitle(WINDOW_TITLES.ExtensionInFullScreenView); - - // Open settings menu button - await driver.clickElement('[data-testid="account-options-menu-button"]'); - - // fix race condition with mmi build - if (process.env.MMI) { - await driver.waitForSelector('[data-testid="global-menu-mmi-portfolio"]'); - } - - // Click settings from dropdown menu - await driver.clickElement('[data-testid="global-menu-settings"]'); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Click redesigned transactions toggle - await driver.clickElement( - '[data-testid="toggle-redesigned-transactions-container"]', - ); - - // Close settings page - await driver.clickElement( - '.settings-page__header__title-container__close-button', - ); -} - /** * Opens the account options menu safely, handling potential race conditions * with the MMI build. @@ -1034,7 +997,6 @@ module.exports = { editGasFeeForm, clickNestedButton, tempToggleSettingRedesignedConfirmations, - tempToggleSettingRedesignedTransactionConfirmations, openMenuSafe, sentryRegEx, createWebSocketConnection, diff --git a/test/e2e/json-rpc/eth_accounts.spec.ts b/test/e2e/json-rpc/eth_accounts.spec.ts index 149021d40a57..c4928dc04c3b 100644 --- a/test/e2e/json-rpc/eth_accounts.spec.ts +++ b/test/e2e/json-rpc/eth_accounts.spec.ts @@ -14,7 +14,7 @@ describe('eth_accounts', function () { .withKeyringControllerAdditionalAccountVault() .withPreferencesControllerAdditionalAccountIdentities() .withAccountsControllerAdditionalAccountIdentities() - .withPermissionControllerConnectedToTestDapp() + .withPermissionControllerConnectedToTestDappWithTwoAccounts() .build(), ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), diff --git a/test/e2e/json-rpc/eth_sendTransaction.spec.js b/test/e2e/json-rpc/eth_sendTransaction.spec.js index 2167fe6586c5..6d135683c3ad 100644 --- a/test/e2e/json-rpc/eth_sendTransaction.spec.js +++ b/test/e2e/json-rpc/eth_sendTransaction.spec.js @@ -4,7 +4,6 @@ const { unlockWallet, WINDOW_TITLES, generateGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); @@ -12,165 +11,104 @@ describe('eth_sendTransaction', function () { const expectedHash = '0x855951a65dcf5949dc54beb032adfb604c52a0a548a0f616799d6873a9521470'; - describe('Old confirmation screens', function () { - it('rejects a new transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + it('confirms a new transaction', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // eth_sendTransaction + await driver.openNewPage(`http://127.0.0.1:8080`); + const request = JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_sendTransaction', + params: [ + { + to: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + from: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + value: '0x0', + maxPriorityFeePerGas: '0x3b9aca00', + maxFeePerGas: '0x2540be400', + }, + ], + id: 0, + }); + await driver.executeScript( + `window.transactionHash = window.ethereum.request(${request})`, + ); - // eth_sendTransaction - await driver.openNewPage(`http://127.0.0.1:8080`); - const request = JSON.stringify({ - jsonrpc: '2.0', - method: 'eth_sendTransaction', - params: [ - { - to: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - from: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - value: '0x0', - maxPriorityFeePerGas: '0x3b9aca00', - maxFeePerGas: '0x2540be400', - }, - ], - id: 0, - }); - await driver.executeScript( - `window.transactionHash = window.ethereum.request(${request})`, - ); - - // reject transaction in mm popup - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Reject', tag: 'button' }); - await driver.switchToWindowWithTitle('E2E Test Dapp'); - const result = await driver - .executeScript(`return window.transactionHash;`) - .then((data) => { - return data; - }) - .catch((err) => { - return err; - }); - assert.ok( - result.message.includes( - 'MetaMask Tx Signature: User denied transaction signature.', - ), - ); - }, - ); - }); + // confirm transaction in mm popup + await driver.waitUntilXWindowHandles(3); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.switchToWindowWithTitle('E2E Test Dapp'); + const actualHash = await driver.executeScript( + `return window.transactionHash;`, + ); + assert.equal(actualHash, expectedHash); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('confirms a new transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // eth_sendTransaction - await driver.openNewPage(`http://127.0.0.1:8080`); - const request = JSON.stringify({ - jsonrpc: '2.0', - method: 'eth_sendTransaction', - params: [ - { - to: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - from: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - value: '0x0', - maxPriorityFeePerGas: '0x3b9aca00', - maxFeePerGas: '0x2540be400', - }, - ], - id: 0, - }); - await driver.executeScript( - `window.transactionHash = window.ethereum.request(${request})`, - ); - - // confirm transaction in mm popup - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.switchToWindowWithTitle('E2E Test Dapp'); - const actualHash = await driver.executeScript( - `return window.transactionHash;`, - ); - assert.equal(actualHash, expectedHash); - }, - ); - }); + it('rejects a new transaction', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - it('rejects a new transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + // eth_sendTransaction + await driver.openNewPage(`http://127.0.0.1:8080`); + const request = JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_sendTransaction', + params: [ + { + to: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + from: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + value: '0x0', + maxPriorityFeePerGas: '0x3b9aca00', + maxFeePerGas: '0x2540be400', + }, + ], + id: 0, + }); + await driver.executeScript( + `window.transactionHash = window.ethereum.request(${request})`, + ); - // eth_sendTransaction - await driver.openNewPage(`http://127.0.0.1:8080`); - const request = JSON.stringify({ - jsonrpc: '2.0', - method: 'eth_sendTransaction', - params: [ - { - to: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - from: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - value: '0x0', - maxPriorityFeePerGas: '0x3b9aca00', - maxFeePerGas: '0x2540be400', - }, - ], - id: 0, + // reject transaction in mm popup + await driver.waitUntilXWindowHandles(3); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + await driver.switchToWindowWithTitle('E2E Test Dapp'); + const result = await driver + .executeScript(`return window.transactionHash;`) + .then((data) => { + return data; + }) + .catch((err) => { + return err; }); - await driver.executeScript( - `window.transactionHash = window.ethereum.request(${request})`, - ); - - // reject transaction in mm popup - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.switchToWindowWithTitle('E2E Test Dapp'); - const result = await driver - .executeScript(`return window.transactionHash;`) - .then((data) => { - return data; - }) - .catch((err) => { - return err; - }); - assert.ok( - result.message.includes( - 'MetaMask Tx Signature: User denied transaction signature.', - ), - ); - }, - ); - }); + assert.ok( + result.message.includes( + 'MetaMask Tx Signature: User denied transaction signature.', + ), + ); + }, + ); }); }); diff --git a/test/e2e/json-rpc/switchEthereumChain.spec.js b/test/e2e/json-rpc/switchEthereumChain.spec.js index e55dfc622865..77c1589411ac 100644 --- a/test/e2e/json-rpc/switchEthereumChain.spec.js +++ b/test/e2e/json-rpc/switchEthereumChain.spec.js @@ -8,670 +8,412 @@ const { unlockWallet, switchToNotificationWindow, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); const { isManifestV3 } = require('../../../shared/modules/mv3.utils'); describe('Switch Ethereum Chain for two dapps', function () { - describe('Old confirmation screens', function () { - it('queues send tx after switchEthereum request with a warning, if switchEthereum request is cancelled should show pending tx', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [{ port: 8546, chainId: 1338 }], - }, - title: this.test.fullTitle(), + it('switches the chainId of two dapps when switchEthereumChain of one dapp is confirmed', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [{ port: 8546, chainId: 1338 }], }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open settings menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Toggle off request queue setting (on by default now) - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // open two dapps - const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); - const dappOne = await openDapp(driver, undefined, DAPP_URL); - - // Connect Dapp One - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Switch and connect Dapp Two - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - const editButtons = await driver.findElements('[data-testid="edit"]'); - - // Click the edit button for networks - await editButtons[1].click(); - - // Disconnect Mainnet - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); - - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp Two - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Switch to notification of switchEthereumChain - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - - // Switch back to dapp one - await driver.switchToWindow(dappOne); - assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); - - // Initiate send tx on dapp one - await driver.clickElement('#sendButton'); - await driver.delay(2000); - - // Switch to notification that should still be switchEthereumChain request but with an warning. - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // THIS IS BROKEN - // await driver.findElement({ - // span: 'span', - // text: 'Switching networks will cancel all pending confirmations', - // }); - - // Cancel switchEthereumChain with queued pending tx - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - - // Delay for second notification of the pending tx - await driver.delay(1000); - - // Switch to new pending tx notification - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findElement({ - text: 'Sending ETH', - tag: 'span', - }); - - // Confirm pending tx - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - }, - ); - }); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + // open two dapps + const dappOne = await openDapp(driver, undefined, DAPP_URL); + const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); + + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x53a' }], + }); + + // Initiate switchEthereumChain on Dapp Two + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + + // Confirm switchEthereumChain + await switchToNotificationWindow(driver, 4); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // Switch to Dapp One + await driver.switchToWindow(dappOne); + assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); + + // Wait for chain id element to change, there's a page reload. + await driver.waitForSelector({ + css: '#chainId', + text: '0x53a', + }); + + // Dapp One ChainId assertion + await driver.findElement({ css: '#chainId', text: '0x53a' }); + + // Switch to Dapp Two + await driver.switchToWindow(dappTwo); + assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); + + // Dapp Two ChainId Assertion + await driver.findElement({ css: '#chainId', text: '0x53a' }); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('switches the chainId of two dapps when switchEthereumChain of one dapp is confirmed', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .build(), - dappOptions: { numberOfDapps: 2 }, - - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [{ port: 8546, chainId: 1338 }], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open settings menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Toggle off request queue setting (on by default now) - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // open two dapps - const dappOne = await openDapp(driver, undefined, DAPP_URL); - const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Initiate switchEthereumChain on Dapp Two - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Confirm switchEthereumChain - await switchToNotificationWindow(driver, 4); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Switch to Dapp One - await driver.switchToWindow(dappOne); - assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); - - // Wait for chain id element to change, there's a page reload. - await driver.waitForSelector({ - css: '#chainId', - text: '0x53a', - }); - - // Dapp One ChainId assertion - await driver.findElement({ css: '#chainId', text: '0x53a' }); - - // Switch to Dapp Two - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - // Dapp Two ChainId Assertion - await driver.findElement({ css: '#chainId', text: '0x53a' }); - }, - ); - }); - - it('queues switchEthereumChain request from second dapp after send tx request', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerSmartTransactionsOptedOut() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [{ port: 8546, chainId: 1338 }], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open settings menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Toggle off request queue setting (on by default now) - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // open two dapps - await openDapp(driver, undefined, DAPP_URL); - await openDapp(driver, undefined, DAPP_ONE_URL); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Switch to Dapp One and connect it - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findClickableElement({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const editButtons = await driver.findElements('[data-testid="edit"]'); - - await editButtons[1].click(); - - // Disconnect Localhost 8545 - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); - - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Switch to Dapp Two - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - // Initiate send transaction on Dapp two - await driver.clickElement('#sendButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - - // Switch to Dapp One - await driver.switchToWindowWithUrl(DAPP_URL); - - // Switch Ethereum chain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp One - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - await switchToNotificationWindow(driver, 4); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - // Delay here after notification for second notification popup for switchEthereumChain - await driver.delay(1000); - - // Switch and confirm to queued notification for switchEthereumChain - await switchToNotificationWindow(driver, 4); - - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ css: '#chainId', text: '0x539' }); - }, - ); - }); - - it('queues send tx after switchEthereum request with a warning, confirming removes pending tx', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [{ port: 8546, chainId: 1338 }], - }, - title: this.test.fullTitle(), + it('queues switchEthereumChain request from second dapp after send tx request', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withPreferencesControllerSmartTransactionsOptedOut() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [{ port: 8546, chainId: 1338 }], }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open settings menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Toggle off request queue setting (on by default now) - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // open two dapps - const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); - const dappOne = await openDapp(driver, undefined, DAPP_URL); - - // Connect Dapp One - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Switch and connect Dapp Two - - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const editButtons = await driver.findElements('[data-testid="edit"]'); - - // Click the edit button for networks - await editButtons[1].click(); - - // Disconnect Mainnet - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); - - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp Two - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - // Switch back to dapp one - await driver.switchToWindow(dappOne); - assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); - - // Initiate send tx on dapp one - await driver.clickElement('#sendButton'); - await driver.delay(2000); - - // Switch to notification that should still be switchEthereumChain request but with a warning. - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // THIS IS BROKEN - // await driver.findElement({ - // span: 'span', - // text: 'Switching networks will cancel all pending confirmations', - // }); - - // Confirm switchEthereumChain with queued pending tx - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Window handles should only be expanded mm, dapp one, dapp 2, and the offscreen document - // if this is an MV3 build(3 or 4 total) - await driver.wait(async () => { - const windowHandles = await driver.getAllWindowHandles(); - const numberOfWindowHandlesToExpect = isManifestV3 ? 4 : 3; - return windowHandles.length === numberOfWindowHandlesToExpect; - }); - }, - ); - }); - - it('queues send tx after switchEthereum request with a warning, if switchEthereum request is cancelled should show pending tx', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [{ port: 8546, chainId: 1338 }], - }, - title: this.test.fullTitle(), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // open two dapps + await openDapp(driver, undefined, DAPP_URL); + await openDapp(driver, undefined, DAPP_ONE_URL); + + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // Switch to Dapp One and connect it + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findClickableElement({ + text: 'Connect', + tag: 'button', + }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const editButtons = await driver.findElements('[data-testid="edit"]'); + + await editButtons[1].click(); + + // Disconnect Localhost 8545 + await driver.clickElement({ + text: 'Localhost 8545', + tag: 'p', + }); + + await driver.clickElement('[data-testid="connect-more-chains-button"]'); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // Switch to Dapp Two + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + // Initiate send transaction on Dapp two + await driver.clickElement('#sendButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + + // Switch to Dapp One + await driver.switchToWindowWithUrl(DAPP_URL); + + // Switch Ethereum chain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); + + // Initiate switchEthereumChain on Dapp One + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + await switchToNotificationWindow(driver, 4); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + }); + // Delay here after notification for second notification popup for switchEthereumChain + await driver.delay(1000); + + // Switch and confirm to queued notification for switchEthereumChain + await switchToNotificationWindow(driver, 4); + + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Confirm', + tag: 'button', + }); + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findElement({ css: '#chainId', text: '0x539' }); + }, + ); + }); + + it('queues send tx after switchEthereum request with a warning, confirming removes pending tx', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [{ port: 8546, chainId: 1338 }], }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open settings menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const experimentalTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(experimentalTabRawLocator); - - // Toggle off request queue setting (on by default now) - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // open two dapps - const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); - const dappOne = await openDapp(driver, undefined, DAPP_URL); - - // Connect Dapp One - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Switch and connect Dapp Two - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - const editButtons = await driver.findElements('[data-testid="edit"]'); - - // Click the edit button for networks - await editButtons[1].click(); - - // Disconnect Mainnet - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); - - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - await driver.switchToWindow(dappTwo); - assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp Two - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Switch to notification of switchEthereumChain - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - - // Switch back to dapp one - await driver.switchToWindow(dappOne); - assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); - - // Initiate send tx on dapp one - await driver.clickElement('#sendButton'); - await driver.delay(2000); - - // Switch to notification that should still be switchEthereumChain request but with an warning. - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Cancel switchEthereumChain with queued pending tx - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - - // Delay for second notification of the pending tx - await driver.delay(1000); - - // Switch to new pending tx notification - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findElement({ - text: 'Transfer request', - tag: 'h3', - }); - - await driver.findElement({ - text: '0 ETH', - tag: 'h2', - }); - - // Confirm pending tx - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // open two dapps + const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); + const dappOne = await openDapp(driver, undefined, DAPP_URL); + + // Connect Dapp One + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // Switch and connect Dapp Two + + await driver.switchToWindow(dappTwo); + assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); + + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const editButtons = await driver.findElements('[data-testid="edit"]'); + + // Click the edit button for networks + await editButtons[1].click(); + + // Disconnect Mainnet + await driver.clickElement({ + text: 'Localhost 8545', + tag: 'p', + }); + + await driver.clickElement('[data-testid="connect-more-chains-button"]'); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + await driver.switchToWindow(dappTwo); + assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); + + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); + + // Initiate switchEthereumChain on Dapp Two + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + // Switch back to dapp one + await driver.switchToWindow(dappOne); + assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); + + // Initiate send tx on dapp one + await driver.clickElement('#sendButton'); + await driver.delay(2000); + + // Switch to notification that should still be switchEthereumChain request but with a warning. + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // THIS IS BROKEN + // await driver.findElement({ + // span: 'span', + // text: 'Switching networks will cancel all pending confirmations', + // }); + + // Confirm switchEthereumChain with queued pending tx + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // Window handles should only be expanded mm, dapp one, dapp 2, and the offscreen document + // if this is an MV3 build(3 or 4 total) + await driver.wait(async () => { + const windowHandles = await driver.getAllWindowHandles(); + const numberOfWindowHandlesToExpect = isManifestV3 ? 4 : 3; + return windowHandles.length === numberOfWindowHandlesToExpect; + }); + }, + ); + }); + + it('queues send tx after switchEthereum request with a warning, if switchEthereum request is cancelled should show pending tx', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [{ port: 8546, chainId: 1338 }], }, - ); - }); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // open two dapps + const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL); + const dappOne = await openDapp(driver, undefined, DAPP_URL); + + // Connect Dapp One + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // Switch and connect Dapp Two + await driver.switchToWindow(dappTwo); + assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); + + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + const editButtons = await driver.findElements('[data-testid="edit"]'); + + // Click the edit button for networks + await editButtons[1].click(); + + // Disconnect Mainnet + await driver.clickElement({ + text: 'Localhost 8545', + tag: 'p', + }); + + await driver.clickElement('[data-testid="connect-more-chains-button"]'); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + await driver.switchToWindow(dappTwo); + assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`); + + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); + + // Initiate switchEthereumChain on Dapp Two + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + + // Switch to notification of switchEthereumChain + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + + // Switch back to dapp one + await driver.switchToWindow(dappOne); + assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`); + + // Initiate send tx on dapp one + await driver.clickElement('#sendButton'); + await driver.delay(2000); + + // Switch to notification that should still be switchEthereumChain request but with an warning. + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // Cancel switchEthereumChain with queued pending tx + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + + // Delay for second notification of the pending tx + await driver.delay(1000); + + // Switch to new pending tx notification + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.findElement({ + text: 'Transfer request', + tag: 'h3', + }); + + await driver.findElement({ + text: '0 ETH', + tag: 'h2', + }); + + // Confirm pending tx + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + }); + }, + ); }); }); diff --git a/test/e2e/json-rpc/wallet_requestPermissions.spec.js b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts similarity index 51% rename from test/e2e/json-rpc/wallet_requestPermissions.spec.js rename to test/e2e/json-rpc/wallet_requestPermissions.spec.ts index 5484fdf73d80..d2a033dcf3c5 100644 --- a/test/e2e/json-rpc/wallet_requestPermissions.spec.js +++ b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts @@ -1,58 +1,42 @@ -const { strict: assert } = require('assert'); -const { - defaultGanacheOptions, - withFixtures, - switchToNotificationWindow, - switchToOrOpenDapp, - unlockWallet, -} = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); +import { strict as assert } from 'assert'; +import { withFixtures } from '../helpers'; +import FixtureBuilder from '../fixture-builder'; +import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; +import TestDapp from '../page-objects/pages/test-dapp'; describe('wallet_requestPermissions', function () { it('executes a request permissions on eth_accounts event', async function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.title, + fixtures: new FixtureBuilder().build(), + title: this.test?.title, }, async ({ driver }) => { - await unlockWallet(driver); + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); // wallet_requestPermissions - await driver.openNewPage(`http://127.0.0.1:8080`); - const requestPermissionsRequest = JSON.stringify({ jsonrpc: '2.0', method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }], }); - await driver.executeScript( `window.ethereum.request(${requestPermissionsRequest})`, ); - await switchToNotificationWindow(driver); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await switchToOrOpenDapp(driver); + // confirm connect account + await testDapp.confirmConnectAccountModal(); const getPermissionsRequest = JSON.stringify({ method: 'wallet_getPermissions', }); - const getPermissions = await driver.executeScript( `return window.ethereum.request(${getPermissionsRequest})`, ); - - assert.strictEqual(getPermissions[0].parentCapability, 'eth_accounts'); + assert.strictEqual(getPermissions[1].parentCapability, 'eth_accounts'); }, ); }); diff --git a/test/e2e/json-rpc/wallet_revokePermissions.spec.js b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts similarity index 52% rename from test/e2e/json-rpc/wallet_revokePermissions.spec.js rename to test/e2e/json-rpc/wallet_revokePermissions.spec.ts index 70d2fd3ba572..5c444b5ecf01 100644 --- a/test/e2e/json-rpc/wallet_revokePermissions.spec.js +++ b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts @@ -1,12 +1,8 @@ -const { strict: assert } = require('assert'); - -const { - withFixtures, - defaultGanacheOptions, - unlockWallet, - openDapp, -} = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); +import { strict as assert } from 'assert'; +import { ACCOUNT_1, withFixtures } from '../helpers'; +import FixtureBuilder from '../fixture-builder'; +import TestDapp from '../page-objects/pages/test-dapp'; +import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; describe('Revoke Dapp Permissions', function () { it('should revoke dapp permissions ', async function () { @@ -16,18 +12,13 @@ describe('Revoke Dapp Permissions', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver); - - await driver.findElement({ - text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - css: '#accounts', - }); + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_connectedAccounts(ACCOUNT_1); // wallet_revokePermissions request const revokePermissionsRequest = JSON.stringify({ @@ -43,15 +34,10 @@ describe('Revoke Dapp Permissions', function () { const result = await driver.executeScript( `return window.ethereum.request(${revokePermissionsRequest})`, ); - // Response of method call assert.deepEqual(result, null); - // TODO: Fix having to reload dapp as it is not the proper behavior in production, issue with test setup. - await driver.executeScript(`window.location.reload()`); - - // You cannot use driver.findElement() with an empty string, so use xpath - await driver.findElement({ xpath: '//span[@id="accounts"][.=""]' }); + await testDapp.check_connectedAccounts(ACCOUNT_1, false); }, ); }); diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index c7d8b02d4c7d..72809ea62e48 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -753,7 +753,29 @@ async function setupMocking( return { ok: true, statusCode: 200, - json: [{ feature1: true }, { feature2: false }], + json: [ + { feature1: true }, + { feature2: false }, + { + feature3: [ + { + value: 'valueA', + name: 'groupA', + scope: { type: 'threshold', value: 0.3 }, + }, + { + value: 'valueB', + name: 'groupB', + scope: { type: 'threshold', value: 0.5 }, + }, + { + scope: { type: 'threshold', value: 1 }, + value: 'valueC', + name: 'groupC', + }, + ], + }, + ], }; }); diff --git a/test/e2e/mv3-perf-stats/bundle-size.js b/test/e2e/mv3-perf-stats/bundle-size.js index d37ec561bde5..b6580d86538c 100755 --- a/test/e2e/mv3-perf-stats/bundle-size.js +++ b/test/e2e/mv3-perf-stats/bundle-size.js @@ -37,7 +37,7 @@ const UIFileRegex = /ui-[0-9]*.js/u; async function main() { const { argv } = yargs(hideBin(process.argv)).usage( '$0 [options]', - 'Run a page load benchmark', + 'Capture bundle size stats', (_yargs) => _yargs.option('out', { description: diff --git a/test/e2e/mv3-perf-stats/index.js b/test/e2e/mv3-perf-stats/index.js deleted file mode 100644 index 4e56a2385a67..000000000000 --- a/test/e2e/mv3-perf-stats/index.js +++ /dev/null @@ -1,2 +0,0 @@ -require('./init-load-stats'); -require('./bundle-size'); diff --git a/test/e2e/mv3-perf-stats/init-load-stats.js b/test/e2e/mv3-perf-stats/init-load-stats.js deleted file mode 100755 index 40584343d990..000000000000 --- a/test/e2e/mv3-perf-stats/init-load-stats.js +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env node - -/* eslint-disable node/shebang */ -const path = require('path'); -const { promises: fs } = require('fs'); -const yargs = require('yargs/yargs'); -const { hideBin } = require('yargs/helpers'); - -const { exitWithError } = require('../../../development/lib/exit-with-error'); -const { - isWritable, - getFirstParentDirectoryThatExists, -} = require('../../helpers/file'); -const { withFixtures, tinyDelayMs } = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); - -/** - * The e2e test case is used to capture load and initialisation time statistics for extension in MV3 environment. - */ - -async function profilePageLoad() { - const parsedLogs = {}; - try { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - disableServerMochaToBackground: true, - }, - async ({ driver }) => { - await driver.delay(tinyDelayMs); - await driver.navigate(); - await driver.delay(1000); - const logs = await driver.checkBrowserForLavamoatLogs(); - - let logString = ''; - let logType = ''; - - logs.forEach((log) => { - if (log.indexOf('"version": 1') >= 0) { - // log end here - logString += log; - parsedLogs[logType] = JSON.parse(`{${logString}}`); - logString = ''; - logType = ''; - } else if (logType) { - // log string continues - logString += log; - } else if ( - log.search(/"name": ".*app\/scripts\/background.js",/u) >= 0 - ) { - // background log starts - logString += log; - logType = 'background'; - } else if (log.search(/"name": ".*app\/scripts\/ui.js",/u) >= 0) { - // ui log starts - logString += log; - logType = 'ui'; - } else if (log.search(/"name": "Total"/u) >= 0) { - // load time log starts - logString += log; - logType = 'loadTime'; - } - }); - }, - ); - } catch (error) { - console.log('Error in trying to parse logs.'); - } - return parsedLogs; -} - -async function main() { - const { argv } = yargs(hideBin(process.argv)).usage( - '$0 [options]', - 'Run a page load benchmark', - (_yargs) => - _yargs.option('out', { - description: - 'Output filename. Output printed to STDOUT of this is omitted.', - type: 'string', - normalize: true, - }), - ); - - const results = await profilePageLoad(); - const { out } = argv; - - const logCategories = [ - { key: 'background', dirPath: 'initialisation/background/stacks.json' }, - { key: 'ui', dirPath: 'initialisation/ui/stacks.json' }, - { key: 'loadTime', dirPath: 'load_time/stats.json' }, - ]; - - if (out) { - logCategories.forEach(async ({ key, dirPath }) => { - if (results[key]) { - const outPath = `${out}/${dirPath}`; - const outputDirectory = path.dirname(outPath); - const existingParentDirectory = await getFirstParentDirectoryThatExists( - outputDirectory, - ); - if (!(await isWritable(existingParentDirectory))) { - throw new Error('Specified output file directory is not writable'); - } - if (outputDirectory !== existingParentDirectory) { - await fs.mkdir(outputDirectory, { recursive: true }); - } - await fs.writeFile(outPath, JSON.stringify(results[key], null, 2)); - } - }); - } else { - console.log(JSON.stringify(results, null, 2)); - } -} - -main().catch((error) => { - exitWithError(error); -}); diff --git a/test/e2e/mv3-stats.js b/test/e2e/mv3-stats.js deleted file mode 100755 index 2dd24791e9a5..000000000000 --- a/test/e2e/mv3-stats.js +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env node - -/* eslint-disable node/shebang */ -const path = require('path'); -const { promises: fs } = require('fs'); -const yargs = require('yargs/yargs'); -const { hideBin } = require('yargs/helpers'); - -const { exitWithError } = require('../../development/lib/exit-with-error'); -const { - isWritable, - getFirstParentDirectoryThatExists, -} = require('../helpers/file'); -const { withFixtures, tinyDelayMs } = require('./helpers'); -const FixtureBuilder = require('./fixture-builder'); - -/** - * The e2e test case is used to capture load and initialisation time statistics for extension in MV3 environment. - */ - -async function profilePageLoad() { - const parsedLogs = {}; - try { - await withFixtures( - { fixtures: new FixtureBuilder().build() }, - async ({ driver }) => { - await driver.delay(tinyDelayMs); - await driver.navigate(); - await driver.delay(1000); - const logs = await driver.checkBrowserForLavamoatLogs(); - - let logString = ''; - let logType = ''; - - logs.forEach((log) => { - if (log.indexOf('"version": 1') >= 0) { - // log end here - logString += log; - parsedLogs[logType] = JSON.parse(`{${logString}}`); - logString = ''; - logType = ''; - } else if (logType) { - // log string continues - logString += log; - } else if ( - log.search(/"name": ".*app\/scripts\/background.js",/u) >= 0 - ) { - // background log starts - logString += log; - logType = 'background'; - } else if (log.search(/"name": ".*app\/scripts\/ui.js",/u) >= 0) { - // ui log starts - logString += log; - logType = 'ui'; - } else if (log.search(/"name": "Total"/u) >= 0) { - // load time log starts - logString += log; - logType = 'loadTime'; - } - }); - }, - ); - } catch (error) { - console.log('Error in trying to parse logs.'); - } - return parsedLogs; -} - -async function main() { - const { argv } = yargs(hideBin(process.argv)).usage( - '$0 [options]', - 'Run a page load benchmark', - (_yargs) => - _yargs.option('out', { - description: - 'Output filename. Output printed to STDOUT of this is omitted.', - type: 'string', - normalize: true, - }), - ); - - const results = await profilePageLoad(); - const { out } = argv; - - const logCategories = [ - { key: 'background', dirPath: 'initialisation/background/stacks.json' }, - { key: 'ui', dirPath: 'initialisation/ui/stacks.json' }, - { key: 'loadTime', dirPath: 'load_time/stats.json' }, - ]; - - if (out) { - logCategories.forEach(async ({ key, dirPath }) => { - if (results[key]) { - const outPath = `${out}/${dirPath}`; - const outputDirectory = path.dirname(outPath); - const existingParentDirectory = await getFirstParentDirectoryThatExists( - outputDirectory, - ); - if (!(await isWritable(existingParentDirectory))) { - throw new Error('Specified output file directory is not writable'); - } - if (outputDirectory !== existingParentDirectory) { - await fs.mkdir(outputDirectory, { recursive: true }); - } - await fs.writeFile(outPath, JSON.stringify(results[key], null, 2)); - } - }); - } else { - console.log(JSON.stringify(results, null, 2)); - } -} - -main().catch((error) => { - exitWithError(error); -}); diff --git a/test/e2e/page-objects/flows/watch-account.flow.ts b/test/e2e/page-objects/flows/watch-account.flow.ts new file mode 100644 index 000000000000..8481c71599a6 --- /dev/null +++ b/test/e2e/page-objects/flows/watch-account.flow.ts @@ -0,0 +1,22 @@ +import { Driver } from '../../webdriver/driver'; +import HomePage from '../pages/home/homepage'; +import AccountListPage from '../pages/account-list-page'; + +/** + * Initiates the flow of watching an EOA address. + * + * @param driver - The WebDriver instance. + * @param address - The EOA address that is to be watched. + */ +export async function watchEoaAddress( + driver: Driver, + address: string, +): Promise { + // watch a new EOA + const homePage = new HomePage(driver); + await homePage.headerNavbar.openAccountMenu(); + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addEoaAccount(address); + await homePage.check_pageIsLoaded(); +} diff --git a/test/e2e/page-objects/pages/account-list-page.ts b/test/e2e/page-objects/pages/account-list-page.ts index bbf25013f607..8f24cfffede3 100644 --- a/test/e2e/page-objects/pages/account-list-page.ts +++ b/test/e2e/page-objects/pages/account-list-page.ts @@ -1,13 +1,11 @@ -import { strict as assert } from 'assert'; import { Driver } from '../../webdriver/driver'; import { largeDelayMs, regularDelayMs } from '../../helpers'; import messages from '../../../../app/_locales/en/messages.json'; +import { ACCOUNT_TYPE } from '../../constants'; class AccountListPage { private readonly driver: Driver; - private readonly accountAddressText = '.qr-code__address-segments'; - private readonly accountListAddressItem = '[data-testid="account-list-address"]'; @@ -28,10 +26,6 @@ class AccountListPage { private readonly accountOptionsMenuButton = '[data-testid="account-list-item-menu-button"]'; - private readonly accountQrCodeImage = '.qr-code__wrapper'; - - private readonly accountQrCodeAddress = '.qr-code__address-segments'; - private readonly addAccountConfirmButton = '[data-testid="submit-add-account-with-name"]'; @@ -40,9 +34,17 @@ class AccountListPage { tag: 'button', }; + private readonly addSolanaAccountButton = { + text: messages.addNewSolanaAccount.message, + tag: 'button', + }; + private readonly addEthereumAccountButton = '[data-testid="multichain-account-menu-popover-add-account"]'; + private readonly addEoaAccountButton = + '[data-testid="multichain-account-menu-popover-add-watch-only-account"]'; + private readonly addHardwareWalletButton = { text: 'Add hardware wallet', tag: 'button', @@ -65,11 +67,6 @@ class AccountListPage { private readonly currentSelectedAccount = '.multichain-account-list-item--selected'; - private readonly editableLabelButton = - '[data-testid="editable-label-button"]'; - - private readonly editableLabelInput = '[data-testid="editable-input"] input'; - private readonly hiddenAccountOptionsMenuButton = '.multichain-account-menu-popover__list--menu-item-hidden-account [data-testid="account-list-item-menu-button"]'; @@ -119,8 +116,21 @@ class AccountListPage { tag: 'button', }; - private readonly saveAccountLabelButton = - '[data-testid="save-account-label-input"]'; + private readonly watchAccountAddressInput = + 'input#address-input[type="text"]'; + + private readonly watchAccountConfirmButton = { + text: 'Watch account', + tag: 'button', + }; + + private readonly watchAccountModalTitle = { + text: 'Watch any Ethereum account', + tag: 'h4', + }; + + private readonly selectAccountSelector = + '.multichain-account-list-item__account-name'; constructor(driver: Driver) { this.driver = driver; @@ -140,70 +150,35 @@ class AccountListPage { } /** - * Adds a new account with an optional custom label. + * Watch an EOA (external owned account). * - * @param customLabel - The custom label for the new account. If not provided, a default name will be used. + * @param address - The address to watch. + * @param expectedErrorMessage - Optional error message to display if the address is invalid. */ - async addNewAccount(customLabel?: string): Promise { - if (customLabel) { - console.log(`Adding new account with custom label: ${customLabel}`); - } else { - console.log(`Adding new account with default name`); - } + async addEoaAccount( + address: string, + expectedErrorMessage: string = '', + ): Promise { + console.log(`Watch EOA account with address ${address}`); await this.driver.clickElement(this.createAccountButton); - await this.driver.clickElement(this.addEthereumAccountButton); - if (customLabel) { - await this.driver.fill(this.accountNameInput, customLabel); - } - // needed to mitigate a race condition with the state update - // there is no condition we can wait for in the UI - await this.driver.delay(largeDelayMs); + await this.driver.clickElement(this.addEoaAccountButton); + await this.driver.waitForSelector(this.watchAccountModalTitle); + await this.driver.fill(this.watchAccountAddressInput, address); await this.driver.clickElementAndWaitToDisappear( - this.addAccountConfirmButton, + this.watchAccountConfirmButton, ); - } - - /** - * Adds a new BTC account with an optional custom name. - * - * @param options - Options for adding a new BTC account. - * @param [options.btcAccountCreationEnabled] - Indicates if the BTC account creation is expected to be enabled or disabled. Defaults to true. - * @param [options.accountName] - The custom name for the BTC account. Defaults to an empty string, which means the default name will be used. - */ - async addNewBtcAccount({ - btcAccountCreationEnabled = true, - accountName = '', - }: { - btcAccountCreationEnabled?: boolean; - accountName?: string; - } = {}): Promise { - console.log( - `Adding new BTC account${ - accountName ? ` with custom name: ${accountName}` : ' with default name' - }`, - ); - await this.driver.clickElement(this.createAccountButton); - if (btcAccountCreationEnabled) { - await this.driver.clickElement(this.addBtcAccountButton); - // needed to mitigate a race condition with the state update - // there is no condition we can wait for in the UI - await this.driver.delay(largeDelayMs); - if (accountName) { - await this.driver.fill(this.accountNameInput, accountName); - } - await this.driver.clickElementAndWaitToDisappear( - this.addAccountConfirmButton, - // Longer timeout than usual, this reduces the flakiness - // around Bitcoin account creation (mainly required for - // Firefox) - 5000, + if (expectedErrorMessage) { + console.log( + `Check if error message is displayed: ${expectedErrorMessage}`, ); + await this.driver.waitForSelector({ + css: '.snap-ui-renderer__text', + text: expectedErrorMessage, + }); } else { - const createButton = await this.driver.findElement( - this.addBtcAccountButton, + await this.driver.clickElementAndWaitToDisappear( + this.addAccountConfirmButton, ); - assert.equal(await createButton.isEnabled(), false); - await this.driver.clickElement(this.closeAccountModalButton); } } @@ -235,44 +210,100 @@ class AccountListPage { } /** - * Changes the label of the current account. + * Adds a new Solana account with optional custom name. * - * @param newLabel - The new label to set for the account. + * @param options - Options for creating the Solana account + * @param [options.solanaAccountCreationEnabled] - Whether Solana account creation is enabled. If false, verifies the create button is disabled. + * @param [options.accountName] - Optional custom name for the new account + * @returns Promise that resolves when account creation is complete */ - async changeAccountLabel(newLabel: string): Promise { - console.log(`Changing account label to: ${newLabel}`); - await this.driver.clickElement(this.accountMenuButton); - await this.changeLabelFromAccountDetailsModal(newLabel); + async addNewSolanaAccount({ + solanaAccountCreationEnabled = true, + accountName = '', + }: { + solanaAccountCreationEnabled?: boolean; + accountName?: string; + } = {}): Promise { + console.log( + `Adding new Solana account${ + accountName ? ` with custom name: ${accountName}` : ' with default name' + }`, + ); + if (solanaAccountCreationEnabled) { + await this.driver.clickElement(this.addSolanaAccountButton); + // needed to mitigate a race condition with the state update + // there is no condition we can wait for in the UI + if (accountName) { + await this.driver.fill(this.accountNameInput, accountName); + } + await this.driver.clickElementAndWaitToDisappear( + this.addAccountConfirmButton, + // Longer timeout than usual, this reduces the flakiness + // around Bitcoin account creation (mainly required for + // Firefox) + 5000, + ); + } else { + const createButton = await this.driver.findElement( + this.addSolanaAccountButton, + ); + assert.equal(await createButton.isEnabled(), false); + await this.driver.clickElement(this.closeAccountModalButton); + } } /** - * Changes the account label from within an already opened account details modal. - * Note: This method assumes the account details modal is already open. - * - * Recommended usage: - * ```typescript - * await accountListPage.openAccountDetailsModal('Current Account Name'); - * await accountListPage.changeLabelFromAccountDetailsModal('New Account Name'); - * ``` + * Adds a new account of the specified type with an optional custom name. * - * @param newLabel - The new label to set for the account - * @throws Will throw an error if the modal is not open when method is called + * @param options - Options for adding a new account + * @param options.accountType - The type of account to add (Ethereum, Bitcoin, or Solana) + * @param [options.accountName] - Optional custom name for the new account + * @throws {Error} If the specified account type is not supported * @example - * // To rename a specific account, first open its details modal: - * await accountListPage.openAccountDetailsModal('Current Account Name'); - * await accountListPage.changeLabelFromAccountDetailsModal('New Account Name'); + * // Add a new Ethereum account with default name + * await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Ethereum }); * - * // Note: Using changeAccountLabel() alone will only work for the first account + * // Add a new Bitcoin account with custom name + * await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Bitcoin, accountName: 'My BTC Wallet' }); */ - async changeLabelFromAccountDetailsModal(newLabel: string): Promise { - await this.driver.waitForSelector(this.editableLabelButton); - console.log( - `Account details modal opened, changing account label to: ${newLabel}`, + async addAccount({ + accountType, + accountName, + }: { + accountType: ACCOUNT_TYPE; + accountName?: string; + }) { + console.log(`Adding new account of type: ${ACCOUNT_TYPE[accountType]}`); + await this.driver.clickElement(this.createAccountButton); + let addAccountButton; + switch (accountType) { + case ACCOUNT_TYPE.Ethereum: + addAccountButton = this.addEthereumAccountButton; + break; + case ACCOUNT_TYPE.Bitcoin: + addAccountButton = this.addBtcAccountButton; + break; + case ACCOUNT_TYPE.Solana: + addAccountButton = this.addSolanaAccountButton; + break; + default: + throw new Error('Account type not supported'); + } + + await this.driver.clickElement(addAccountButton); + if (accountName) { + console.log( + `Customize the new account with account name: ${accountName}`, + ); + await this.driver.fill(this.accountNameInput, accountName); + } + // needed to mitigate a race condition with the state update + // there is no condition we can wait for in the UI + await this.driver.delay(largeDelayMs); + await this.driver.clickElementAndWaitToDisappear( + this.addAccountConfirmButton, + 5000, ); - await this.driver.clickElement(this.editableLabelButton); - await this.driver.fill(this.editableLabelInput, newLabel); - await this.driver.clickElement(this.saveAccountLabelButton); - await this.driver.clickElement(this.closeAccountModalButton); } async closeAccountModal(): Promise { @@ -282,23 +313,6 @@ class AccountListPage { ); } - /** - * Get the address of the specified account. - * - * @param accountLabel - The label of the account to get the address. - */ - async getAccountAddress(accountLabel: string): Promise { - console.log(`Get account address in account list`); - await this.openAccountOptionsInAccountList(accountLabel); - await this.driver.clickElement(this.accountMenuButton); - await this.driver.waitForSelector(this.accountAddressText); - const accountAddress = await ( - await this.driver.findElement(this.accountAddressText) - ).getText(); - await this.driver.clickElement(this.closeAccountModalButton); - return accountAddress; - } - async hideAccount(): Promise { console.log(`Hide account in account list`); await this.driver.clickElement(this.hideUnhideAccountButton); @@ -330,6 +344,13 @@ class AccountListPage { ); } + async isBtcAccountCreationButtonEnabled(): Promise { + const createButton = await this.driver.findElement( + this.addBtcAccountButton, + ); + return await createButton.isEnabled(); + } + /** * Open the account details modal for the specified account in account list. * @@ -368,10 +389,32 @@ class AccountListPage { console.log( `Check that account value and suffix ${expectedValueAndSuffix} is displayed in account list`, ); - await this.driver.waitForSelector({ - css: this.accountValueAndSuffix, - text: expectedValueAndSuffix, - }); + await this.driver.findElement(this.accountValueAndSuffix, 5000); + await this.driver.waitForSelector( + { + css: this.accountValueAndSuffix, + text: expectedValueAndSuffix, + }, + { + timeout: 20000, + }, + ); + } + + async check_addBitcoinAccountAvailable( + expectedAvailability: boolean, + ): Promise { + console.log( + `Check add bitcoin account button is ${ + expectedAvailability ? 'displayed ' : 'not displayed' + }`, + ); + await this.openAddAccountModal(); + if (expectedAvailability) { + await this.driver.waitForSelector(this.addBtcAccountButton); + } else { + await this.driver.assertElementNotPresent(this.addBtcAccountButton); + } } async openAccountOptionsMenu(): Promise { @@ -492,6 +535,18 @@ class AccountListPage { }); } + async check_accountNotDisplayedInAccountList( + expectedLabel: string = 'Account', + ): Promise { + console.log( + `Check that account label ${expectedLabel} is not displayed in account list`, + ); + await this.driver.assertElementNotPresent({ + css: this.accountListItem, + text: expectedLabel, + }); + } + /** * Checks that the account with the specified label is not displayed in the account list. * @@ -530,21 +585,37 @@ class AccountListPage { } /** - * Check that the correct address is displayed in the account details modal. + * Checks that the add watch account button is displayed in the create account modal. * - * @param expectedAddress - The expected address to check. + * @param expectedAvailability - Whether the add watch account button is expected to be displayed. */ - async check_addressInAccountDetailsModal( - expectedAddress: string, + async check_addWatchAccountAvailable( + expectedAvailability: boolean, ): Promise { console.log( - `Check that address ${expectedAddress} is displayed in account details modal`, + `Check add watch account button is ${ + expectedAvailability ? 'displayed ' : 'not displayed' + }`, ); - await this.driver.waitForSelector(this.accountQrCodeImage); - await this.driver.waitForSelector({ - css: this.accountQrCodeAddress, - text: expectedAddress, - }); + await this.openAddAccountModal(); + if (expectedAvailability) { + await this.driver.waitForSelector(this.addEoaAccountButton); + } else { + await this.driver.assertElementNotPresent(this.addEoaAccountButton); + } + } + + /** + * Verifies that all occurrences of the account balance value and symbol are displayed as private. + * + */ + async check_balanceIsPrivateEverywhere(): Promise { + console.log(`Verify all account balance occurrences are private`); + const balanceSelectors = { + tag: 'span', + text: '••••••', + }; + await this.driver.elementCountBecomesN(balanceSelectors, 6); } async check_currentAccountIsImported(): Promise { @@ -571,11 +642,17 @@ class AccountListPage { console.log( `Verify the number of accounts in the account menu is: ${expectedNumberOfAccounts}`, ); + + await this.driver.waitForSelector(this.accountListItem); await this.driver.wait(async () => { const internalAccounts = await this.driver.findElements( this.accountListItem, ); - return internalAccounts.length === expectedNumberOfAccounts; + const isValid = internalAccounts.length === expectedNumberOfAccounts; + console.log( + `Number of accounts: ${internalAccounts.length} is equal to ${expectedNumberOfAccounts}? ${isValid}`, + ); + return isValid; }, 20000); } @@ -593,6 +670,13 @@ class AccountListPage { await this.openAccountOptionsInAccountList(accountLabel); await this.driver.assertElementNotPresent(this.removeAccountButton); } + + async selectAccount(accountLabel: string): Promise { + await this.driver.clickElement({ + css: this.selectAccountSelector, + text: accountLabel, + }); + } } export default AccountListPage; diff --git a/test/e2e/page-objects/pages/dialog/account-details-modal.ts b/test/e2e/page-objects/pages/dialog/account-details-modal.ts new file mode 100644 index 000000000000..0dbb2e0f87d7 --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/account-details-modal.ts @@ -0,0 +1,106 @@ +import { Driver } from '../../../webdriver/driver'; + +class AccountDetailsModal { + private driver: Driver; + + private readonly accountAddressText = '.qr-code__address-segments'; + + private readonly accountQrCodeAddress = '.qr-code__address-segments'; + + private readonly accountQrCodeImage = '.qr-code__wrapper'; + + private readonly closeAccountModalButton = + 'header button[aria-label="Close"]'; + + private readonly copyAddressButton = + '[data-testid="address-copy-button-text"]'; + + private readonly editableLabelButton = + '[data-testid="editable-label-button"]'; + + private readonly editableLabelInput = '[data-testid="editable-input"] input'; + + private readonly saveAccountLabelButton = + '[data-testid="save-account-label-input"]'; + + private readonly showPrivateKeyButton = { + css: 'button', + text: 'Show private key', + }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.editableLabelButton, + this.copyAddressButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for account details modal to be loaded', + e, + ); + throw e; + } + console.log('Account details modal is loaded'); + } + + async closeAccountDetailsModal(): Promise { + await this.driver.clickElementAndWaitToDisappear( + this.closeAccountModalButton, + ); + } + + /** + * Change the label of the account in the account details modal. + * + * @param newLabel - The new label to set for the account. + */ + async changeAccountLabel(newLabel: string): Promise { + console.log( + `Account details modal opened, changing account label to: ${newLabel}`, + ); + await this.driver.clickElement(this.editableLabelButton); + await this.driver.fill(this.editableLabelInput, newLabel); + await this.driver.clickElement(this.saveAccountLabelButton); + await this.closeAccountDetailsModal(); + } + + async getAccountAddress(): Promise { + console.log(`Get account address in account details modal`); + await this.driver.waitForSelector(this.accountAddressText); + const accountAddress = await ( + await this.driver.findElement(this.accountAddressText) + ).getText(); + await this.closeAccountDetailsModal(); + return accountAddress; + } + + /** + * Check that the correct address is displayed in the account details modal. + * + * @param expectedAddress - The expected address to check. + */ + async check_addressInAccountDetailsModal( + expectedAddress: string, + ): Promise { + console.log( + `Check that address ${expectedAddress} is displayed in account details modal`, + ); + await this.driver.waitForSelector(this.accountQrCodeImage); + await this.driver.waitForSelector({ + css: this.accountQrCodeAddress, + text: expectedAddress, + }); + } + + async check_showPrivateKeyButtonIsNotDisplayed(): Promise { + console.log('Check that show private key button is not displayed'); + await this.driver.assertElementNotPresent(this.showPrivateKeyButton); + } +} + +export default AccountDetailsModal; diff --git a/test/e2e/page-objects/pages/dialog/add-tokens.ts b/test/e2e/page-objects/pages/dialog/add-tokens.ts new file mode 100644 index 000000000000..e587113ab7f5 --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/add-tokens.ts @@ -0,0 +1,50 @@ +import { strict as assert } from 'assert'; +import { Driver } from '../../../webdriver/driver'; + +class AddTokensModal { + protected driver: Driver; + + private addTokenButton = { text: 'Add token', tag: 'button' }; + + private tokenListItem = '.confirm-add-suggested-token__token-list-item'; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.tokenListItem, + this.addTokenButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for Add tokens dialog to be loaded', + e, + ); + throw e; + } + console.log('Add tokens dialog was loaded'); + } + + /** + * Checks the count of suggested tokens. + * + * @param expectedTokenCount - The expected count of suggested tokens. + */ + async check_SuggestedTokensCount(expectedTokenCount: number) { + const multipleSuggestedTokens = await this.driver.findElements( + this.tokenListItem, + ); + + // Confirm the expected number of tokens are present as suggested token list + assert.equal(multipleSuggestedTokens.length, expectedTokenCount); + } + + async confirmAddTokens() { + await this.driver.clickElementAndWaitForWindowToClose(this.addTokenButton); + } +} + +export default AddTokensModal; diff --git a/test/e2e/page-objects/pages/dialog/create-contract.ts b/test/e2e/page-objects/pages/dialog/create-contract.ts new file mode 100644 index 000000000000..44c101271ffe --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/create-contract.ts @@ -0,0 +1,39 @@ +import { Driver } from '../../../webdriver/driver'; + +class CreateContractModal { + protected driver: Driver; + + private readonly confirmButtton = { text: 'Confirm', tag: 'button' }; + + private readonly cancelButton = { text: 'Cancel', tag: 'button' }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.confirmButtton, + this.cancelButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for create contract dialog to be loaded', + e, + ); + throw e; + } + console.log('Create contract dialog was loaded'); + } + + async clickConfirm() { + await this.driver.clickElementAndWaitForWindowToClose(this.confirmButtton); + } + + async clickCancel() { + await this.driver.clickElementAndWaitForWindowToClose(this.cancelButton); + } +} + +export default CreateContractModal; diff --git a/test/e2e/page-objects/pages/header-navbar.ts b/test/e2e/page-objects/pages/header-navbar.ts index 5c0808eea93a..5324def49aab 100644 --- a/test/e2e/page-objects/pages/header-navbar.ts +++ b/test/e2e/page-objects/pages/header-navbar.ts @@ -1,13 +1,16 @@ +import { strict as assert } from 'assert'; import { Driver } from '../../webdriver/driver'; class HeaderNavbar { - private driver: Driver; + protected driver: Driver; private readonly accountMenuButton = '[data-testid="account-menu-icon"]'; private readonly allPermissionsButton = '[data-testid="global-menu-connected-sites"]'; + private readonly copyAddressButton = '[data-testid="app-header-copy-button"]'; + private readonly threeDotMenuButton = '[data-testid="account-options-menu-button"]'; @@ -18,10 +21,15 @@ class HeaderNavbar { private readonly mmiPortfolioButton = '[data-testid="global-menu-mmi-portfolio"]'; + private readonly openAccountDetailsButton = + '[data-testid="account-list-menu-details"]'; + private readonly settingsButton = '[data-testid="global-menu-settings"]'; private readonly switchNetworkDropDown = '[data-testid="network-display"]'; + private readonly networkPicker = '.mm-picker-network'; + constructor(driver: Driver) { this.driver = driver; } @@ -46,6 +54,13 @@ class HeaderNavbar { async openAccountMenu(): Promise { await this.driver.clickElement(this.accountMenuButton); + await this.driver.waitForSelector('.multichain-account-menu-popover__list'); + } + + async openAccountDetailsModal(): Promise { + console.log('Open account details modal'); + await this.openThreeDotMenu(); + await this.driver.clickElement(this.openAccountDetailsButton); } async openThreeDotMenu(): Promise { @@ -87,6 +102,29 @@ class HeaderNavbar { ); } + async check_ifNetworkPickerClickable(clickable: boolean): Promise { + console.log('Check whether the network picker is clickable or not'); + assert.equal( + await (await this.driver.findElement(this.networkPicker)).isEnabled(), + clickable, + ); + } + + /** + * Verifies that the displayed account address in header matches the expected address. + * + * @param expectedAddress - The expected address of the account. + */ + async check_accountAddress(expectedAddress: string): Promise { + console.log( + `Verify the displayed account address in header is: ${expectedAddress}`, + ); + await this.driver.waitForSelector({ + css: this.copyAddressButton, + text: expectedAddress, + }); + } + /** * Verifies that the displayed account label in header matches the expected label. * diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index db9367991bf7..8c120b9879b7 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -24,6 +24,11 @@ class AssetListPage { private readonly currentNetworksTotal = `${this.currentNetworkOption} [data-testid="account-value-and-suffix"]`; + private readonly customTokenModalOption = { + text: 'Custom token', + tag: 'button', + }; + private readonly hideTokenButton = '[data-testid="asset-options__hide"]'; private readonly hideTokenConfirmationButton = @@ -43,16 +48,42 @@ class AssetListPage { private readonly networksToggle = '[data-testid="sort-by-networks"]'; + private sortByAlphabetically = '[data-testid="sortByAlphabetically"]'; + + private sortByDecliningBalance = '[data-testid="sortByDecliningBalance"]'; + + private sortByPopoverToggle = '[data-testid="sort-by-popover-toggle"]'; + + private readonly tokenAddressInput = + '[data-testid="import-tokens-modal-custom-address"]'; + private readonly tokenAmountValue = '[data-testid="multichain-token-list-item-value"]'; + private readonly tokenImportedSuccessMessage = { + text: 'Token imported', + tag: 'h6', + }; + private readonly tokenListItem = '[data-testid="multichain-token-list-button"]'; private readonly tokenOptionsButton = '[data-testid="import-token-button"]'; + private tokenPercentage(address: string): string { + return `[data-testid="token-increase-decrease-percentage-${address}"]`; + } + private readonly tokenSearchInput = 'input[placeholder="Search tokens"]'; + private readonly tokenSymbolInput = + '[data-testid="import-tokens-modal-custom-symbol"]'; + + private readonly modalWarningBanner = 'div.mm-banner-alert--severity-warning'; + + private readonly tokenIncreaseDecreaseValue = + '[data-testid="token-increase-decrease-value"]'; + constructor(driver: Driver) { this.driver = driver; } @@ -103,6 +134,29 @@ class AssetListPage { return assets.length; } + async getTokenListNames(): Promise { + console.log(`Retrieving the list of token names`); + const tokenElements = await this.driver.findElements(this.tokenListItem); + const tokenNames = await Promise.all( + tokenElements.map(async (element) => { + return await element.getText(); + }), + ); + return tokenNames; + } + + async sortTokenList( + sortBy: 'alphabetically' | 'decliningBalance', + ): Promise { + console.log(`Sorting the token list by ${sortBy}`); + await this.driver.clickElement(this.sortByPopoverToggle); + if (sortBy === 'alphabetically') { + await this.driver.clickElement(this.sortByAlphabetically); + } else if (sortBy === 'decliningBalance') { + await this.driver.clickElement(this.sortByDecliningBalance); + } + } + /** * Hides a token by clicking on the token name, and confirming the hide modal. * @@ -119,6 +173,22 @@ class AssetListPage { ); } + async importCustomToken(tokenAddress: string, symbol: string): Promise { + console.log(`Creating custom token ${symbol} on homepage`); + await this.driver.clickElement(this.tokenOptionsButton); + await this.driver.clickElement(this.importTokensButton); + await this.driver.waitForSelector(this.importTokenModalTitle); + await this.driver.clickElement(this.customTokenModalOption); + await this.driver.waitForSelector(this.modalWarningBanner); + await this.driver.fill(this.tokenAddressInput, tokenAddress); + await this.driver.fill(this.tokenSymbolInput, symbol); + await this.driver.clickElement(this.importTokensNextButton); + await this.driver.clickElementAndWaitToDisappear( + this.confirmImportTokenButton, + ); + await this.driver.waitForSelector(this.tokenImportedSuccessMessage); + } + async importTokenBySearch(tokenName: string) { console.log(`Import token ${tokenName} on homepage by search`); await this.driver.clickElement(this.tokenOptionsButton); @@ -133,6 +203,24 @@ class AssetListPage { ); } + async importMultipleTokensBySearch(tokenNames: string[]) { + console.log( + `Importing tokens ${tokenNames.join(', ')} on homepage by search`, + ); + await this.driver.clickElement(this.tokenOptionsButton); + await this.driver.clickElement(this.importTokensButton); + await this.driver.waitForSelector(this.importTokenModalTitle); + + for (const name of tokenNames) { + await this.driver.fill(this.tokenSearchInput, name); + await this.driver.clickElement({ text: name, tag: 'p' }); + } + await this.driver.clickElement(this.importTokensNextButton); + await this.driver.clickElementAndWaitToDisappear( + this.confirmImportTokenButton, + ); + } + async openNetworksFilter(): Promise { console.log(`Opening the network filter`); await this.driver.clickElement(this.networksToggle); @@ -204,6 +292,21 @@ class AssetListPage { }); } + /** + * This function checks if the specified token is displayed in the token list by its name. + * + * @param tokenName - The name of the token to check for. + * @returns A promise that resolves if the specified token is displayed. + */ + async check_tokenIsDisplayed(tokenName: string): Promise { + console.log(`Waiting for token ${tokenName} to be displayed`); + await this.driver.waitForSelector({ + text: tokenName, + tag: 'p', + }); + console.log(`Token ${tokenName} is displayed.`); + } + /** * This function checks if the specified number of token items is displayed in the token list. * @@ -220,6 +323,71 @@ class AssetListPage { `Expected number of token items ${expectedNumber} is displayed.`, ); } + + /** + * Checks if the token's general increase or decrease percentage is displayed correctly + * + * @param address - The token address to check + * @param expectedChange - The expected change percentage value (e.g. '+0.02%' or '-0.03%') + */ + async check_tokenGeneralChangePercentage( + address: string, + expectedChange: string, + ): Promise { + console.log( + `Checking token general change percentage for address ${address}`, + ); + const isPresent = await this.driver.isElementPresentAndVisible({ + css: this.tokenPercentage(address), + text: expectedChange, + }); + if (!isPresent) { + throw new Error( + `Token general change percentage ${expectedChange} not found for address ${address}`, + ); + } + } + + /** + * Checks if the token's percentage change element does not exist + * + * @param address - The token address to check + */ + async check_tokenGeneralChangePercentageNotPresent( + address: string, + ): Promise { + console.log( + `Checking token general change percentage is not present for address ${address}`, + ); + const isPresent = await this.driver.isElementPresent({ + css: this.tokenPercentage(address), + }); + if (isPresent) { + throw new Error( + `Token general change percentage element should not exist for address ${address}`, + ); + } + } + + /** + * Checks if the token's general increase or decrease value is displayed correctly + * + * @param expectedChangeValue - The expected change value (e.g. '+$50.00' or '-$30.00') + */ + async check_tokenGeneralChangeValue( + expectedChangeValue: string, + ): Promise { + console.log(`Checking token general change value ${expectedChangeValue}`); + const isPresent = await this.driver.isElementPresentAndVisible({ + css: this.tokenIncreaseDecreaseValue, + text: expectedChangeValue, + }); + if (!isPresent) { + throw new Error( + `Token general change value ${expectedChangeValue} not found`, + ); + } + } } export default AssetListPage; diff --git a/test/e2e/page-objects/pages/home/bitcoin-homepage.ts b/test/e2e/page-objects/pages/home/bitcoin-homepage.ts new file mode 100644 index 000000000000..691d85763b14 --- /dev/null +++ b/test/e2e/page-objects/pages/home/bitcoin-homepage.ts @@ -0,0 +1,106 @@ +import HomePage from './homepage'; + +class BitcoinHomepage extends HomePage { + protected readonly balance = + '[data-testid="coin-overview__primary-currency"]'; + + protected readonly bridgeButton = '[data-testid="coin-overview-bridge"]'; + + private readonly buySellButton = '[data-testid="coin-overview-buy"]'; + + private readonly receiveButton = '[data-testid="coin-overview-receive"]'; + + protected readonly sendButton = '[data-testid="coin-overview-send"]'; + + protected readonly swapButton = '[data-testid="coin-overview-swap"]'; + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.sendButton, + this.buySellButton, + this.receiveButton, + ]); + } catch (e) { + console.log('Timeout while waiting for bitcoin homepage to be loaded', e); + throw e; + } + console.log('Bitcoin homepage is loaded'); + } + + /** + * Checks if the bridge button is enabled on bitcoin account homepage. + * + */ + async check_isBridgeButtonEnabled(): Promise { + try { + await this.driver.findClickableElement(this.bridgeButton, 1000); + } catch (e) { + console.log('Bridge button not enabled', e); + return false; + } + console.log('Bridge button is enabled'); + return true; + } + + /** + * Checks if the buy/sell button is enabled on bitcoin account homepage. + */ + async check_isBuySellButtonEnabled(): Promise { + try { + await this.driver.findClickableElement(this.buySellButton, 1000); + } catch (e) { + console.log('Buy/Sell button not enabled', e); + return false; + } + console.log('Buy/Sell button is enabled'); + return true; + } + + /** + * Checks if the expected bitcoin balance is displayed on homepage. + * + * @param expectedBalance - The expected bitcoin balance to be displayed. Defaults to '0'. + */ + async check_isExpectedBitcoinBalanceDisplayed( + expectedBalance: number = 0, + ): Promise { + console.log( + `Check if expected bitcoin balance is displayed: ${expectedBalance} BTC`, + ); + await this.driver.waitForSelector({ + css: this.balance, + text: `${expectedBalance}BTC`, + }); + } + + /** + * Checks if the receive button is enabled on bitcoin account homepage. + */ + async check_isReceiveButtonEnabled(): Promise { + try { + await this.driver.findClickableElement(this.receiveButton, 1000); + } catch (e) { + console.log('Receive button not enabled', e); + return false; + } + console.log('Receive button is enabled'); + return true; + } + + /** + * Checks if the swap button is enabled on bitcoin account homepage. + */ + async check_isSwapButtonEnabled(): Promise { + try { + await this.driver.findClickableElement(this.swapButton, 1000); + } catch (e) { + console.log('Swap button not enabled', e); + return false; + } + console.log('Swap button is enabled'); + return true; + } +} + +export default BitcoinHomepage; diff --git a/test/e2e/page-objects/pages/home/homepage.ts b/test/e2e/page-objects/pages/home/homepage.ts index 8240e51f736c..708ae5ac0277 100644 --- a/test/e2e/page-objects/pages/home/homepage.ts +++ b/test/e2e/page-objects/pages/home/homepage.ts @@ -4,38 +4,62 @@ import { getCleanAppState } from '../../../helpers'; import HeaderNavbar from '../header-navbar'; class HomePage { - private driver: Driver; + protected driver: Driver; public headerNavbar: HeaderNavbar; - private readonly activityTab = - '[data-testid="account-overview__activity-tab"]'; + private readonly activityTab = { + testId: 'account-overview__activity-tab', + }; - private readonly balance = '[data-testid="eth-overview__primary-currency"]'; + protected readonly balance: string = + '[data-testid="eth-overview__primary-currency"]'; private readonly basicFunctionalityOffWarningMessage = { text: 'Basic functionality is off', css: '.mm-banner-alert', }; + protected readonly bridgeButton: string = + '[data-testid="eth-overview-bridge"]'; + private readonly closeUseNetworkNotificationModalButton = { text: 'Got it', tag: 'h6', }; - private readonly erc20TokenDropdown = '[data-testid="import-token-button"]'; + private readonly erc20TokenDropdown = { + testId: 'import-token-button', + }; - private readonly nftTab = '[data-testid="account-overview__nfts-tab"]'; + private readonly nftTab = { + testId: 'account-overview__nfts-tab', + }; private readonly popoverBackground = '.popover-bg'; - private readonly popoverCloseButton = '[data-testid="popover-close"]'; + private readonly popoverCloseButton = { + testId: 'popover-close', + }; - private readonly refreshErc20Tokens = '[data-testid="refreshList"]'; + private readonly portfolioLink = '[data-testid="portfolio-link"]'; - private readonly sendButton = '[data-testid="eth-overview-send"]'; + private readonly privacyBalanceToggle = { + testId: 'sensitive-toggle', + }; + + protected readonly sendButton: string = '[data-testid="eth-overview-send"]'; - private readonly tokensTab = '[data-testid="account-overview__asset-tab"]'; + protected readonly swapButton: string = + '[data-testid="token-overview-button-swap"]'; + + private readonly refreshErc20Tokens = { + testId: 'refreshList', + }; + + private readonly tokensTab = { + testId: 'account-overview__asset-tab', + }; constructor(driver: Driver) { this.driver = driver; @@ -83,6 +107,11 @@ class HomePage { await this.driver.clickElement(this.nftTab); } + async openPortfolioPage(): Promise { + console.log(`Open portfolio page on homepage`); + await this.driver.clickElement(this.portfolioLink); + } + async refreshErc20TokenList(): Promise { console.log(`Refresh the ERC20 token list`); await this.driver.clickElement(this.erc20TokenDropdown); @@ -93,6 +122,10 @@ class HomePage { await this.driver.clickElement(this.sendButton); } + async togglePrivacyBalance(): Promise { + await this.driver.clickElement(this.privacyBalanceToggle); + } + /** * Checks if the toaster message for adding a network is displayed on the homepage. * @@ -115,6 +148,13 @@ class HomePage { await this.driver.waitForSelector(this.basicFunctionalityOffWarningMessage); } + async check_disabledButtonTooltip(tooltipText: string): Promise { + console.log(`Check if disabled button tooltip is displayed on homepage`); + await this.driver.waitForSelector( + `.icon-button--disabled [data-tooltipped][data-original-title="${tooltipText}"]`, + ); + } + /** * Checks if the toaster message for editing a network is displayed on the homepage. * @@ -170,6 +210,39 @@ class HomePage { }, 10000); } + async check_ifBridgeButtonIsClickable(): Promise { + try { + await this.driver.findClickableElement(this.bridgeButton, 1000); + } catch (e) { + console.log('Bridge button not clickable', e); + return false; + } + console.log('Bridge button is clickable'); + return true; + } + + async check_ifSendButtonIsClickable(): Promise { + try { + await this.driver.findClickableElement(this.sendButton, 1000); + } catch (e) { + console.log('Send button not clickable', e); + return false; + } + console.log('Send button is clickable'); + return true; + } + + async check_ifSwapButtonIsClickable(): Promise { + try { + await this.driver.findClickableElement(this.swapButton, 1000); + } catch (e) { + console.log('Swap button not clickable', e); + return false; + } + console.log('Swap button is clickable'); + return true; + } + async check_localBlockchainBalanceIsDisplayed( localBlockchainServer?: Ganache, address = null, diff --git a/test/e2e/page-objects/pages/home/nft-list.ts b/test/e2e/page-objects/pages/home/nft-list.ts index e26a98e44a92..ca8211417daf 100644 --- a/test/e2e/page-objects/pages/home/nft-list.ts +++ b/test/e2e/page-objects/pages/home/nft-list.ts @@ -73,7 +73,7 @@ class NftListPage { `Check that NFT item ${nftName} is displayed in NFT tab on homepage`, ); await this.driver.waitForSelector({ - tag: 'h5', + tag: 'p', text: nftName, }); } diff --git a/test/e2e/page-objects/pages/home/non-evm-homepage.ts b/test/e2e/page-objects/pages/home/non-evm-homepage.ts new file mode 100644 index 000000000000..20e37f28595b --- /dev/null +++ b/test/e2e/page-objects/pages/home/non-evm-homepage.ts @@ -0,0 +1,67 @@ +import HomePage from './homepage'; + +class NonEvmHomepage extends HomePage { + protected readonly buySellButton = '[data-testid="coin-overview-buy"]'; + + protected readonly receiveButton = '[data-testid="coin-overview-receive"]'; + + protected readonly sendButton = '[data-testid="coin-overview-send"]'; + + protected readonly swapButton = '[data-testid="token-overview-button-swap"]'; + + /** + * Clicks the send button on the non-EVM account homepage. + */ + async clickOnSendButton(): Promise { + await this.driver.waitForControllersLoaded(); + await this.driver.clickElement(this.sendButton); + } + + /** + * Checks if the expected balance is displayed on homepage. + * + * @param balance + */ + async check_getBalance(balance: string): Promise { + console.log(`Getting Non-evm account balance`); + await this.driver.waitForSelector( + { + css: 'div', + text: balance, + }, + { timeout: 5000 }, + ); + } + + /** + * Checks if the receive button is enabled on a non-evm account homepage. + */ + async check_isReceiveButtonEnabled(): Promise { + try { + await this.driver.waitForSelector(this.receiveButton, { timeout: 5000 }); + } catch (e) { + console.log('Receive button not enabled', e); + return false; + } + console.log('Receive button is enabled'); + return true; + } + + /** + * Checks if the buy/sell button is enabled on a non-evm account homepage. + */ + async check_ifBuySellButtonIsClickable(): Promise { + try { + await this.driver.waitForSelector(this.buySellButton, { timeout: 5000 }); + const buySellButton = await this.driver.findClickableElement( + this.buySellButton, + ); + return await buySellButton.isEnabled(); + } catch (e) { + console.log('Buy/Sell button not enabled', e); + return false; + } + } +} + +export default NonEvmHomepage; diff --git a/test/e2e/page-objects/pages/permission/site-permission-page.ts b/test/e2e/page-objects/pages/permission/site-permission-page.ts index bc5eee61c781..9f7ae5d778ff 100644 --- a/test/e2e/page-objects/pages/permission/site-permission-page.ts +++ b/test/e2e/page-objects/pages/permission/site-permission-page.ts @@ -7,7 +7,33 @@ import { Driver } from '../../../webdriver/driver'; class SitePermissionPage { private driver: Driver; - private readonly permissionPage = '[data-testid ="connections-page"]'; + private readonly confirmEditAccountsButton = + '[data-testid="connect-more-accounts-button"]'; + + private readonly confirmEditNetworksButton = + '[data-testid="connect-more-chains-button"]'; + + private readonly connectedAccountsInfo = { + text: 'See your accounts and suggest transactions', + tag: 'p', + }; + + private readonly editAccountsModalTitle = { + text: 'Edit accounts', + tag: 'h4', + }; + + private readonly editButton = '[data-testid="edit"]'; + + private readonly editNetworksModalTitle = { + text: 'Edit networks', + tag: 'h4', + }; + + private readonly enabledNetworksInfo = { + text: 'Use your enabled networks', + tag: 'p', + }; constructor(driver: Driver) { this.driver = driver; @@ -20,7 +46,8 @@ class SitePermissionPage { */ async check_pageIsLoaded(site: string): Promise { try { - await this.driver.waitForSelector(this.permissionPage); + await this.driver.waitForSelector(this.connectedAccountsInfo); + await this.driver.waitForSelector(this.enabledNetworksInfo); await this.driver.waitForSelector({ text: site, tag: 'span' }); } catch (e) { console.log( @@ -31,6 +58,68 @@ class SitePermissionPage { } console.log('Site permission page is loaded'); } + + /** + * Edit permissions for accounts on site permission page + * + * @param accountLabels - Account labels to edit + */ + async editPermissionsForAccount(accountLabels: string[]): Promise { + console.log(`Edit permissions for accounts: ${accountLabels}`); + const editButtons = await this.driver.findElements(this.editButton); + await editButtons[0].click(); + await this.driver.waitForSelector(this.editAccountsModalTitle); + for (const accountLabel of accountLabels) { + await this.driver.clickElement({ text: accountLabel, tag: 'button' }); + } + await this.driver.clickElementAndWaitToDisappear( + this.confirmEditAccountsButton, + ); + } + + /** + * Edit permissions for networks on site permission page + * + * @param networkNames - Network names to edit + */ + async editPermissionsForNetwork(networkNames: string[]): Promise { + console.log(`Edit permissions for networks: ${networkNames}`); + const editButtons = await this.driver.findElements(this.editButton); + await editButtons[1].click(); + await this.driver.waitForSelector(this.editNetworksModalTitle); + for (const networkName of networkNames) { + await this.driver.clickElement({ text: networkName, tag: 'p' }); + } + await this.driver.clickElementAndWaitToDisappear( + this.confirmEditNetworksButton, + ); + } + + /** + * Check if the number of connected accounts is correct + * + * @param number - Expected number of connected accounts + */ + async check_connectedAccountsNumber(number: number): Promise { + console.log(`Check that the number of connected accounts is: ${number}`); + await this.driver.waitForSelector({ + text: `${number} accounts connected`, + tag: 'span', + }); + } + + /** + * Check if the number of connected networks is correct + * + * @param number - Expected number of connected networks + */ + async check_connectedNetworksNumber(number: number): Promise { + console.log(`Check that the number of connected networks is: ${number}`); + await this.driver.waitForSelector({ + text: `${number} networks connected`, + tag: 'span', + }); + } } export default SitePermissionPage; diff --git a/test/e2e/page-objects/pages/send/send-token-page.ts b/test/e2e/page-objects/pages/send/send-token-page.ts index 3c1d96618556..6b3dd2a78d78 100644 --- a/test/e2e/page-objects/pages/send/send-token-page.ts +++ b/test/e2e/page-objects/pages/send/send-token-page.ts @@ -40,6 +40,9 @@ class SendTokenPage { private readonly toastText = '.toast-text'; + private readonly warning = + '[data-testid="send-warning"] .mm-box--min-width-0 span'; + constructor(driver: Driver) { this.driver = driver; } @@ -196,6 +199,22 @@ class SendTokenPage { text: address, }); } + + /** + * Verifies that a specific warning message is displayed on the send token screen. + * + * @param warningText - The expected warning text to validate against. + * @returns A promise that resolves if the warning message matches the expected text. + * @throws Assertion error if the warning message does not match the expected text. + */ + async check_warningMessage(warningText: string): Promise { + console.log(`Checking if warning message "${warningText}" is displayed`); + await this.driver.waitForSelector({ + css: this.warning, + text: warningText, + }); + console.log('Warning message validation successful'); + } } export default SendTokenPage; diff --git a/test/e2e/page-objects/pages/send/solana-confirm-tx-page.ts b/test/e2e/page-objects/pages/send/solana-confirm-tx-page.ts new file mode 100644 index 000000000000..85086cd36659 --- /dev/null +++ b/test/e2e/page-objects/pages/send/solana-confirm-tx-page.ts @@ -0,0 +1,90 @@ +import { Driver } from '../../../webdriver/driver'; + +class ConfirmSolanaTxPage { + private driver: Driver; + + private readonly toAddressInput = '#send-to'; + + private readonly sendButton = { + text: 'Send', + tag: 'span', + }; + + private readonly cancelButton = { + text: 'Cancel', + tag: 'span', + }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async checkAmountDisplayed( + amount: string, + currency: string = 'SOL', + ): Promise { + try { + await this.driver.waitForSelector({ + text: `Sending ${amount} ${currency}`, + tag: 'h2', + }); + return true; + } catch (err) { + console.log('Amount summary text incorrect'); + return false; + } + } + + async isTransactionDetailDisplayed(text: string): Promise { + const detail = await this.driver.findElement( + { + text, + tag: 'p', + }, + 200, + ); + return await detail.isDisplayed(); + } + + async setToAddress(toAddress: string): Promise { + await this.driver.pasteIntoField(this.toAddressInput, toAddress); + } + + /** + * Clicks the send button on the Solana transaction confirmation page + */ + async clickOnSend(): Promise { + const sendButton = await this.driver.findElement(this.sendButton); + await sendButton.click(); + } + + async isSendButtonEnabled(): Promise { + try { + await this.driver.findClickableElement(this.sendButton, 1000); + } catch (e) { + console.log('Send button not enabled', e); + return false; + } + console.log('Send button is enabled'); + return true; + } + + async isInsufficientBalanceDisplayed(): Promise { + try { + await this.driver.findClickableElement( + { + text: 'Insufficient balance', + tag: 'p', + }, + 1000, + ); + } catch (e) { + console.log('Insufficient balance message not displayed', e); + return false; + } + console.log('Insufficient balance message displayed'); + return true; + } +} + +export default ConfirmSolanaTxPage; diff --git a/test/e2e/page-objects/pages/send/solana-send-page.ts b/test/e2e/page-objects/pages/send/solana-send-page.ts new file mode 100644 index 000000000000..e048bd5c63df --- /dev/null +++ b/test/e2e/page-objects/pages/send/solana-send-page.ts @@ -0,0 +1,98 @@ +import { Driver } from '../../../webdriver/driver'; + +class SendSolanaPage { + private driver: Driver; + + private readonly sendAmountInput = '#send-amount-input'; + + private readonly toAddressInput = '#send-to'; + + private readonly continueButton = { + text: 'Continue', + tag: 'button', + }; + + private readonly swapCurrencyButton = '#send-swap-currency'; + + private readonly cancelButton = { + text: 'Cancel', + tag: 'button', + }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async clickOnSwapCurrencyButton(): Promise { + await this.driver.waitForControllersLoaded(); + const swapCurrencyButton = await this.driver.waitForSelector( + this.swapCurrencyButton, + { timeout: 10000 }, + ); + await swapCurrencyButton.click(); + } + + async check_validationErrorAppears( + validationErrorText: string, + ): Promise { + try { + await this.driver.waitForSelector( + { + text: validationErrorText, + tag: 'p', + }, + { timeout: 5000 }, + ); + return true; + } catch (e) { + console.log(`${validationErrorText} is not displayed`); + return false; + } + } + + async setAmount(amount: string): Promise { + await this.driver.waitForControllersLoaded(); + await this.driver.waitForSelector(this.sendAmountInput, { timeout: 10000 }); + await this.driver.pasteIntoField(this.sendAmountInput, amount); + } + + async setToAddress(toAddress: string): Promise { + await this.driver.waitForControllersLoaded(); + await this.driver.waitForSelector(this.toAddressInput, { timeout: 10000 }); + await this.driver.pasteIntoField(this.toAddressInput, toAddress); + } + + async clickOnContinue(): Promise { + const continueButton = await this.driver.waitForSelector( + { + text: 'Continue', + tag: 'span', + }, + { timeout: 5000 }, + ); // Since the buttons takes a bit to get enabled, this avoid test flakiness + const clickableButton = await this.driver.findElement( + '.confirmation-page button:nth-of-type(2)', + ); + await this.driver.wait(() => clickableButton.isEnabled()); + await continueButton.click(); + } + + async isContinueButtonEnabled(): Promise { + try { + const continueButton = await this.driver.findClickableElement( + this.continueButton, + 2000, + ); + await this.driver.wait( + async () => await continueButton.isEnabled(), + 5000, + ); + return await continueButton.isEnabled(); + } catch (e) { + console.log('Continue button not enabled', e); + return false; + } + } +} + +export default SendSolanaPage; diff --git a/test/e2e/page-objects/pages/send/solana-tx-result-page.ts b/test/e2e/page-objects/pages/send/solana-tx-result-page.ts new file mode 100644 index 000000000000..41d029df2cd6 --- /dev/null +++ b/test/e2e/page-objects/pages/send/solana-tx-result-page.ts @@ -0,0 +1,82 @@ +import { Driver } from '../../../webdriver/driver'; + +class SolanaTxresultPage { + private driver: Driver; + + private readonly closeButton = { + text: 'Close', + tag: 'span', + }; + + private readonly viewTransactionLink = { + text: 'View transaction', + tag: 'span', + }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_isViewTransactionLinkDisplayed() { + try { + await this.driver.findClickableElement(this.viewTransactionLink); + return true; + } catch (err) { + console.log('View transaction link not displayed'); + return false; + } + } + + async check_TransactionStatus(sent: boolean): Promise { + const statusText = sent ? 'Sent' : 'Transaction failed'; + try { + await this.driver.findElement({ + text: statusText, + tag: 'h2', + }); + return true; + } catch (err) { + console.log('Transaction status incorrect'); + return false; + } + } + + async check_TransactionStatusText( + amount: string, + sent: boolean, + ): Promise { + const displayedText = sent + ? `${amount} SOL was successfully sent` + : `Unable to send ${amount} SOL`; + const txStatusText = { + text: displayedText, + tag: 'p', + }; + try { + await this.driver.waitForSelector( + txStatusText, + { timeout: 5000 }, // even the tx is being mock, there is an spinner that sometimes is slow to disappear + ); + return true; + } catch (err) { + console.log( + `Transaction status text incorrect, expected ${displayedText} did not match`, + ); + return false; + } + } + + async isTransactionDetailDisplayed(text: string): Promise { + const detail = await this.driver.waitForSelector({ + text, + tag: 'p', + }); + return await detail.isDisplayed(); + } + + async clickOnClose(): Promise { + await this.driver.clickElement(this.closeButton); + } +} + +export default SolanaTxresultPage; diff --git a/test/e2e/page-objects/pages/settings/experimental-settings.ts b/test/e2e/page-objects/pages/settings/experimental-settings.ts index c3f81d99bf23..f3755db72947 100644 --- a/test/e2e/page-objects/pages/settings/experimental-settings.ts +++ b/test/e2e/page-objects/pages/settings/experimental-settings.ts @@ -1,4 +1,5 @@ import { Driver } from '../../../webdriver/driver'; +import messages from '../../../../../app/_locales/en/messages.json'; class ExperimentalSettings { private readonly driver: Driver; @@ -7,6 +8,9 @@ class ExperimentalSettings { private readonly addAccountSnapToggle = '[data-testid="add-account-snap-toggle-div"]'; + private readonly addBitcoinAccountToggle = + '[data-testid="bitcoin-support-toggle-div"]'; + private readonly experimentalPageTitle = { text: 'Experimental', tag: 'h4', @@ -15,8 +19,11 @@ class ExperimentalSettings { private readonly redesignedSignatureToggle = '[data-testid="toggle-redesigned-confirmations-container"]'; - private readonly requestQueueToggle = - '[data-testid="experimental-setting-toggle-request-queue"] label'; + private readonly watchAccountToggleState = + '[data-testid="watch-account-toggle"]'; + + private readonly watchAccountToggle = + '[data-testid="watch-account-toggle-div"]'; constructor(driver: Driver) { this.driver = driver; @@ -35,6 +42,24 @@ class ExperimentalSettings { console.log('Experimental Settings page is loaded'); } + // Get the state of the Watch Account Toggle, returns true if the toggle is selected + async getWatchAccountToggleState(): Promise { + console.log('Get Watch Account Toggle State'); + const toggleInput = await this.driver.findElement( + this.watchAccountToggleState, + ); + return toggleInput.isSelected(); + } + + async toggleBitcoinAccount(): Promise { + console.log('Toggle Add new Bitcoin account on experimental setting page'); + await this.driver.waitForSelector({ + text: messages.bitcoinSupportToggleTitle.message, + tag: 'span', + }); + await this.driver.clickElement(this.addBitcoinAccountToggle); + } + async toggleAddAccountSnap(): Promise { console.log('Toggle Add Account Snap on experimental setting page'); await this.driver.clickElement(this.addAccountSnapToggle); @@ -45,9 +70,9 @@ class ExperimentalSettings { await this.driver.clickElement(this.redesignedSignatureToggle); } - async toggleRequestQueue(): Promise { - console.log('Toggle Request Queue on experimental setting page'); - await this.driver.clickElement(this.requestQueueToggle); + async toggleWatchAccount(): Promise { + console.log('Toggle Watch Account on experimental setting page'); + await this.driver.clickElement(this.watchAccountToggle); } } diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index 5155707663b6..5e86a7189dce 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -8,6 +8,11 @@ const DAPP_URL = `http://${DAPP_HOST_ADDRESS}`; class TestDapp { private driver: Driver; + private readonly addTokensToWalletButton = { + text: 'Add Token(s) to Wallet', + tag: 'button', + }; + private readonly confirmDepositButton = '[data-testid="confirm-footer-button"]'; @@ -38,6 +43,8 @@ class TestDapp { private readonly simpleSendButton = '#sendButton'; + private readonly erc20TokenAddresses = '#erc20TokenAddresses'; + private readonly erc721MintButton = '#mintButton'; private readonly erc721TransferFromButton = '#transferFromButton'; @@ -177,6 +184,11 @@ class TestDapp { private erc20TokenTransferButton = '#transferTokens'; + private createTokenButton = { + text: 'Create Token', + tag: 'button', + }; + constructor(driver: Driver) { this.driver = driver; } @@ -221,11 +233,21 @@ class TestDapp { }); } + public async clickAddTokenToWallet() { + await this.driver.clickElement(this.addTokensToWalletButton); + } + async clickSimpleSendButton() { + await this.driver.waitForSelector(this.simpleSendButton, { + state: 'enabled', + }); await this.driver.clickElement(this.simpleSendButton); } async clickERC721MintButton() { + await this.driver.waitForSelector(this.erc721MintButton, { + state: 'enabled', + }); await this.driver.clickElement(this.erc721MintButton); } @@ -273,26 +295,46 @@ class TestDapp { await this.driver.clickElement(this.erc20TokenTransferButton); } - /** - * Connect account to test dapp. - * - * @param publicAddress - The public address to connect to test dapp. - */ - async connectAccount(publicAddress: string) { - console.log('Connect account to test dapp'); - await this.driver.clickElement(this.connectAccountButton); + async confirmConnectAccountModal() { + console.log('Confirm connect account modal in notification window'); await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); await this.driver.waitForSelector(this.connectMetaMaskMessage); - await this.driver.clickElementAndWaitForWindowToClose( this.confirmDialogButton, ); await this.driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await this.driver.waitForSelector({ - css: this.connectedAccount, - text: publicAddress.toLowerCase(), - }); - await this.driver.waitForSelector(this.localhostNetworkMessage); + } + + /** + * Connect account to test dapp. + * + * @param options - Options for connecting account to test dapp. + * @param [options.connectAccountButtonEnabled] - Indicates if the connect account button should be enabled. + * @param options.publicAddress - The public address to connect to test dapp. + */ + async connectAccount({ + connectAccountButtonEnabled = true, + publicAddress, + }: { + connectAccountButtonEnabled?: boolean; + publicAddress?: string; + }) { + console.log('Connect account to test dapp'); + await this.driver.clickElement(this.connectAccountButton); + if (connectAccountButtonEnabled) { + await this.confirmConnectAccountModal(); + } else { + await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await this.driver.waitForSelector(this.connectMetaMaskMessage); + const confirmConnectDialogButton = await this.driver.findElement( + this.confirmDialogButton, + ); + assert.equal(await confirmConnectDialogButton.isEnabled(), false); + } + if (publicAddress) { + await this.check_connectedAccounts(publicAddress); + await this.driver.waitForSelector(this.localhostNetworkMessage); + } } async createDepositTransaction() { @@ -315,10 +357,43 @@ class TestDapp { await this.driver.clickElement(this.revokePermissionButton); await this.driver.refresh(); await this.check_pageIsLoaded(); - await this.driver.assertElementNotPresent({ - css: this.connectedAccount, - text: publicAddress.toLowerCase(), - }); + await this.check_connectedAccounts(publicAddress, false); + } + + /** + * Scrolls to the create token button and clicks it. + */ + public async findAndClickCreateToken() { + const createTokenElement = await this.driver.findElement( + this.createTokenButton, + ); + await this.driver.scrollToElement(createTokenElement); + await this.driver.clickElement(this.createTokenButton); + } + + /** + * Verifies the accounts connected to the test dapp. + * + * @param connectedAccounts - Account addresses to check if connected to test dapp, separated by a comma. + * @param shouldBeConnected - Whether the accounts should be connected to test dapp. Defaults to true. + */ + async check_connectedAccounts( + connectedAccounts: string, + shouldBeConnected: boolean = true, + ) { + if (shouldBeConnected) { + console.log('Verify connected accounts:', connectedAccounts); + await this.driver.waitForSelector({ + css: this.connectedAccount, + text: connectedAccounts.toLowerCase(), + }); + } else { + console.log('Verify accounts not connected:', connectedAccounts); + await this.driver.assertElementNotPresent({ + css: this.connectedAccount, + text: connectedAccounts.toLowerCase(), + }); + } } /** @@ -557,6 +632,24 @@ class TestDapp { }); } + /** + * Checks the count of token addresses. + * + * @param expectedCount - The expected count of token addresses. + */ + async check_TokenAddressesCount(expectedCount: number) { + console.log(`checking token addresses count: ${expectedCount}`); + await this.driver.wait(async () => { + const tokenAddressesElement = await this.driver.findElement( + this.erc20TokenAddresses, + ); + const tokenAddresses = await tokenAddressesElement.getText(); + const addresses = tokenAddresses.split(',').filter(Boolean); + + return addresses.length === expectedCount; + }, 10000); + } + async verify_successSignTypedDataV4Result(result: string) { await this.driver.waitForSelector({ css: this.signTypedDataV4Result, diff --git a/test/e2e/page-objects/pages/token-overview-page.ts b/test/e2e/page-objects/pages/token-overview-page.ts new file mode 100644 index 000000000000..46e93ed490c7 --- /dev/null +++ b/test/e2e/page-objects/pages/token-overview-page.ts @@ -0,0 +1,54 @@ +import { Driver } from '../../webdriver/driver'; + +class TokenOverviewPage { + private driver: Driver; + + private readonly receiveButton = { + text: 'Receive', + css: '.icon-button', + }; + + private readonly sendButton = { + text: 'Send', + css: '.icon-button', + }; + + private readonly swapButton = { + text: 'Swap', + css: '.icon-button', + }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.sendButton, + this.swapButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for Token overview page to be loaded', + e, + ); + throw e; + } + console.log('Token overview page is loaded'); + } + + async clickReceive(): Promise { + await this.driver.clickElement(this.receiveButton); + } + + async clickSend(): Promise { + await this.driver.clickElement(this.sendButton); + } + + async clickSwap(): Promise { + await this.driver.clickElement(this.swapButton); + } +} + +export default TokenOverviewPage; diff --git a/test/e2e/playwright/global/specs/protect-intrinsics.spec.ts b/test/e2e/playwright/global/specs/protect-intrinsics.spec.ts index 7f67cd587f2b..63091e9fe5cc 100644 --- a/test/e2e/playwright/global/specs/protect-intrinsics.spec.ts +++ b/test/e2e/playwright/global/specs/protect-intrinsics.spec.ts @@ -1,5 +1,4 @@ import { test, expect } from '@playwright/test'; -// @ts-expect-error lint fails otherwise import 'ses'; import '../../../../../app/scripts/lockdown-run'; import '../../../../../app/scripts/lockdown-more'; diff --git a/test/e2e/playwright/shared/pageObjects/network-controller-page.ts b/test/e2e/playwright/shared/pageObjects/network-controller-page.ts index cc496f2c9a36..e2116bcac676 100644 --- a/test/e2e/playwright/shared/pageObjects/network-controller-page.ts +++ b/test/e2e/playwright/shared/pageObjects/network-controller-page.ts @@ -24,8 +24,6 @@ export class NetworkController { readonly dismissBtn: Locator; - readonly networkList: Locator; - readonly networkListEdit: Locator; readonly rpcName: Locator; @@ -39,9 +37,6 @@ export class NetworkController { constructor(page: Page) { this.page = page; this.networkDisplay = this.page.getByTestId('network-display'); - this.networkList = this.page.getByTestId( - 'network-list-item-options-button-0x1', - ); this.networkListEdit = this.page.getByTestId( 'network-list-item-options-edit', ); @@ -69,9 +64,14 @@ export class NetworkController { }) { let rpcName = options.name; await this.networkDisplay.click(); - if (options.name === Tenderly.Mainnet.name) { + if ( + options.name === Tenderly.Mainnet.name || + options.name === Tenderly.Linea.name + ) { rpcName = options.rpcName; - await this.networkList.click(); + await this.page + .getByTestId(`network-list-item-options-button-${options.chainID}`) + .click(); await this.networkListEdit.click(); } else { await this.addNetworkButton.click(); @@ -82,7 +82,10 @@ export class NetworkController { await this.networkRpc.fill(options.url); await this.rpcName.fill(rpcName); await this.addURLBtn.click(); - if (options.name !== Tenderly.Mainnet.name) { + if ( + options.name !== Tenderly.Mainnet.name && + options.name !== Tenderly.Linea.name + ) { await this.networkChainId.fill(options.chainID); } await this.networkTicker.fill(options.symbol); diff --git a/test/e2e/playwright/shared/pageObjects/signup-page.ts b/test/e2e/playwright/shared/pageObjects/signup-page.ts index 28909f23ba20..692ca2ea70a4 100644 --- a/test/e2e/playwright/shared/pageObjects/signup-page.ts +++ b/test/e2e/playwright/shared/pageObjects/signup-page.ts @@ -49,6 +49,8 @@ export class SignUpPage { readonly skipSrpBackupBtn: Locator; + readonly popOverBtn: Locator; + constructor(page: Page) { this.page = page; this.getStartedBtn = page.locator('button:has-text("Get started")'); @@ -77,6 +79,7 @@ export class SignUpPage { this.nextBtn = page.getByTestId('pin-extension-next'); this.agreeBtn = page.locator('button:has-text("I agree")'); this.enableBtn = page.locator('button:has-text("Enable")'); + this.popOverBtn = page.getByTestId('popover-close'); } async importWallet() { @@ -114,5 +117,6 @@ export class SignUpPage { await this.gotItBtn.click(); await this.nextBtn.click(); await this.doneBtn.click(); + await this.popOverBtn.click(); } } diff --git a/test/e2e/playwright/swap/pageObjects/swap-page.ts b/test/e2e/playwright/swap/pageObjects/swap-page.ts index c10536d37f05..1daed72cbdf1 100644 --- a/test/e2e/playwright/swap/pageObjects/swap-page.ts +++ b/test/e2e/playwright/swap/pageObjects/swap-page.ts @@ -63,7 +63,12 @@ export class SwapPage { ); } - async enterQuote(options: { from?: string; to: string; qty: string }) { + async enterQuote(options: { + from?: string; + to: string; + qty: string; + checkBalance: boolean; + }) { // Enter source token const native = await this.page.$(`text=/${options.from}/`); if (!native && options.from) { @@ -75,7 +80,7 @@ export class SwapPage { .locator('[class*="balance"]') .first() .textContent(); - if (balanceString) { + if (balanceString && options.checkBalance) { if (parseFloat(balanceString.split(' ')[1]) <= parseFloat(options.qty)) { await this.goBack(); // not enough balance so cancel out @@ -84,6 +89,8 @@ export class SwapPage { } // Enter Swap Quantity + await this.page.waitForTimeout(1000); + await this.tokenQty.waitFor({ state: 'visible' }); await this.tokenQty.fill(options.qty); this.swapQty = options.qty; diff --git a/test/e2e/playwright/swap/specs/swap.spec.ts b/test/e2e/playwright/swap/specs/swap.spec.ts index ec9cd73858da..1a553293a5de 100644 --- a/test/e2e/playwright/swap/specs/swap.spec.ts +++ b/test/e2e/playwright/swap/specs/swap.spec.ts @@ -14,6 +14,7 @@ let swapPage: SwapPage; let networkController: NetworkController; let walletPage: WalletPage; let activityListPage: ActivityListPage; +let wallet: ethers.Wallet; const testSet = [ { @@ -23,6 +24,22 @@ const testSet = [ destination: 'DAI', network: Tenderly.Mainnet, }, + /* TODO: Skipping these tests as it returning no quote available + { + quantity: '.5', + source: 'ETH', + type: 'native', + destination: 'DAI', + network: Tenderly.Linea, + }, + { + quantity: '10', + source: 'DAI', + type: 'unapproved', + destination: 'USDC', + network: Tenderly.Linea, + }, + */ { quantity: '50', source: 'DAI', @@ -61,9 +78,6 @@ test.beforeAll( const page = await extension.initExtension(); page.setDefaultTimeout(15000); - const wallet = ethers.Wallet.createRandom(); - await addFundsToAccount(Tenderly.Mainnet.url, wallet.address); - const signUp = new SignUpPage(page); await signUp.createWallet(); @@ -71,13 +85,42 @@ test.beforeAll( swapPage = new SwapPage(page); activityListPage = new ActivityListPage(page); walletPage = new WalletPage(page); - - await networkController.addCustomNetwork(Tenderly.Mainnet); - await walletPage.importAccount(wallet.privateKey); - expect(walletPage.accountMenu).toHaveText('Account 2', { timeout: 30000 }); }, ); +// TODO: Skipping test as it's failing in the pipeline for unknown reasons +test.skip(`Get quote on Mainnet Network`, async () => { + await walletPage.selectSwapAction(); + await walletPage.page.waitForTimeout(3000); + await swapPage.enterQuote({ + from: 'ETH', + to: 'USDC', + qty: '.01', + checkBalance: false, + }); + await walletPage.page.waitForTimeout(3000); + const quoteFound = await swapPage.waitForQuote(); + expect(quoteFound).toBeTruthy(); + await swapPage.goBack(); +}); + +test(`Add Custom Networks and import test account`, async () => { + let response; + wallet = ethers.Wallet.createRandom(); + + response = await addFundsToAccount(Tenderly.Mainnet.url, wallet.address); + expect(response.error).toBeUndefined(); + + response = await addFundsToAccount(Tenderly.Linea.url, wallet.address); + expect(response.error).toBeUndefined(); + + await networkController.addCustomNetwork(Tenderly.Linea); + await networkController.addCustomNetwork(Tenderly.Mainnet); + + await walletPage.importAccount(wallet.privateKey); + expect(walletPage.accountMenu).toHaveText('Account 2', { timeout: 30000 }); +}); + testSet.forEach((options) => { test(`should swap ${options.type} token ${options.source} to ${options.destination} on ${options.network.name}'`, async () => { await walletPage.selectTokenWallet(); @@ -94,6 +137,7 @@ testSet.forEach((options) => { from: options.source, to: options.destination, qty: options.quantity, + checkBalance: true, }); if (quoteEntered) { diff --git a/test/e2e/playwright/swap/tenderly-network.ts b/test/e2e/playwright/swap/tenderly-network.ts index 996dee47a81a..26afb57cbab4 100644 --- a/test/e2e/playwright/swap/tenderly-network.ts +++ b/test/e2e/playwright/swap/tenderly-network.ts @@ -1,12 +1,11 @@ import axios from 'axios'; -import log from 'loglevel'; export const Tenderly = { Mainnet: { name: 'Ethereum Mainnet', rpcName: 'Tenderly - Mainnet', - url: 'https://virtual.mainnet.rpc.tenderly.co/03bb8912-7505-4856-839f-52819a26d0cd', - chainID: '1', + url: 'https://virtual.mainnet.rpc.tenderly.co/6a1cf1d8-3625-4ba0-b07e-c620d326ecb9', + chainID: '0x1', symbol: 'ETH', }, Optimism: { @@ -23,6 +22,13 @@ export const Tenderly = { chainID: '137', symbol: 'ETH', }, + Linea: { + name: 'Linea', + rpcName: '', + url: 'https://virtual.linea.rpc.tenderly.co/76ec2678-5c4e-4cd8-baa0-8d3dea738645', + chainID: '0xe708', + symbol: 'ETH', + }, }; export async function addFundsToAccount( @@ -42,9 +48,5 @@ export async function addFundsToAccount( }, }); - if (response.data.error) { - log.error( - `\tERROR: RROR: Failed to add funds to Tenderly VirtualTestNet\n${response.data.error}`, - ); - } + return response.data; } diff --git a/test/e2e/restore/MetaMaskUserData.json b/test/e2e/restore/MetaMaskUserData.json index 7a687ec254c0..6f08305db357 100644 --- a/test/e2e/restore/MetaMaskUserData.json +++ b/test/e2e/restore/MetaMaskUserData.json @@ -40,7 +40,6 @@ }, "theme": "light", "useBlockie": false, - "useRequestQueue": true, "useNftDetection": false, "useNonceField": false, "usePhishDetect": true, diff --git a/test/e2e/seeder/ganache.ts b/test/e2e/seeder/ganache.ts index 7fa3d1ab0238..d262924ab61e 100644 --- a/test/e2e/seeder/ganache.ts +++ b/test/e2e/seeder/ganache.ts @@ -76,6 +76,13 @@ export class Ganache { }); } + async mineBlock() { + return await this.getProvider()?.request({ + method: 'evm_mine', + params: [], + }); + } + async quit() { if (!this.#server) { throw new Error('Server not running yet'); diff --git a/test/e2e/snaps/enums.js b/test/e2e/snaps/enums.js index c17c4bd9eff7..8ac5dacd1f73 100644 --- a/test/e2e/snaps/enums.js +++ b/test/e2e/snaps/enums.js @@ -1,3 +1,3 @@ module.exports = { - TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/snaps/test-snaps/2.15.4', + TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/snaps/test-snaps/2.18.0', }; diff --git a/test/e2e/snaps/test-snap-cronjob.spec.js b/test/e2e/snaps/test-snap-cronjob.spec.js index 5fbc22d7ad71..73362b9df3ca 100644 --- a/test/e2e/snaps/test-snap-cronjob.spec.js +++ b/test/e2e/snaps/test-snap-cronjob.spec.js @@ -52,6 +52,8 @@ describe('Test Snap Cronjob', function () { tag: 'button', }); + await driver.clickElementSafe('[data-testid="snap-install-scroll"]'); + // wait for and click confirm await driver.waitForSelector({ text: 'Confirm' }); await driver.clickElement({ diff --git a/test/e2e/snaps/test-snap-ethprovider.spec.js b/test/e2e/snaps/test-snap-ethprovider.spec.js index 0e5ea68a09eb..0d4492d1fcc4 100644 --- a/test/e2e/snaps/test-snap-ethprovider.spec.js +++ b/test/e2e/snaps/test-snap-ethprovider.spec.js @@ -116,11 +116,44 @@ describe('Test Snap ethereum_provider', function () { // switch to test snap page await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - // check the results of the message signature using waitForSelector + // check the results of the account selection using waitForSelector await driver.waitForSelector({ css: '#ethproviderResult', text: '"0x5cfe73b6021e818b776b421b1c4db2474086a7e1"', }); + + // Test personal_sign + await driver.pasteIntoField('#personalSignMessage', 'foo'); + await driver.clickElement('#signPersonalSignMessage'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Confirm', + tag: 'button', + }); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); + await driver.waitForSelector({ + css: '#personalSignResult', + text: '"0xf63c587cd42e7775e2e815a579f9744ea62944f263b3e69fad48535ba98a5ea107bc878088a99942733a59a89ef1d590eafdb467d59cf76564158d7e78351b751b"', + }); + + // Test eth_signTypedData + await driver.pasteIntoField('#signTypedData', 'bar'); + await driver.clickElement('#signTypedDataButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElementSafe('.confirm-scroll-to-bottom__button'); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Confirm', + tag: 'button', + }); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); + await driver.waitForSelector({ + css: '#signTypedDataResult', + text: '"0x18d05f8139ad66d581fb658aca4d41950c6f38a8daeb3adfdb18614e645bf73508a4c24d4fc4026b5d447d223fcf026a32947846205f663c536df8a7b4d841fe1c"', + }); }, ); }); diff --git a/test/e2e/snaps/test-snap-managestate.spec.js b/test/e2e/snaps/test-snap-managestate.spec.js index 4d6a58faa678..0ecdb1291da8 100644 --- a/test/e2e/snaps/test-snap-managestate.spec.js +++ b/test/e2e/snaps/test-snap-managestate.spec.js @@ -8,7 +8,152 @@ const FixtureBuilder = require('../fixture-builder'); const { TEST_SNAPS_WEBSITE_URL } = require('./enums'); describe('Test Snap manageState', function () { - it('can pop up manageState snap and do update get and clear', async function () { + it('can use the new state API', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // navigate to test snaps page, then fill in the snapId + await driver.driver.get(TEST_SNAPS_WEBSITE_URL); + + // wait for page to load + await driver.waitForSelector({ + text: 'Installed Snaps', + tag: 'h2', + }); + + // scroll to manage-state snap + const snapButton1 = await driver.findElement('#connectstate'); + await driver.scrollToElement(snapButton1); + + // added delay for firefox (deflake) + await driver.delayFirefox(1000); + + // wait for and click connect + await driver.waitForSelector('#connectstate'); + await driver.clickElement('#connectstate'); + + // switch to metamask extension + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // wait for and click connect + await driver.waitForSelector({ + text: 'Connect', + tag: 'button', + }); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + // wait for and click confirm + await driver.waitForSelector({ text: 'Confirm' }); + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + }); + + // wait for and click ok and wait for window to close + await driver.waitForSelector({ text: 'OK' }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'OK', + tag: 'button', + }); + + // fill and click send inputs on test snap page + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); + + // wait for npm installation success + await driver.waitForSelector({ + css: '#connectstate', + text: 'Reconnect to State Snap', + }); + + // Enter data and click set + const sendEncrypted = await driver.findElement('#setStateKey'); + await driver.scrollToElement(sendEncrypted); + await driver.delayFirefox(1000); + await driver.pasteIntoField('#setStateKey', 'foo'); + await driver.pasteIntoField('#dataState', '"bar"'); + await driver.clickElement('#sendState'); + + // Check that the entire state blob was updated + await driver.waitForSelector({ + css: '#encryptedStateResult', + text: JSON.stringify({ foo: 'bar' }, null, 2), + }); + + // Check that we can retrieve one state key + const getKeyField = await driver.findElement('#getState'); + await driver.scrollToElement(getKeyField); + await driver.delayFirefox(1000); + await driver.pasteIntoField('#getState', 'foo'); + await driver.clickElement('#sendGetState'); + + await driver.waitForSelector({ + css: '#getStateResult', + text: '"bar"', + }); + + // click clear results + await driver.clickElement('#clearState'); + + // check result array is empty + await driver.waitForSelector({ + css: '#encryptedStateResult', + text: 'null', + }); + + // repeat the same above steps to check unencrypted state management + + // Enter data and click set + const sendUnencrypted = await driver.findElement( + '#setStateKeyUnencrypted', + ); + await driver.scrollToElement(sendUnencrypted); + await driver.delayFirefox(1000); + await driver.pasteIntoField('#setStateKeyUnencrypted', 'foo'); + await driver.pasteIntoField('#dataUnencryptedState', '"bar"'); + await driver.clickElement('#sendUnencryptedState'); + + // Check that the entire state blob was updated + await driver.waitForSelector({ + css: '#unencryptedStateResult', + text: JSON.stringify({ foo: 'bar' }, null, 2), + }); + + // Check that we can retrive one state key + const getUnencryptedKeyField = await driver.findElement( + '#getUnencryptedState', + ); + await driver.scrollToElement(getUnencryptedKeyField); + await driver.delayFirefox(1000); + await driver.pasteIntoField('#getUnencryptedState', 'foo'); + await driver.clickElement('#sendGetUnencryptedState'); + + await driver.waitForSelector({ + css: '#getStateUnencryptedResult', + text: '"bar"', + }); + + // click clear results + await driver.clickElement('#clearStateUnencrypted'); + + // check result array is empty + await driver.waitForSelector({ + css: '#unencryptedStateResult', + text: 'null', + }); + }, + ); + }); + + it('can use the legacy state API', async function () { await withFixtures( { fixtures: new FixtureBuilder().build(), @@ -71,7 +216,7 @@ describe('Test Snap manageState', function () { // wait for npm installation success await driver.waitForSelector({ css: '#connectmanage-state', - text: 'Reconnect to Manage State Snap', + text: 'Reconnect to Legacy State Snap', }); // enter data and click send managestate diff --git a/test/e2e/snaps/test-snap-metrics.spec.js b/test/e2e/snaps/test-snap-metrics.spec.js index 0b3ef8db2bf6..934bda718d43 100644 --- a/test/e2e/snaps/test-snap-metrics.spec.js +++ b/test/e2e/snaps/test-snap-metrics.spec.js @@ -245,7 +245,7 @@ describe('Test Snap Metrics', function () { assert.deepStrictEqual(events[1].properties, { snap_id: 'npm:@metamask/notification-example-snap', origin: 'https://metamask.github.io', - version: '2.2.0', + version: '2.3.0', category: 'Snaps', locale: 'en', chain_id: '0x539', @@ -545,7 +545,7 @@ describe('Test Snap Metrics', function () { const events = await getEventPayloads(driver, mockedEndpoints); assert.deepStrictEqual(events[0].properties, { snap_id: 'npm:@metamask/notification-example-snap', - version: '2.2.0', + version: '2.3.0', category: 'Snaps', locale: 'en', chain_id: '0x539', diff --git a/test/e2e/snaps/test-snap-siginsights.spec.js b/test/e2e/snaps/test-snap-siginsights.spec.js index c463d09d864a..3f90b7d56e28 100644 --- a/test/e2e/snaps/test-snap-siginsights.spec.js +++ b/test/e2e/snaps/test-snap-siginsights.spec.js @@ -175,8 +175,13 @@ describe('Test Snap Signature Insights', function () { // switch back to MetaMask window and switch to tx insights pane await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector( + '[data-testid="signature-request-scroll-button"]', + ); // click down arrow - await driver.clickElementSafe('.fa-arrow-down'); + await driver.clickElementSafe( + '[data-testid="signature-request-scroll-button"]', + ); // wait for and click sign await clickSignOnSignatureConfirmation({ @@ -223,7 +228,12 @@ describe('Test Snap Signature Insights', function () { await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); // click down arrow - await driver.clickElementSafe('.fa-arrow-down'); + await driver.waitForSelector( + '[data-testid="signature-request-scroll-button"]', + ); + await driver.clickElementSafe( + '[data-testid="signature-request-scroll-button"]', + ); // wait for and click sign await clickSignOnSignatureConfirmation({ diff --git a/test/e2e/snaps/test-snap-txinsights-v2.spec.js b/test/e2e/snaps/test-snap-txinsights-v2.spec.js deleted file mode 100644 index ba2d468a870a..000000000000 --- a/test/e2e/snaps/test-snap-txinsights-v2.spec.js +++ /dev/null @@ -1,174 +0,0 @@ -const { - defaultGanacheOptions, - withFixtures, - unlockWallet, - WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); -const { TEST_SNAPS_WEBSITE_URL } = require('./enums'); - -describe('Test Snap TxInsights-v2', function () { - describe('Old confirmation screens', function () { - it('tests tx insights v2 functionality', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // navigate to test snaps page and connect - await driver.openNewPage(TEST_SNAPS_WEBSITE_URL); - - // wait for page to load - await driver.waitForSelector({ - text: 'Installed Snaps', - tag: 'h2', - }); - - // find and scroll to the transaction-insights test snap - const snapButton1 = await driver.findElement( - '#connecttransaction-insights', - ); - await driver.scrollToElement(snapButton1); - - // added delay for firefox (deflake) - await driver.delayFirefox(1000); - - // wait for and click connect - await driver.waitForSelector('#connecttransaction-insights'); - await driver.clickElement('#connecttransaction-insights'); - - // switch to metamask extension - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click connect - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // wait for and click connect - await driver.waitForSelector({ text: 'Confirm' }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - - // wait for and click ok and wait for window to close - await driver.waitForSelector({ text: 'OK' }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'OK', - tag: 'button', - }); - - // switch to test-snaps page - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - - // wait for and click get accounts - await driver.waitForSelector('#getAccounts'); - await driver.clickElement('#getAccounts'); - - // switch back to MetaMask window - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click confirm and wait for window to close - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // switch to test-snaps page and send tx - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - await driver.clickElement('#sendInsights'); - - // delay added for rendering (deflake) - await driver.delay(2000); - - // switch back to MetaMask window and switch to tx insights pane - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // find confirm button - await driver.findClickableElement({ - text: 'Confirm', - tag: 'button', - }); - - // wait for and click insights snap tab - await driver.waitForSelector({ - text: 'Insights Example Snap', - tag: 'button', - }); - await driver.clickElement({ - text: 'Insights Example Snap', - tag: 'button', - }); - - // check that txinsightstest tab contains the right info - await driver.waitForSelector({ - css: '.snap-ui-renderer__content', - text: 'ERC-20', - }); - - // click confirm to continue - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - - // check for warning from txinsights - await driver.waitForSelector({ - css: '.snap-delineator__header__text', - text: 'Warning from Insights Example Snap', - }); - - // check info in warning - await driver.waitForSelector({ - css: '.snap-ui-renderer__text', - text: 'ERC-20', - }); - - // click the warning confirm checkbox - await driver.clickElement('.mm-checkbox__input'); - - // click confirm button to send transaction - await driver.clickElement({ - css: '.mm-box--color-error-inverse', - text: 'Confirm', - tag: 'button', - }); - - // switch back to MetaMask tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // switch to activity pane - await driver.clickElement({ - tag: 'button', - text: 'Activity', - }); - - // wait for transaction confirmation - await driver.waitForSelector({ - css: '.transaction-status-label', - text: 'Confirmed', - }); - }, - ); - }); - }); -}); diff --git a/test/e2e/snaps/test-snap-txinsights.spec.js b/test/e2e/snaps/test-snap-txinsights.spec.js index 0171759587b5..c599bb124c52 100644 --- a/test/e2e/snaps/test-snap-txinsights.spec.js +++ b/test/e2e/snaps/test-snap-txinsights.spec.js @@ -3,229 +3,113 @@ const { withFixtures, unlockWallet, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); const { TEST_SNAPS_WEBSITE_URL } = require('./enums'); describe('Test Snap TxInsights', function () { - describe('Old confirmation screens', function () { - it('tests tx insights functionality', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // navigate to test snaps page and connect - await driver.driver.get(TEST_SNAPS_WEBSITE_URL); - - // wait for page to load - await driver.waitForSelector({ - text: 'Installed Snaps', - tag: 'h2', - }); - - // find and scroll to the transaction-insights test snap - const snapButton1 = await driver.findElement( - '#connecttransaction-insights', - ); - await driver.scrollToElement(snapButton1); - - // added delay for firefox (deflake) - await driver.delayFirefox(1000); - - // wait for and click connect - await driver.waitForSelector('#connecttransaction-insights'); - await driver.clickElement('#connecttransaction-insights'); - - // switch to metamask extension - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click connect - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // wait for and click confirm - await driver.waitForSelector({ text: 'Confirm' }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - - // wait for and click ok and wait for window to close - await driver.waitForSelector({ text: 'OK' }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'OK', - tag: 'button', - }); - - // switch to test-snaps page and get accounts - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - - // click get accounts - await driver.clickElement('#getAccounts'); - - // switch back to MetaMask window - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click next and wait for window to close - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // switch to test-snaps page - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - - // click send tx - await driver.clickElement('#sendInsights'); - - // delay added for rendering (deflake) - await driver.delay(2000); - - // switch back to MetaMask window - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and switch to insight snap pane - await driver.waitForSelector({ - text: 'Insights Example Snap', - tag: 'button', - }); - await driver.clickElement({ - text: 'Insights Example Snap', - tag: 'button', - }); - - // check that txinsightstest tab contains the right info - await driver.waitForSelector({ - css: '.snap-ui-renderer__content', - text: 'ERC-20', - }); - }, - ); - }); - }); - - describe('Redesigned confirmation screens', function () { - it('tests tx insights functionality', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // navigate to test snaps page and connect - await driver.driver.get(TEST_SNAPS_WEBSITE_URL); - - // wait for page to load - await driver.waitForSelector({ - text: 'Installed Snaps', - tag: 'h2', - }); - - // find and scroll to the transaction-insights test snap - const snapButton1 = await driver.findElement( - '#connecttransaction-insights', - ); - await driver.scrollToElement(snapButton1); - - // added delay for firefox (deflake) - await driver.delayFirefox(1000); - - // wait for and click connect - await driver.waitForSelector('#connecttransaction-insights'); - await driver.clickElement('#connecttransaction-insights'); - - // switch to metamask extension - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click connect - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // wait for and click confirm - await driver.waitForSelector({ text: 'Confirm' }); - await driver.clickElement({ - text: 'Confirm', - tag: 'button', - }); - - // wait for and click ok and wait for window to close - await driver.waitForSelector({ text: 'OK' }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'OK', - tag: 'button', - }); - - // switch to test-snaps page and get accounts - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - - // click get accounts - await driver.clickElement('#getAccounts'); - - // switch back to MetaMask window - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and click next and wait for window to close - await driver.waitForSelector({ - text: 'Connect', - tag: 'button', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // switch to test-snaps page - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); - - // click send tx - await driver.clickElement('#sendInsights'); - - // delay added for rendering (deflake) - await driver.delay(2000); - - // switch back to MetaMask window - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for and switch to insight snap pane - await driver.waitForSelector({ - text: 'Insights Example Snap', - tag: 'span', - }); - - // check that txinsightstest tab contains the right info - await driver.waitForSelector({ - css: 'p', - text: 'ERC-20', - }); - }, - ); - }); + it('tests tx insights functionality', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // navigate to test snaps page and connect + await driver.driver.get(TEST_SNAPS_WEBSITE_URL); + + // wait for page to load + await driver.waitForSelector({ + text: 'Installed Snaps', + tag: 'h2', + }); + + // find and scroll to the transaction-insights test snap + const snapButton1 = await driver.findElement( + '#connecttransaction-insights', + ); + await driver.scrollToElement(snapButton1); + + // added delay for firefox (deflake) + await driver.delayFirefox(1000); + + // wait for and click connect + await driver.waitForSelector('#connecttransaction-insights'); + await driver.clickElement('#connecttransaction-insights'); + + // switch to metamask extension + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // wait for and click connect + await driver.waitForSelector({ + text: 'Connect', + tag: 'button', + }); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + // wait for and click confirm + await driver.waitForSelector({ text: 'Confirm' }); + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + }); + + // wait for and click ok and wait for window to close + await driver.waitForSelector({ text: 'OK' }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'OK', + tag: 'button', + }); + + // switch to test-snaps page and get accounts + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); + + // click get accounts + await driver.clickElement('#getAccounts'); + + // switch back to MetaMask window + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // wait for and click next and wait for window to close + await driver.waitForSelector({ + text: 'Connect', + tag: 'button', + }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // switch to test-snaps page + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestSnaps); + + // click send tx + await driver.clickElement('#sendInsights'); + + // delay added for rendering (deflake) + await driver.delay(2000); + + // switch back to MetaMask window + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // wait for and switch to insight snap pane + await driver.waitForSelector({ + text: 'Insights Example Snap', + tag: 'span', + }); + + // check that txinsightstest tab contains the right info + await driver.waitForSelector({ + css: 'p', + text: 'ERC-20', + }); + }, + ); }); }); diff --git a/test/e2e/tests/account/account-custom-name.spec.ts b/test/e2e/tests/account/account-custom-name.spec.ts index 4c0ecbe196f9..92302e032224 100644 --- a/test/e2e/tests/account/account-custom-name.spec.ts +++ b/test/e2e/tests/account/account-custom-name.spec.ts @@ -1,8 +1,10 @@ import { Suite } from 'mocha'; import { Driver } from '../../webdriver/driver'; import { withFixtures } from '../../helpers'; +import { ACCOUNT_TYPE } from '../../constants'; import FixtureBuilder from '../../fixture-builder'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; +import AccountDetailsModal from '../../page-objects/pages/dialog/account-details-modal'; import AccountListPage from '../../page-objects/pages/account-list-page'; import HeaderNavbar from '../../page-objects/pages/header-navbar'; @@ -25,14 +27,20 @@ describe('Account Custom Name Persistence', function (this: Suite) { // Change account label for existing account and verify edited account label const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - await accountListPage.openAccountOptionsMenu(); - await accountListPage.changeAccountLabel(newAccountLabel); + await accountListPage.openAccountDetailsModal('Account 1'); + + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + await accountDetailsModal.changeAccountLabel(newAccountLabel); await headerNavbar.check_accountLabel(newAccountLabel); // Add new account with custom label and verify new added account label await headerNavbar.openAccountMenu(); await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewAccount(anotherAccountLabel); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: anotherAccountLabel, + }); await headerNavbar.check_accountLabel(anotherAccountLabel); // Switch back to the first account and verify first custom account persists diff --git a/test/e2e/tests/account/add-account.spec.ts b/test/e2e/tests/account/add-account.spec.ts index db62927b91d7..ea0a52ed5f83 100644 --- a/test/e2e/tests/account/add-account.spec.ts +++ b/test/e2e/tests/account/add-account.spec.ts @@ -1,17 +1,14 @@ import { E2E_SRP } from '../../default-fixture'; import FixtureBuilder from '../../fixture-builder'; +import { ACCOUNT_TYPE } from '../../constants'; import { WALLET_PASSWORD, defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, withFixtures, } from '../../helpers'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; import { completeImportSRPOnboardingFlow } from '../../page-objects/flows/onboarding.flow'; -import { - sendRedesignedTransactionToAccount, - sendTransactionToAccount, -} from '../../page-objects/flows/send-transaction.flow'; +import { sendRedesignedTransactionToAccount } from '../../page-objects/flows/send-transaction.flow'; import AccountListPage from '../../page-objects/pages/account-list-page'; import ActivityListPage from '../../page-objects/pages/home/activity-list'; import HeaderNavbar from '../../page-objects/pages/header-navbar'; @@ -20,189 +17,118 @@ import LoginPage from '../../page-objects/pages/login-page'; import ResetPasswordPage from '../../page-objects/pages/reset-password-page'; describe('Add account', function () { - describe('Old confirmation screens', function () { - it('should not affect public address when using secret recovery phrase to recover account with non-zero balance @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder({ onboarding: true }).build(), - ganacheOptions: defaultGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await completeImportSRPOnboardingFlow({ driver }); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - const homePage = new HomePage(driver); - await homePage.check_pageIsLoaded(); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.openAccountMenu(); - - // Create new account with default name `newAccountName` - const newAccountName = 'Account 2'; - const accountListPage = new AccountListPage(driver); - await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewAccount(); - await headerNavbar.check_accountLabel(newAccountName); - await homePage.check_expectedBalanceIsDisplayed(); - - // Switch back to the first account and transfer some balance to 2nd account so they will not be removed after recovering SRP - await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); - await accountListPage.check_accountDisplayedInAccountList( - 'Account 1', - ); - await accountListPage.switchToAccount('Account 1'); - await headerNavbar.check_accountLabel('Account 1'); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - await sendTransactionToAccount({ - driver, - recipientAccount: newAccountName, - amount: '2.8', - gasFee: '0.000042', - totalFee: '2.800042', - }); - await homePage.check_pageIsLoaded(); - const activityList = new ActivityListPage(driver); - await activityList.check_confirmedTxNumberDisplayedInActivity(); - await activityList.check_txAmountInActivity('-2.8 ETH'); - - // Lock wallet and recover via SRP in "forget password" option - await headerNavbar.lockMetaMask(); - await new LoginPage(driver).gotoResetPasswordPage(); - const resetPasswordPage = new ResetPasswordPage(driver); - await resetPasswordPage.check_pageIsLoaded(); - await resetPasswordPage.resetPassword(E2E_SRP, WALLET_PASSWORD); - - // Check wallet balance for both accounts - await homePage.check_pageIsLoaded(); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); - await accountListPage.check_accountDisplayedInAccountList( - newAccountName, - ); - await accountListPage.switchToAccount(newAccountName); - await headerNavbar.check_accountLabel(newAccountName); - await homePage.check_expectedBalanceIsDisplayed('2.8'); - }, - ); - }); + it('should not affect public address when using secret recovery phrase to recover account with non-zero balance @no-mmi', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder({ onboarding: true }).build(), + ganacheOptions: defaultGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await completeImportSRPOnboardingFlow({ driver }); + + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.openAccountMenu(); + + // Create new account with default name `newAccountName` + const newAccountName = 'Account 2'; + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + }); + await headerNavbar.check_accountLabel(newAccountName); + await homePage.check_expectedBalanceIsDisplayed(); + + // Switch back to the first account and transfer some balance to 2nd account so they will not be removed after recovering SRP + await headerNavbar.openAccountMenu(); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_accountDisplayedInAccountList('Account 1'); + await accountListPage.switchToAccount('Account 1'); + await headerNavbar.check_accountLabel('Account 1'); + await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); + + await sendRedesignedTransactionToAccount({ + driver, + recipientAccount: newAccountName, + amount: '2.8', + }); + + await homePage.check_pageIsLoaded(); + const activityList = new ActivityListPage(driver); + await activityList.check_confirmedTxNumberDisplayedInActivity(); + await activityList.check_txAmountInActivity('-2.8 ETH'); + + // Lock wallet and recover via SRP in "forget password" option + await headerNavbar.lockMetaMask(); + await new LoginPage(driver).gotoResetPasswordPage(); + const resetPasswordPage = new ResetPasswordPage(driver); + await resetPasswordPage.check_pageIsLoaded(); + await resetPasswordPage.resetPassword(E2E_SRP, WALLET_PASSWORD); + + // Check wallet balance for both accounts + await homePage.check_pageIsLoaded(); + await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); + await headerNavbar.openAccountMenu(); + await accountListPage.check_pageIsLoaded(); + await accountListPage.check_accountDisplayedInAccountList( + newAccountName, + ); + await accountListPage.switchToAccount(newAccountName); + await headerNavbar.check_accountLabel(newAccountName); + await homePage.check_expectedBalanceIsDisplayed('2.8'); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should not affect public address when using secret recovery phrase to recover account with non-zero balance @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder({ onboarding: true }).build(), - ganacheOptions: defaultGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await completeImportSRPOnboardingFlow({ driver }); - - const homePage = new HomePage(driver); - await homePage.check_pageIsLoaded(); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.openAccountMenu(); - - // Create new account with default name `newAccountName` - const newAccountName = 'Account 2'; - const accountListPage = new AccountListPage(driver); - await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewAccount(); - await headerNavbar.check_accountLabel(newAccountName); - await homePage.check_expectedBalanceIsDisplayed(); - - // Switch back to the first account and transfer some balance to 2nd account so they will not be removed after recovering SRP - await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); - await accountListPage.check_accountDisplayedInAccountList( - 'Account 1', - ); - await accountListPage.switchToAccount('Account 1'); - await headerNavbar.check_accountLabel('Account 1'); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - - await sendRedesignedTransactionToAccount({ - driver, - recipientAccount: newAccountName, - amount: '2.8', - }); - - await homePage.check_pageIsLoaded(); - const activityList = new ActivityListPage(driver); - await activityList.check_confirmedTxNumberDisplayedInActivity(); - await activityList.check_txAmountInActivity('-2.8 ETH'); - - // Lock wallet and recover via SRP in "forget password" option - await headerNavbar.lockMetaMask(); - await new LoginPage(driver).gotoResetPasswordPage(); - const resetPasswordPage = new ResetPasswordPage(driver); - await resetPasswordPage.check_pageIsLoaded(); - await resetPasswordPage.resetPassword(E2E_SRP, WALLET_PASSWORD); - - // Check wallet balance for both accounts - await homePage.check_pageIsLoaded(); - await homePage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - await headerNavbar.openAccountMenu(); - await accountListPage.check_pageIsLoaded(); - await accountListPage.check_accountDisplayedInAccountList( - newAccountName, - ); - await accountListPage.switchToAccount(newAccountName); - await headerNavbar.check_accountLabel(newAccountName); - await homePage.check_expectedBalanceIsDisplayed('2.8'); - }, - ); - }); - - it('should be possible to remove an account imported with a private key, but should not be possible to remove an account generated from the SRP imported in onboarding @no-mmi', async function () { - const testPrivateKey: string = - '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'; - - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - title: this.test?.fullTitle(), - }, - async ({ driver }) => { - await loginWithBalanceValidation(driver); - const headerNavbar = new HeaderNavbar(driver); - const homePage = new HomePage(driver); - await headerNavbar.openAccountMenu(); - - // Create new account with default name Account 2 - const accountListPage = new AccountListPage(driver); - await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewAccount(); - await headerNavbar.check_accountLabel('Account 2'); - await homePage.check_expectedBalanceIsDisplayed(); - - // Check user cannot delete 2nd account generated from the SRP imported in onboarding - await headerNavbar.openAccountMenu(); - await accountListPage.check_removeAccountButtonIsNotDisplayed( - 'Account 1', - ); - - // Create 3rd account with private key - await accountListPage.addNewImportedAccount(testPrivateKey); - await headerNavbar.check_accountLabel('Account 3'); - await homePage.check_expectedBalanceIsDisplayed(); - - // Remove the 3rd account imported with a private key - await headerNavbar.openAccountMenu(); - await accountListPage.removeAccount('Account 3'); - await homePage.check_pageIsLoaded(); - await homePage.check_expectedBalanceIsDisplayed(); - await headerNavbar.openAccountMenu(); - await accountListPage.check_accountIsNotDisplayedInAccountList( - 'Account 3', - ); - }, - ); - }); + it('should be possible to remove an account imported with a private key, but should not be possible to remove an account generated from the SRP imported in onboarding @no-mmi', async function () { + const testPrivateKey: string = + '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'; + + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + title: this.test?.fullTitle(), + }, + async ({ driver }) => { + await loginWithBalanceValidation(driver); + const headerNavbar = new HeaderNavbar(driver); + const homePage = new HomePage(driver); + await headerNavbar.openAccountMenu(); + + // Create new account with default name Account 2 + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + }); + await headerNavbar.check_accountLabel('Account 2'); + await homePage.check_expectedBalanceIsDisplayed(); + + // Check user cannot delete 2nd account generated from the SRP imported in onboarding + await headerNavbar.openAccountMenu(); + await accountListPage.check_removeAccountButtonIsNotDisplayed( + 'Account 1', + ); + + // Create 3rd account with private key + await accountListPage.addNewImportedAccount(testPrivateKey); + await headerNavbar.check_accountLabel('Account 3'); + await homePage.check_expectedBalanceIsDisplayed(); + + // Remove the 3rd account imported with a private key + await headerNavbar.openAccountMenu(); + await accountListPage.removeAccount('Account 3'); + await homePage.check_pageIsLoaded(); + await homePage.check_expectedBalanceIsDisplayed(); + await headerNavbar.openAccountMenu(); + await accountListPage.check_accountIsNotDisplayedInAccountList( + 'Account 3', + ); + }, + ); }); }); diff --git a/test/e2e/tests/account/import-flow.spec.ts b/test/e2e/tests/account/import-flow.spec.ts index dbb7b2f85d49..c8ffcc334e49 100644 --- a/test/e2e/tests/account/import-flow.spec.ts +++ b/test/e2e/tests/account/import-flow.spec.ts @@ -3,6 +3,7 @@ import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants'; import { withFixtures } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; import AccountListPage from '../../page-objects/pages/account-list-page'; +import AccountDetailsModal from '../../page-objects/pages/dialog/account-details-modal'; import HeaderNavbar from '../../page-objects/pages/header-navbar'; import HomePage from '../../page-objects/pages/home/homepage'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; @@ -32,7 +33,9 @@ describe('Import flow @no-mmi', function () { const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); await accountListPage.openAccountDetailsModal('Account 1'); - await accountListPage.check_addressInAccountDetailsModal( + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + await accountDetailsModal.check_addressInAccountDetailsModal( DEFAULT_FIXTURE_ACCOUNT.toLowerCase(), ); }, diff --git a/test/e2e/tests/account/snap-account-signatures-and-disconnects.spec.ts b/test/e2e/tests/account/snap-account-signatures-and-disconnects.spec.ts index 7e355302212a..d3c177ff7fdd 100644 --- a/test/e2e/tests/account/snap-account-signatures-and-disconnects.spec.ts +++ b/test/e2e/tests/account/snap-account-signatures-and-disconnects.spec.ts @@ -56,7 +56,9 @@ describe('Snap Account Signatures and Disconnects @no-mmi', function (this: Suit // Disconnect from Test Dapp and reconnect to Test Dapp await testDapp.disconnectAccount(newPublicKey); - await testDapp.connectAccount(newPublicKey); + await testDapp.connectAccount({ + publicAddress: newPublicKey, + }); // SignTypedDataV4 with Test Dapp await signTypedDataV4WithSnapAccount(driver, newPublicKey, false, true); diff --git a/test/e2e/tests/account/snap-account-transfers.spec.ts b/test/e2e/tests/account/snap-account-transfers.spec.ts index d6ebff34d642..2a0aa78e9825 100644 --- a/test/e2e/tests/account/snap-account-transfers.spec.ts +++ b/test/e2e/tests/account/snap-account-transfers.spec.ts @@ -2,7 +2,6 @@ import { Suite } from 'mocha'; import { multipleGanacheOptions, PRIVATE_KEY_TWO, - tempToggleSettingRedesignedTransactionConfirmations, WINDOW_TITLES, withFixtures, } from '../../helpers'; @@ -17,313 +16,149 @@ import HomePage from '../../page-objects/pages/home/homepage'; import SnapSimpleKeyringPage from '../../page-objects/pages/snap-simple-keyring-page'; import { installSnapSimpleKeyring } from '../../page-objects/flows/snap-simple-keyring.flow'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; -import { - sendRedesignedTransactionWithSnapAccount, - sendTransactionWithSnapAccount, -} from '../../page-objects/flows/send-transaction.flow'; +import { sendRedesignedTransactionWithSnapAccount } from '../../page-objects/flows/send-transaction.flow'; describe('Snap Account Transfers @no-mmi', function (this: Suite) { - // TODO: Remove the old confirmations screen tests once migration has been complete. - // See: https://github.com/MetaMask/MetaMask-planning/issues/3030 - describe('Old confirmation screens', function () { - it('can import a private key and transfer 1 ETH (sync flow)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ + it('can import a private key and transfer 1 ETH (sync flow)', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: multipleGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ + driver, + ganacheServer, + }: { + driver: Driver; + ganacheServer?: Ganache; + }) => { + await loginWithBalanceValidation(driver, ganacheServer); + + await installSnapSimpleKeyring(driver); + const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); + + // import snap account with private key on snap simple keyring page. + await snapSimpleKeyringPage.importAccountWithPrivateKey( + PRIVATE_KEY_TWO, + ); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel('SSK Account'); + + // send 1 ETH from snap account to account 1 + await sendRedesignedTransactionWithSnapAccount({ driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await installSnapSimpleKeyring(driver); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 - await sendTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - gasFee: '0.000042', - totalFee: '1.000042', - }); - await headerNavbar.check_pageIsLoaded(); - await headerNavbar.openAccountMenu(); - const accountList = new AccountListPage(driver); - await accountList.check_pageIsLoaded(); - - // check the balance of the 2 accounts are updated - await accountList.check_accountBalanceDisplayed('26'); - await accountList.check_accountBalanceDisplayed('24'); - }, - ); - }); - - it('can import a private key and transfer 1 ETH (async flow approve)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ - driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await installSnapSimpleKeyring(driver, false); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 and approve the transaction - await sendTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - gasFee: '0.000042', - totalFee: '1.000042', - isSyncFlow: false, - }); - await headerNavbar.check_pageIsLoaded(); - await headerNavbar.openAccountMenu(); - const accountList = new AccountListPage(driver); - await accountList.check_pageIsLoaded(); - - // check the balance of the 2 accounts are updated - await accountList.check_accountBalanceDisplayed('26'); - await accountList.check_accountBalanceDisplayed('24'); - }, - ); - }); - - it('can import a private key and transfer 1 ETH (async flow reject)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - ignoredConsoleErrors: ['Request rejected by user or snap.'], - }, - async ({ - driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await installSnapSimpleKeyring(driver, false); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // Import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 and reject the transaction - await sendTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - gasFee: '0.000042', - totalFee: '1.000042', - isSyncFlow: false, - approveTransaction: false, - }); - - // check the transaction is failed in MetaMask activity list - await new HomePage(driver).check_pageIsLoaded(); - await new ActivityListPage( - driver, - ).check_failedTxNumberDisplayedInActivity(); - }, - ); - }); + recipientAddress: DEFAULT_FIXTURE_ACCOUNT, + amount: '1', + }); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.openAccountMenu(); + const accountList = new AccountListPage(driver); + await accountList.check_pageIsLoaded(); + + // check the balance of the 2 accounts are updated + await accountList.check_accountBalanceDisplayed('26'); + await accountList.check_accountBalanceDisplayed('24'); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('can import a private key and transfer 1 ETH (sync flow)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ + it('can import a private key and transfer 1 ETH (async flow approve)', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: multipleGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ + driver, + ganacheServer, + }: { + driver: Driver; + ganacheServer?: Ganache; + }) => { + await loginWithBalanceValidation(driver, ganacheServer); + + await installSnapSimpleKeyring(driver, false); + const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); + + // import snap account with private key on snap simple keyring page. + await snapSimpleKeyringPage.importAccountWithPrivateKey( + PRIVATE_KEY_TWO, + ); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel('SSK Account'); + + // send 1 ETH from snap account to account 1 and approve the transaction + await sendRedesignedTransactionWithSnapAccount({ driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await installSnapSimpleKeyring(driver); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 - await sendRedesignedTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - }); - await headerNavbar.check_pageIsLoaded(); - await headerNavbar.openAccountMenu(); - const accountList = new AccountListPage(driver); - await accountList.check_pageIsLoaded(); - - // check the balance of the 2 accounts are updated - await accountList.check_accountBalanceDisplayed('26'); - await accountList.check_accountBalanceDisplayed('24'); - }, - ); - }); + recipientAddress: DEFAULT_FIXTURE_ACCOUNT, + amount: '1', + isSyncFlow: false, + }); + await headerNavbar.check_pageIsLoaded(); + await headerNavbar.openAccountMenu(); + const accountList = new AccountListPage(driver); + await accountList.check_pageIsLoaded(); + + // check the balance of the 2 accounts are updated + await accountList.check_accountBalanceDisplayed('26'); + await accountList.check_accountBalanceDisplayed('24'); + }, + ); + }); - it('can import a private key and transfer 1 ETH (async flow approve)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ + it('can import a private key and transfer 1 ETH (async flow reject)', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: multipleGanacheOptions, + title: this.test?.fullTitle(), + ignoredConsoleErrors: ['Request rejected by user or snap.'], + }, + async ({ + driver, + ganacheServer, + }: { + driver: Driver; + ganacheServer?: Ganache; + }) => { + await loginWithBalanceValidation(driver, ganacheServer); + + await installSnapSimpleKeyring(driver, false); + const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); + + // Import snap account with private key on snap simple keyring page. + await snapSimpleKeyringPage.importAccountWithPrivateKey( + PRIVATE_KEY_TWO, + ); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.check_accountLabel('SSK Account'); + + // send 1 ETH from snap account to account 1 and reject the transaction + await sendRedesignedTransactionWithSnapAccount({ driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await installSnapSimpleKeyring(driver, false); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 and approve the transaction - await sendRedesignedTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - isSyncFlow: false, - }); - await headerNavbar.check_pageIsLoaded(); - await headerNavbar.openAccountMenu(); - const accountList = new AccountListPage(driver); - await accountList.check_pageIsLoaded(); - - // check the balance of the 2 accounts are updated - await accountList.check_accountBalanceDisplayed('26'); - await accountList.check_accountBalanceDisplayed('24'); - }, - ); - }); - - it('can import a private key and transfer 1 ETH (async flow reject)', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: multipleGanacheOptions, - title: this.test?.fullTitle(), - ignoredConsoleErrors: ['Request rejected by user or snap.'], - }, - async ({ + recipientAddress: DEFAULT_FIXTURE_ACCOUNT, + amount: '1', + isSyncFlow: false, + approveTransaction: false, + }); + + // check the transaction is failed in MetaMask activity list + await new HomePage(driver).check_pageIsLoaded(); + await new ActivityListPage( driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await installSnapSimpleKeyring(driver, false); - const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver); - - // Import snap account with private key on snap simple keyring page. - await snapSimpleKeyringPage.importAccountWithPrivateKey( - PRIVATE_KEY_TWO, - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - const headerNavbar = new HeaderNavbar(driver); - await headerNavbar.check_accountLabel('SSK Account'); - - // send 1 ETH from snap account to account 1 and reject the transaction - await sendRedesignedTransactionWithSnapAccount({ - driver, - recipientAddress: DEFAULT_FIXTURE_ACCOUNT, - amount: '1', - isSyncFlow: false, - approveTransaction: false, - }); - - // check the transaction is failed in MetaMask activity list - await new HomePage(driver).check_pageIsLoaded(); - await new ActivityListPage( - driver, - ).check_failedTxNumberDisplayedInActivity(); - }, - ); - }); + ).check_failedTxNumberDisplayedInActivity(); + }, + ); }); }); diff --git a/test/e2e/tests/bridge/bridge-test-utils.ts b/test/e2e/tests/bridge/bridge-test-utils.ts index cf57deb59f96..842ff31fff39 100644 --- a/test/e2e/tests/bridge/bridge-test-utils.ts +++ b/test/e2e/tests/bridge/bridge-test-utils.ts @@ -12,7 +12,7 @@ import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { Driver } from '../../webdriver/driver'; import { isManifestV3 } from '../../../../shared/modules/mv3.utils'; -import { FeatureFlagResponse } from '../../../../ui/pages/bridge/types'; +import type { FeatureFlagResponse } from '../../../../shared/types/bridge'; import { DEFAULT_FEATURE_FLAGS_RESPONSE, ETH_CONVERSION_RATE_USD, diff --git a/test/e2e/tests/bridge/constants.ts b/test/e2e/tests/bridge/constants.ts index d5b6da9afc61..844cec673509 100644 --- a/test/e2e/tests/bridge/constants.ts +++ b/test/e2e/tests/bridge/constants.ts @@ -1,4 +1,4 @@ -import { FeatureFlagResponse } from '../../../../ui/pages/bridge/types'; +import type { FeatureFlagResponse } from '../../../../shared/types/bridge'; export const DEFAULT_FEATURE_FLAGS_RESPONSE: FeatureFlagResponse = { 'extension-config': { diff --git a/test/e2e/tests/confirmations/alerts/queued-confirmations.spec.ts b/test/e2e/tests/confirmations/alerts/queued-confirmations.spec.ts index 8ecd7e908a30..97b6beb81096 100644 --- a/test/e2e/tests/confirmations/alerts/queued-confirmations.spec.ts +++ b/test/e2e/tests/confirmations/alerts/queued-confirmations.spec.ts @@ -41,7 +41,7 @@ describe('Queued Confirmations', function () { dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .withSelectedNetworkControllerPerDomain() .build(), dappOptions: { numberOfDapps: 2 }, @@ -86,7 +86,7 @@ describe('Queued Confirmations', function () { dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .withSelectedNetworkControllerPerDomain() .build(), dappOptions: { numberOfDapps: 2 }, @@ -141,7 +141,6 @@ describe('Queued Confirmations', function () { .withPermissionControllerConnectedToTestDapp() .withPreferencesController({ preferences: { redesignedConfirmationsEnabled: true }, - useRequestQueue: true, }) .withSelectedNetworkControllerPerDomain() .build(), @@ -193,7 +192,7 @@ describe('Queued Confirmations', function () { dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .withSelectedNetworkControllerPerDomain() .withMetaMetricsController({ metaMetricsId: 'fake-metrics-id', @@ -281,7 +280,6 @@ describe('Queued Confirmations', function () { .withPermissionControllerConnectedToTestDapp() .withPreferencesController({ preferences: { redesignedConfirmationsEnabled: true }, - useRequestQueue: true, }) .withSelectedNetworkControllerPerDomain() .withMetaMetricsController({ diff --git a/test/e2e/tests/confirmations/signatures/nft-permit.spec.ts b/test/e2e/tests/confirmations/signatures/nft-permit.spec.ts index 4f1afe586116..cd485080208b 100644 --- a/test/e2e/tests/confirmations/signatures/nft-permit.spec.ts +++ b/test/e2e/tests/confirmations/signatures/nft-permit.spec.ts @@ -72,8 +72,9 @@ describe('Confirmation Signature - NFT Permit @no-mmi', function (this: Suite) { signatureType: 'eth_signTypedData_v4', primaryType: 'Permit', uiCustomizations: ['redesigned_confirmation', 'permit'], - decodingChangeTypes: ['RECEIVE', 'LISTING'], + decodingChangeTypes: ['LISTING', 'RECEIVE'], decodingResponse: 'CHANGE', + decodingDescription: null, }); await assertVerifiedResults(driver, publicAddress); @@ -115,8 +116,9 @@ describe('Confirmation Signature - NFT Permit @no-mmi', function (this: Suite) { primaryType: 'Permit', uiCustomizations: ['redesigned_confirmation', 'permit'], location: 'confirmation', - decodingChangeTypes: ['RECEIVE', 'LISTING'], + decodingChangeTypes: ['LISTING', 'RECEIVE'], decodingResponse: 'CHANGE', + decodingDescription: null, }); }, mockSignatureRejectedWithDecoding, diff --git a/test/e2e/tests/confirmations/signatures/permit.spec.ts b/test/e2e/tests/confirmations/signatures/permit.spec.ts index ea375b0c1100..d54ba056242d 100644 --- a/test/e2e/tests/confirmations/signatures/permit.spec.ts +++ b/test/e2e/tests/confirmations/signatures/permit.spec.ts @@ -69,8 +69,9 @@ describe('Confirmation Signature - Permit @no-mmi', function (this: Suite) { signatureType: 'eth_signTypedData_v4', primaryType: 'Permit', uiCustomizations: ['redesigned_confirmation', 'permit'], - decodingChangeTypes: ['RECEIVE', 'LISTING'], + decodingChangeTypes: ['LISTING', 'RECEIVE'], decodingResponse: 'CHANGE', + decodingDescription: null, }); await assertVerifiedResults(driver, publicAddress); @@ -107,8 +108,9 @@ describe('Confirmation Signature - Permit @no-mmi', function (this: Suite) { primaryType: 'Permit', uiCustomizations: ['redesigned_confirmation', 'permit'], location: 'confirmation', - decodingChangeTypes: ['RECEIVE', 'LISTING'], + decodingChangeTypes: ['LISTING', 'RECEIVE'], decodingResponse: 'CHANGE', + decodingDescription: null, }); }, mockSignatureRejectedWithDecoding, @@ -126,12 +128,12 @@ describe('Confirmation Signature - Permit @no-mmi', function (this: Suite) { const simulationSection = driver.findElement({ text: 'Estimated changes', }); - const receiveChange = driver.findElement({ text: 'You receive' }); + const receiveChange = driver.findElement({ text: 'Listing price' }); const listChange = driver.findElement({ text: 'You list' }); const listChangeValue = driver.findElement({ text: '#2101' }); assert.ok(await simulationSection, 'Estimated changes'); - assert.ok(await receiveChange, 'You receive'); + assert.ok(await receiveChange, 'Listing price'); assert.ok(await listChange, 'You list'); assert.ok(await listChangeValue, '#2101'); diff --git a/test/e2e/tests/confirmations/signatures/signature-helpers.ts b/test/e2e/tests/confirmations/signatures/signature-helpers.ts index d341a0020e56..a4c9dd31b2ca 100644 --- a/test/e2e/tests/confirmations/signatures/signature-helpers.ts +++ b/test/e2e/tests/confirmations/signatures/signature-helpers.ts @@ -41,6 +41,7 @@ type AssertSignatureMetricsOptions = { securityAlertResponse?: string; decodingChangeTypes?: string[]; decodingResponse?: string; + decodingDescription?: string | null; }; type SignatureEventProperty = { @@ -55,6 +56,7 @@ type SignatureEventProperty = { eip712_primary_type?: string; decoding_change_types?: string[]; decoding_response?: string; + decoding_description?: string | null; ui_customizations?: string[]; location?: string; }; @@ -83,6 +85,7 @@ export async function initializePages(driver: Driver) { * @param securityAlertResponse * @param decodingChangeTypes * @param decodingResponse + * @param decodingDescription */ function getSignatureEventProperty( signatureType: string, @@ -92,6 +95,7 @@ function getSignatureEventProperty( securityAlertResponse: string = BlockaidResultType.Loading, decodingChangeTypes?: string[], decodingResponse?: string, + decodingDescription?: string | null, ): SignatureEventProperty { const signatureEventProperty: SignatureEventProperty = { account_type: 'MetaMask', @@ -112,6 +116,7 @@ function getSignatureEventProperty( if (decodingResponse) { signatureEventProperty.decoding_change_types = decodingChangeTypes; signatureEventProperty.decoding_response = decodingResponse; + signatureEventProperty.decoding_description = decodingDescription; } return signatureEventProperty; } @@ -147,6 +152,7 @@ export async function assertSignatureConfirmedMetrics({ securityAlertResponse, decodingChangeTypes, decodingResponse, + decodingDescription, }: AssertSignatureMetricsOptions) { const events = await getEventPayloads(driver, mockedEndpoints); const signatureEventProperty = getSignatureEventProperty( @@ -157,6 +163,7 @@ export async function assertSignatureConfirmedMetrics({ securityAlertResponse, decodingChangeTypes, decodingResponse, + decodingDescription, ); assertSignatureRequestedMetrics( @@ -192,6 +199,7 @@ export async function assertSignatureRejectedMetrics({ securityAlertResponse, decodingChangeTypes, decodingResponse, + decodingDescription, }: AssertSignatureMetricsOptions) { const events = await getEventPayloads(driver, mockedEndpoints); const signatureEventProperty = getSignatureEventProperty( @@ -202,6 +210,7 @@ export async function assertSignatureRejectedMetrics({ securityAlertResponse, decodingChangeTypes, decodingResponse, + decodingDescription, ); assertSignatureRequestedMetrics( @@ -314,12 +323,21 @@ function compareDecodingAPIResponse( expectedProperties.decoding_response, `${eventName} event properties do not match: decoding_response is ${actualProperties.decoding_response}`, ); + assert.equal( + actualProperties.decoding_description, + expectedProperties.decoding_description, + `${eventName} event properties do not match: decoding_response is ${actualProperties.decoding_description}`, + ); } // Remove the property from both objects to avoid comparison delete expectedProperties.decoding_change_types; delete expectedProperties.decoding_response; + delete expectedProperties.decoding_description; + delete expectedProperties.decoding_latency; delete actualProperties.decoding_change_types; delete actualProperties.decoding_response; + delete actualProperties.decoding_description; + delete actualProperties.decoding_latency; } export async function clickHeaderInfoBtn(driver: Driver) { diff --git a/test/e2e/tests/confirmations/transactions/erc1155-set-approval-for-all-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/erc1155-set-approval-for-all-redesign.spec.ts index cbb85482e6f1..e2a78bac8fd3 100644 --- a/test/e2e/tests/confirmations/transactions/erc1155-set-approval-for-all-redesign.spec.ts +++ b/test/e2e/tests/confirmations/transactions/erc1155-set-approval-for-all-redesign.spec.ts @@ -86,6 +86,7 @@ async function createTransactionAssertDetailsAndConfirm( const testDapp = new TestDapp(driver); await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); await testDapp.clickERC1155SetApprovalForAllButton(); await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); diff --git a/test/e2e/tests/confirmations/transactions/erc20-approve-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/erc20-approve-redesign.spec.ts index 4e340f5ef3ac..b75d71cda4c0 100644 --- a/test/e2e/tests/confirmations/transactions/erc20-approve-redesign.spec.ts +++ b/test/e2e/tests/confirmations/transactions/erc20-approve-redesign.spec.ts @@ -4,6 +4,7 @@ import { tinyDelayMs, veryLargeDelayMs, WINDOW_TITLES } from '../../../helpers'; import { Driver } from '../../../webdriver/driver'; import { scrollAndConfirmAndAssertConfirm } from '../helpers'; import { + mocked4BytesApprove, openDAppWithContract, TestSuiteArguments, toggleAdvancedDetails, @@ -87,30 +88,6 @@ describe('Confirmation Redesign ERC20 Approve Component', function () { }); }); -export async function mocked4BytesApprove(mockServer: MockttpServer) { - return await mockServer - .forGet('https://www.4byte.directory/api/v1/signatures/') - .always() - .withQuery({ hex_signature: '0x095ea7b3' }) - .thenCallback(() => ({ - statusCode: 200, - json: { - count: 1, - next: null, - previous: null, - results: [ - { - id: 149, - created_at: '2016-07-09T03:58:29.617584Z', - text_signature: 'approve(address,uint256)', - hex_signature: '0x095ea7b3', - bytes_signature: '\t^§³', - }, - ], - }, - })); -} - async function mocks(server: MockttpServer) { return [await mocked4BytesApprove(server)]; } diff --git a/test/e2e/tests/confirmations/transactions/increase-token-allowance-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/increase-token-allowance-redesign.spec.ts index 30c87080c3fc..82b995f217ed 100644 --- a/test/e2e/tests/confirmations/transactions/increase-token-allowance-redesign.spec.ts +++ b/test/e2e/tests/confirmations/transactions/increase-token-allowance-redesign.spec.ts @@ -2,8 +2,6 @@ import FixtureBuilder from '../../../fixture-builder'; import { defaultGanacheOptions, defaultGanacheOptionsForType2Transactions, - largeDelayMs, - veryLargeDelayMs, WINDOW_TITLES, withFixtures, } from '../../../helpers'; @@ -12,7 +10,12 @@ import ContractAddressRegistry from '../../../seeder/contract-address-registry'; import { SMART_CONTRACTS } from '../../../seeder/smart-contracts'; import { Driver } from '../../../webdriver/driver'; import { scrollAndConfirmAndAssertConfirm } from '../helpers'; -import { openDAppWithContract, TestSuiteArguments } from './shared'; +import { + assertChangedSpendingCap, + editSpendingCap, + openDAppWithContract, + TestSuiteArguments, +} from './shared'; describe('Confirmation Redesign ERC20 Increase Allowance', function () { describe('Submit an increase allowance transaction @no-mmi', function () { @@ -158,42 +161,3 @@ async function createERC20IncreaseAllowanceTransaction(driver: Driver) { await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); await driver.clickElement('#increaseTokenAllowance'); } - -export async function editSpendingCap(driver: Driver, newSpendingCap: string) { - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement('[data-testid="edit-spending-cap-icon"'); - - await driver.fill( - '[data-testid="custom-spending-cap-input"]', - newSpendingCap, - ); - - await driver.delay(largeDelayMs); - - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // wait for the confirmation to be updated before submitting tx - await driver.delay(veryLargeDelayMs * 2); -} - -export async function assertChangedSpendingCap( - driver: Driver, - newSpendingCap: string, -) { - await driver.switchToWindowWithTitle(WINDOW_TITLES.ExtensionInFullScreenView); - - await driver.clickElement({ text: 'Activity', tag: 'button' }); - - await driver.delay(veryLargeDelayMs); - - await driver.clickElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - await driver.waitForSelector({ - text: `${newSpendingCap} TST`, - tag: 'span', - }); - - await driver.waitForSelector({ text: 'Confirmed', tag: 'div' }); -} diff --git a/test/e2e/tests/confirmations/transactions/nft-token-send-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/nft-token-send-redesign.spec.ts index 09bd9d4b32a2..9b712ebb7a65 100644 --- a/test/e2e/tests/confirmations/transactions/nft-token-send-redesign.spec.ts +++ b/test/e2e/tests/confirmations/transactions/nft-token-send-redesign.spec.ts @@ -196,6 +196,7 @@ async function createERC721WalletInitiatedTransactionAndAssertDetails( const testDapp = new TestDapp(driver); await testDapp.openTestDappPage({ contractAddress, url: DAPP_URL }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); await testDapp.clickERC721MintButton(); diff --git a/test/e2e/tests/confirmations/transactions/revoke-allowance-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/revoke-allowance-redesign.spec.ts index ba97d9cda4cd..227fdb14ec8f 100644 --- a/test/e2e/tests/confirmations/transactions/revoke-allowance-redesign.spec.ts +++ b/test/e2e/tests/confirmations/transactions/revoke-allowance-redesign.spec.ts @@ -3,12 +3,13 @@ import { MockttpServer } from 'mockttp'; import { WINDOW_TITLES } from '../../../helpers'; import { Driver } from '../../../webdriver/driver'; import { scrollAndConfirmAndAssertConfirm } from '../helpers'; -import { mocked4BytesApprove } from './erc20-approve-redesign.spec'; import { assertChangedSpendingCap, editSpendingCap, -} from './increase-token-allowance-redesign.spec'; -import { openDAppWithContract, TestSuiteArguments } from './shared'; + mocked4BytesApprove, + openDAppWithContract, + TestSuiteArguments, +} from './shared'; const { defaultGanacheOptions, diff --git a/test/e2e/tests/confirmations/transactions/shared.ts b/test/e2e/tests/confirmations/transactions/shared.ts index f984417fae94..d8f79a2053b2 100644 --- a/test/e2e/tests/confirmations/transactions/shared.ts +++ b/test/e2e/tests/confirmations/transactions/shared.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */ -import { MockedEndpoint } from 'mockttp'; -import { veryLargeDelayMs } from '../../../helpers'; +import { MockedEndpoint, MockttpServer } from 'mockttp'; +import { largeDelayMs, veryLargeDelayMs } from '../../../helpers'; import { Ganache } from '../../../seeder/ganache'; import ContractAddressRegistry from '../../../seeder/contract-address-registry'; import { Driver } from '../../../webdriver/driver'; @@ -238,3 +238,66 @@ export async function assertAdvancedGasDetailsWithL2Breakdown(driver: Driver) { await driver.waitForSelector({ css: 'p', text: 'Speed' }); await driver.waitForSelector({ css: 'p', text: 'Max fee' }); } + +export async function editSpendingCap(driver: Driver, newSpendingCap: string) { + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElement('[data-testid="edit-spending-cap-icon"'); + + await driver.fill( + '[data-testid="custom-spending-cap-input"]', + newSpendingCap, + ); + + await driver.delay(largeDelayMs); + + await driver.clickElement({ text: 'Save', tag: 'button' }); + + // wait for the confirmation to be updated before submitting tx + await driver.delay(veryLargeDelayMs * 2); +} + +export async function assertChangedSpendingCap( + driver: Driver, + newSpendingCap: string, +) { + await driver.switchToWindowWithTitle(WINDOW_TITLES.ExtensionInFullScreenView); + + await driver.clickElement({ text: 'Activity', tag: 'button' }); + + await driver.delay(veryLargeDelayMs); + + await driver.clickElement( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + + await driver.waitForSelector({ + text: `${newSpendingCap} TST`, + tag: 'span', + }); + + await driver.waitForSelector({ text: 'Confirmed', tag: 'div' }); +} + +export async function mocked4BytesApprove(mockServer: MockttpServer) { + return await mockServer + .forGet('https://www.4byte.directory/api/v1/signatures/') + .always() + .withQuery({ hex_signature: '0x095ea7b3' }) + .thenCallback(() => ({ + statusCode: 200, + json: { + count: 1, + next: null, + previous: null, + results: [ + { + id: 149, + created_at: '2016-07-09T03:58:29.617584Z', + text_signature: 'approve(address,uint256)', + hex_signature: '0x095ea7b3', + bytes_signature: '\t^§³', + }, + ], + }, + })); +} diff --git a/test/e2e/tests/connections/connect-with-metamask.spec.js b/test/e2e/tests/connections/connect-with-metamask.spec.js deleted file mode 100644 index b46fc8730d84..000000000000 --- a/test/e2e/tests/connections/connect-with-metamask.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - WINDOW_TITLES, - logInWithBalanceValidation, - defaultGanacheOptions, - openDapp, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Connections page', function () { - it('should render new connections flow', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - title: this.test.fullTitle(), - ganacheOptions: defaultGanacheOptions, - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - await openDapp(driver); - // Connect to dapp - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // should render new connections page - const newConnectionPage = await driver.waitForSelector({ - tag: 'h2', - text: 'Connect with MetaMask', - }); - assert.ok(newConnectionPage, 'Connection Page is defined'); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // It should render connected status for button if dapp is connected - const getConnectedStatus = await driver.waitForSelector({ - css: '#connectButton', - text: 'Connected', - }); - assert.ok(getConnectedStatus, 'Account is connected to Dapp'); - - // Switch to extension Tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid ="account-options-menu-button"]', - ); - await driver.clickElement({ text: 'All Permissions', tag: 'div' }); - await driver.clickElement({ - text: '127.0.0.1:8080', - tag: 'p', - }); - const connectionsPageAccountInfo = await driver.isElementPresent({ - text: 'See your accounts and suggest transactions', - tag: 'p', - }); - assert.ok(connectionsPageAccountInfo, 'Connections Page is defined'); - const connectionsPageNetworkInfo = await driver.isElementPresent({ - text: 'Use your enabled networks', - tag: 'p', - }); - assert.ok(connectionsPageNetworkInfo, 'Connections Page is defined'); - }, - ); - }); -}); diff --git a/test/e2e/tests/connections/edit-account-flow.spec.js b/test/e2e/tests/connections/edit-account-flow.spec.js deleted file mode 100644 index 1c4899ed8328..000000000000 --- a/test/e2e/tests/connections/edit-account-flow.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - WINDOW_TITLES, - connectToDapp, - logInWithBalanceValidation, - locateAccountBalanceDOM, - defaultGanacheOptions, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -const accountLabel2 = '2nd custom name'; -const accountLabel3 = '3rd custom name'; -describe('Edit Accounts Flow', function () { - it('should be able to edit accounts', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - title: this.test.fullTitle(), - ganacheOptions: defaultGanacheOptions, - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - await connectToDapp(driver); - - // It should render connected status for button if dapp is connected - const getConnectedStatus = await driver.waitForSelector({ - css: '#connectButton', - text: 'Connected', - }); - assert.ok(getConnectedStatus, 'Account is connected to Dapp'); - - // Switch to extension Tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-account"]', - ); - await driver.fill('[placeholder="Account 2"]', accountLabel2); - await driver.clickElement({ text: 'Add account', tag: 'button' }); - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-account"]', - ); - await driver.fill('[placeholder="Account 3"]', accountLabel3); - await driver.clickElement({ text: 'Add account', tag: 'button' }); - await locateAccountBalanceDOM(driver); - await driver.clickElement( - '[data-testid ="account-options-menu-button"]', - ); - await driver.clickElement({ text: 'All Permissions', tag: 'div' }); - await driver.clickElement({ - text: '127.0.0.1:8080', - tag: 'p', - }); - const connectionsPageAccountInfo = await driver.isElementPresent({ - text: 'See your accounts and suggest transactions', - tag: 'p', - }); - assert.ok(connectionsPageAccountInfo, 'Connections Page is defined'); - const editButtons = await driver.findElements('[data-testid="edit"]'); - - // Ensure there are edit buttons - assert.ok(editButtons.length > 0, 'Edit buttons are available'); - - // Click the first (0th) edit button - await editButtons[0].click(); - - await driver.clickElement({ - text: '2nd custom name', - tag: 'button', - }); - await driver.clickElement({ - text: '3rd custom name', - tag: 'button', - }); - await driver.clickElement( - '[data-testid="connect-more-accounts-button"]', - ); - const updatedAccountInfo = await driver.isElementPresent({ - text: '3 accounts connected', - tag: 'span', - }); - assert.ok(updatedAccountInfo, 'Accounts List Updated'); - }, - ); - }); -}); diff --git a/test/e2e/tests/connections/edit-account-permissions.spec.ts b/test/e2e/tests/connections/edit-account-permissions.spec.ts new file mode 100644 index 000000000000..bd1eebdf9ffd --- /dev/null +++ b/test/e2e/tests/connections/edit-account-permissions.spec.ts @@ -0,0 +1,74 @@ +import { withFixtures, WINDOW_TITLES } from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; +import { + ACCOUNT_TYPE, + DEFAULT_FIXTURE_ACCOUNT, + DAPP_HOST_ADDRESS, +} from '../../constants'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import Homepage from '../../page-objects/pages/home/homepage'; +import PermissionListPage from '../../page-objects/pages/permission/permission-list-page'; +import SitePermissionPage from '../../page-objects/pages/permission/site-permission-page'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +const accountLabel2 = '2nd custom name'; +const accountLabel3 = '3rd custom name'; +describe('Edit Accounts Permissions', function () { + it('should be able to edit accounts', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().build(), + title: this.test?.fullTitle(), + }, + async ({ driver }) => { + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_pageIsLoaded(); + await testDapp.connectAccount({ + publicAddress: DEFAULT_FIXTURE_ACCOUNT, + }); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await new Homepage(driver).check_pageIsLoaded(); + new HeaderNavbar(driver).openAccountMenu(); + + // create second account with custom label + const accountListPage = new AccountListPage(driver); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: accountLabel2, + }); + const homepage = new Homepage(driver); + await homepage.check_expectedBalanceIsDisplayed(); + + // create third account with custom label + await homepage.headerNavbar.openAccountMenu(); + await accountListPage.check_pageIsLoaded(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: accountLabel3, + }); + await homepage.check_expectedBalanceIsDisplayed(); + + // go to connections permissions page + await homepage.headerNavbar.openPermissionsPage(); + const permissionListPage = new PermissionListPage(driver); + await permissionListPage.check_pageIsLoaded(); + await permissionListPage.openPermissionPageForSite(DAPP_HOST_ADDRESS); + const sitePermissionPage = new SitePermissionPage(driver); + await sitePermissionPage.check_pageIsLoaded(DAPP_HOST_ADDRESS); + await sitePermissionPage.editPermissionsForAccount([ + accountLabel2, + accountLabel3, + ]); + await sitePermissionPage.check_connectedAccountsNumber(3); + }, + ); + }); +}); diff --git a/test/e2e/tests/connections/edit-networks-flow.spec.js b/test/e2e/tests/connections/edit-networks-flow.spec.js deleted file mode 100644 index 95a091f7e504..000000000000 --- a/test/e2e/tests/connections/edit-networks-flow.spec.js +++ /dev/null @@ -1,73 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - WINDOW_TITLES, - connectToDapp, - logInWithBalanceValidation, - locateAccountBalanceDOM, - defaultGanacheOptions, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Edit Networks Flow', function () { - it('should be able to edit networks', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - title: this.test.fullTitle(), - ganacheOptions: defaultGanacheOptions, - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - await connectToDapp(driver); - - // It should render connected status for button if dapp is connected - const getConnectedStatus = await driver.waitForSelector({ - css: '#connectButton', - text: 'Connected', - }); - assert.ok(getConnectedStatus, 'Account is connected to Dapp'); - - // Switch to extension Tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement('[data-testid="network-display"]'); - await driver.clickElement('.mm-modal-content__dialog .toggle-button'); - await driver.clickElement( - '.mm-modal-content__dialog button[aria-label="Close"]', - ); - await locateAccountBalanceDOM(driver); - await driver.clickElement( - '[data-testid ="account-options-menu-button"]', - ); - await driver.clickElement({ text: 'All Permissions', tag: 'div' }); - await driver.clickElement({ - text: '127.0.0.1:8080', - tag: 'p', - }); - const editButtons = await driver.findElements('[data-testid="edit"]'); - - // Ensure there are edit buttons - assert.ok(editButtons.length > 0, 'Edit buttons are available'); - - // Click the first (0th) edit button - await editButtons[1].click(); - - // Disconnect Mainnet - await driver.clickElement({ - text: 'Ethereum Mainnet', - tag: 'p', - }); - - await driver.clickElement('[data-testid="connect-more-chains-button"]'); - const updatedNetworkInfo = await driver.isElementPresent({ - text: '2 networks connected', - tag: 'span', - }); - assert.ok(updatedNetworkInfo, 'Networks List Updated'); - }, - ); - }); -}); diff --git a/test/e2e/tests/connections/edit-networks-permissions.spec.ts b/test/e2e/tests/connections/edit-networks-permissions.spec.ts new file mode 100644 index 000000000000..55b7cdd2caeb --- /dev/null +++ b/test/e2e/tests/connections/edit-networks-permissions.spec.ts @@ -0,0 +1,49 @@ +import { withFixtures, WINDOW_TITLES } from '../../helpers'; +import { DEFAULT_FIXTURE_ACCOUNT, DAPP_HOST_ADDRESS } from '../../constants'; +import FixtureBuilder from '../../fixture-builder'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import Homepage from '../../page-objects/pages/home/homepage'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import PermissionListPage from '../../page-objects/pages/permission/permission-list-page'; +import SitePermissionPage from '../../page-objects/pages/permission/site-permission-page'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +describe('Edit Networks Permissions', function () { + it('should be able to edit networks', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().build(), + title: this.test?.fullTitle(), + }, + async ({ driver }) => { + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_pageIsLoaded(); + + await testDapp.connectAccount({ + publicAddress: DEFAULT_FIXTURE_ACCOUNT, + }); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await new Homepage(driver).check_pageIsLoaded(); + + // Open permission page for dapp + new HeaderNavbar(driver).openPermissionsPage(); + const permissionListPage = new PermissionListPage(driver); + await permissionListPage.check_pageIsLoaded(); + await permissionListPage.openPermissionPageForSite(DAPP_HOST_ADDRESS); + const sitePermissionPage = new SitePermissionPage(driver); + await sitePermissionPage.check_pageIsLoaded(DAPP_HOST_ADDRESS); + + // Disconnect Mainnet + await sitePermissionPage.editPermissionsForNetwork([ + 'Ethereum Mainnet', + ]); + await sitePermissionPage.check_connectedNetworksNumber(2); + }, + ); + }); +}); diff --git a/test/e2e/tests/connections/review-switch-permission-page.spec.js b/test/e2e/tests/connections/review-switch-permission-page.spec.js index 5fe3d6d19526..121c3b413833 100644 --- a/test/e2e/tests/connections/review-switch-permission-page.spec.js +++ b/test/e2e/tests/connections/review-switch-permission-page.spec.js @@ -21,7 +21,7 @@ describe('Permissions Page when Dapp Switch to an enabled and non permissioned n dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .withSelectedNetworkControllerPerDomain() .build(), ganacheOptions: { diff --git a/test/e2e/tests/dapp-interactions/contract-interactions.spec.js b/test/e2e/tests/dapp-interactions/contract-interactions.spec.js deleted file mode 100644 index a685954b5857..000000000000 --- a/test/e2e/tests/dapp-interactions/contract-interactions.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -const { - defaultGanacheOptions, - withFixtures, - openDapp, - unlockWallet, - largeDelayMs, - WINDOW_TITLES, - locateAccountBalanceDOM, - clickNestedButton, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Deploy contract and call contract methods', function () { - const smartContract = SMART_CONTRACTS.PIGGYBANK; - - it('should display the correct account balance after contract interactions', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // deploy contract - await openDapp(driver, contractAddress); - - // wait for deployed contract, calls and confirms a contract method where ETH is sent - await driver.delay(largeDelayMs); - await driver.clickElement('#depositButton'); - - await driver.waitForSelector({ - css: 'span', - text: 'Deposit initiated', - }); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-4 ETH', - }); - - // calls and confirms a contract method where ETH is received - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.clickElement('#withdrawButton'); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(2)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-0 ETH', - }); - - // renders the correct ETH balance - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await locateAccountBalanceDOM(driver, ganacheServer); - }, - ); - }); -}); diff --git a/test/e2e/tests/dapp-interactions/dapp-tx-edit.spec.js b/test/e2e/tests/dapp-interactions/dapp-tx-edit.spec.js deleted file mode 100644 index ad168a2b9332..000000000000 --- a/test/e2e/tests/dapp-interactions/dapp-tx-edit.spec.js +++ /dev/null @@ -1,81 +0,0 @@ -const { - defaultGanacheOptions, - logInWithBalanceValidation, - openDapp, - WINDOW_TITLES, - withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Editing confirmations of dapp initiated contract interactions', function () { - const smartContract = SMART_CONTRACTS.PIGGYBANK; - it('should NOT show an edit button on a contract interaction confirmation initiated by a dapp', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // deploy contract - await openDapp(driver, contractAddress); - // wait for deployed contract, calls and confirms a contract method where ETH is sent - await driver.findClickableElement('#deployButton'); - await driver.clickElement('#depositButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.assertElementNotPresent( - '[data-testid="confirm-page-back-edit-button"]', - ); - }, - ); - }); - - it('should NOT show an edit button on a simple ETH send initiated by a dapp', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await logInWithBalanceValidation(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver); - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Sending ETH', - }); - await driver.assertElementNotPresent( - '[data-testid="confirm-page-back-edit-button"]', - ); - }, - ); - }); -}); diff --git a/test/e2e/tests/dapp-interactions/failing-contract.spec.js b/test/e2e/tests/dapp-interactions/failing-contract.spec.js deleted file mode 100644 index c05938d668e0..000000000000 --- a/test/e2e/tests/dapp-interactions/failing-contract.spec.js +++ /dev/null @@ -1,152 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - openDapp, - unlockWallet, - WINDOW_TITLES, - generateGanacheOptions, - clickNestedButton, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Failing contract interaction ', function () { - const smartContract = SMART_CONTRACTS.FAILING; - it('should display a warning when the contract interaction is expected to fail', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver, contractAddress); - let windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - - // waits for deployed contract and calls failing contract method - await driver.findClickableElement('#deployButton'); - await driver.clickElement('#sendFailingButton'); - await driver.waitUntilXWindowHandles(3); - windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - // display warning when transaction is expected to fail - const warningText = - 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.'; - await driver.waitForSelector({ - css: '.mm-banner-alert .mm-text', - text: warningText, - }); - const confirmButton = await driver.findElement( - '[data-testid="page-container-footer-next"]', - ); - assert.equal(await confirmButton.isEnabled(), false); - - // dismiss warning and confirm the transaction - await driver.clickElement({ - text: 'I want to proceed anyway', - tag: 'button', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - - await driver.findElement({ - css: '.activity-list-item .transaction-status-label', - text: 'Failed', - }); - }, - ); - }); -}); - -describe('Failing contract interaction on non-EIP1559 network', function () { - const smartContract = SMART_CONTRACTS.FAILING; - it('should display a warning when the contract interaction is expected to fail', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'berlin' }), - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver, contractAddress); - let windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - // waits for deployed contract and calls failing contract method - await driver.findClickableElement('#deployButton'); - - await driver.fill('#toInput', contractAddress); - await driver.fill('#amountInput', '0'); - await driver.fill('#gasInput', '100'); - - await driver.clickElement('#submitForm'); - - await driver.waitUntilXWindowHandles(3); - windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - // display warning when transaction is expected to fail - const warningText = - 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.'; - await driver.waitForSelector({ - css: '.mm-banner-alert .mm-text', - text: warningText, - }); - const confirmButton = await driver.findElement( - '[data-testid="page-container-footer-next"]', - ); - assert.equal(await confirmButton.isEnabled(), false); - - // dismiss warning and confirm the transaction - await driver.clickElement({ - text: 'I want to proceed anyway', - tag: 'button', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - await driver.findElement({ - css: '.activity-list-item .transaction-status-label', - text: 'Failed', - }); - }, - ); - }); -}); diff --git a/test/e2e/tests/identity/account-syncing/new-user-sync.spec.ts b/test/e2e/tests/identity/account-syncing/new-user-sync.spec.ts index e9a82b128352..64a3ddbf5fd7 100644 --- a/test/e2e/tests/identity/account-syncing/new-user-sync.spec.ts +++ b/test/e2e/tests/identity/account-syncing/new-user-sync.spec.ts @@ -2,6 +2,7 @@ import { Mockttp } from 'mockttp'; import { USER_STORAGE_FEATURE_NAMES } from '@metamask/profile-sync-controller/sdk'; import { withFixtures } from '../../../helpers'; import FixtureBuilder from '../../../fixture-builder'; +import { ACCOUNT_TYPE } from '../../../constants'; import { mockIdentityServices } from '../mocks'; import { IDENTITY_TEAM_PASSWORD } from '../constants'; import { UserStorageMockttpController } from '../../../helpers/identity/user-storage/userStorageMockttpController'; @@ -64,7 +65,10 @@ describe('Account syncing - New User @no-mmi', function () { // Add a second account await accountListPage.openAccountOptionsMenu(); - await accountListPage.addNewAccount('My Second Account'); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: 'My Second Account', + }); // Set SRP to use for retreival const headerNavbar = new HeaderNavbar(driver); diff --git a/test/e2e/tests/identity/account-syncing/onboarding-with-opt-out.spec.ts b/test/e2e/tests/identity/account-syncing/onboarding-with-opt-out.spec.ts index 19908211181b..bd063c182baf 100644 --- a/test/e2e/tests/identity/account-syncing/onboarding-with-opt-out.spec.ts +++ b/test/e2e/tests/identity/account-syncing/onboarding-with-opt-out.spec.ts @@ -7,6 +7,7 @@ import { IDENTITY_TEAM_PASSWORD, IDENTITY_TEAM_SEED_PHRASE, } from '../constants'; +import { ACCOUNT_TYPE } from '../../../constants'; import { UserStorageMockttpController } from '../../../helpers/identity/user-storage/userStorageMockttpController'; import AccountListPage from '../../../page-objects/pages/account-list-page'; import HeaderNavbar from '../../../page-objects/pages/header-navbar'; @@ -135,7 +136,11 @@ describe('Account syncing - Opt-out Profile Sync @no-mmi', function () { await accountListPage.check_accountDisplayedInAccountList( 'Account 1', ); - await accountListPage.addNewAccount('New Account'); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: 'New Account', + }); + // Set SRP to use for retreival const headerNavbar = new HeaderNavbar(driver); await headerNavbar.check_pageIsLoaded(); diff --git a/test/e2e/tests/identity/account-syncing/sync-after-adding-account.spec.ts b/test/e2e/tests/identity/account-syncing/sync-after-adding-account.spec.ts index 9c2fdb69c7e9..e02833e7c172 100644 --- a/test/e2e/tests/identity/account-syncing/sync-after-adding-account.spec.ts +++ b/test/e2e/tests/identity/account-syncing/sync-after-adding-account.spec.ts @@ -3,6 +3,7 @@ import { USER_STORAGE_FEATURE_NAMES } from '@metamask/profile-sync-controller/sd import { withFixtures } from '../../../helpers'; import FixtureBuilder from '../../../fixture-builder'; import { mockIdentityServices } from '../mocks'; +import { ACCOUNT_TYPE } from '../../../constants'; import { IDENTITY_TEAM_PASSWORD, IDENTITY_TEAM_SEED_PHRASE, @@ -65,7 +66,10 @@ describe('Account syncing - Add Account @no-mmi', function () { await accountListPage.check_accountDisplayedInAccountList( 'My Second Synced Account', ); - await accountListPage.addNewAccount('My third account'); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + accountName: 'My third account', + }); }, ); @@ -164,7 +168,9 @@ describe('Account syncing - Add Account @no-mmi', function () { await accountListPage.check_accountDisplayedInAccountList( 'My Second Synced Account', ); - await accountListPage.addNewAccount(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + }); }, ); diff --git a/test/e2e/tests/identity/account-syncing/sync-after-modifying-account-name.spec.ts b/test/e2e/tests/identity/account-syncing/sync-after-modifying-account-name.spec.ts index 07f6e4848aba..ce10b3129d58 100644 --- a/test/e2e/tests/identity/account-syncing/sync-after-modifying-account-name.spec.ts +++ b/test/e2e/tests/identity/account-syncing/sync-after-modifying-account-name.spec.ts @@ -9,6 +9,7 @@ import { } from '../constants'; import { UserStorageMockttpController } from '../../../helpers/identity/user-storage/userStorageMockttpController'; import HeaderNavbar from '../../../page-objects/pages/header-navbar'; +import AccountDetailsModal from '../../../page-objects/pages/dialog/account-details-modal'; import AccountListPage from '../../../page-objects/pages/account-list-page'; import HomePage from '../../../page-objects/pages/home/homepage'; import { completeImportSRPOnboardingFlow } from '../../../page-objects/flows/onboarding.flow'; @@ -65,8 +66,14 @@ describe('Account syncing - Rename Accounts @no-mmi', function () { await accountListPage.check_accountDisplayedInAccountList( 'My Second Synced Account', ); - await accountListPage.openAccountOptionsMenu(); - await accountListPage.changeAccountLabel('My Renamed First Account'); + await accountListPage.openAccountDetailsModal( + 'My First Synced Account', + ); + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + await accountDetailsModal.changeAccountLabel( + 'My Renamed First Account', + ); }, ); diff --git a/test/e2e/tests/identity/account-syncing/sync-with-account-balances.spec.ts b/test/e2e/tests/identity/account-syncing/sync-with-account-balances.spec.ts index 6fcc9e9cc0d0..ec52bb3124bd 100644 --- a/test/e2e/tests/identity/account-syncing/sync-with-account-balances.spec.ts +++ b/test/e2e/tests/identity/account-syncing/sync-with-account-balances.spec.ts @@ -6,8 +6,10 @@ import { IDENTITY_TEAM_PASSWORD, IDENTITY_TEAM_SEED_PHRASE, } from '../constants'; +import { ACCOUNT_TYPE } from '../../../constants'; import { UserStorageMockttpController } from '../../../helpers/identity/user-storage/userStorageMockttpController'; import HeaderNavbar from '../../../page-objects/pages/header-navbar'; +import AccountDetailsModal from '../../../page-objects/pages/dialog/account-details-modal'; import AccountListPage from '../../../page-objects/pages/account-list-page'; import HomePage from '../../../page-objects/pages/home/homepage'; import { completeImportSRPOnboardingFlow } from '../../../page-objects/flows/onboarding.flow'; @@ -108,7 +110,9 @@ describe('Account syncing - User already has balances on multple accounts @no-mm } // Create new account and prepare for additional accounts - await accountListPage.addNewAccount(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + }); accountsToMock = [...INITIAL_ACCOUNTS, ...ADDITIONAL_ACCOUNTS]; }, ); @@ -158,11 +162,13 @@ describe('Account syncing - User already has balances on multple accounts @no-mm // Rename Account 6 to verify update to user storage await accountListPage.switchToAccount('Account 6'); + await header.check_accountLabel('Account 6'); await header.openAccountMenu(); + await accountListPage.check_pageIsLoaded(); await accountListPage.openAccountDetailsModal('Account 6'); - await accountListPage.changeLabelFromAccountDetailsModal( - 'My Renamed Account 6', - ); + const accountDetailsModal = new AccountDetailsModal(driver); + await accountDetailsModal.check_pageIsLoaded(); + await accountDetailsModal.changeAccountLabel('My Renamed Account 6'); }, ); diff --git a/test/e2e/tests/metrics/delete-metametrics-data.spec.ts b/test/e2e/tests/metrics/delete-metametrics-data.spec.ts index 308ff8508d0a..621e42b29c85 100644 --- a/test/e2e/tests/metrics/delete-metametrics-data.spec.ts +++ b/test/e2e/tests/metrics/delete-metametrics-data.spec.ts @@ -17,11 +17,7 @@ const selectors = { globalMenuSettingsButton: '[data-testid="global-menu-settings"]', securityAndPrivacySettings: { text: 'Security & privacy', tag: 'div' }, experimentalSettings: { text: 'Experimental', tag: 'div' }, - deletMetaMetricsSettings: '[data-testid="delete-metametrics-data-button"]', - deleteMetaMetricsDataButton: { - text: 'Delete MetaMetrics data', - tag: 'button', - }, + deleteMetaMetricsDataButton: '[data-testid="delete-metametrics-data-button"]', clearButton: { text: 'Clear', tag: 'button' }, backButton: '[data-testid="settings-back-button"]', }; @@ -111,7 +107,6 @@ describe('Delete MetaMetrics Data @no-mmi', function (this: Suite) { await driver.clickElement(selectors.globalMenuSettingsButton); await driver.clickElement(selectors.securityAndPrivacySettings); - await driver.findElement(selectors.deletMetaMetricsSettings); await driver.clickElement(selectors.deleteMetaMetricsDataButton); // there is a race condition, where we need to wait before clicking clear button otherwise an error is thrown in the background @@ -157,65 +152,37 @@ describe('Delete MetaMetrics Data @no-mmi', function (this: Suite) { }, ); }); + it('while user has opted out for metrics tracking', async function () { await withFixtures( { fixtures: new FixtureBuilder() .withMetaMetricsController({ metaMetricsId: 'fake-metrics-id', + participateInMetaMetrics: false, }) .build(), defaultGanacheOptions, title: this.test?.fullTitle(), testSpecificMock: mockSegment, }, - async ({ - driver, - mockedEndpoint: mockedEndpoints, - }: TestSuiteArguments) => { + async ({ driver }: TestSuiteArguments) => { await unlockWallet(driver); await driver.clickElement(selectors.accountOptionsMenuButton); await driver.clickElement(selectors.globalMenuSettingsButton); await driver.clickElement(selectors.securityAndPrivacySettings); - await driver.findElement(selectors.deletMetaMetricsSettings); - await driver.clickElement(selectors.deleteMetaMetricsDataButton); - - // there is a race condition, where we need to wait before clicking clear button otherwise an error is thrown in the background - // we cannot wait for a UI conditon, so we a delay to mitigate this until another solution is found - await driver.delay(3000); - await driver.clickElementAndWaitToDisappear(selectors.clearButton); - const deleteMetaMetricsDataButton = await driver.findElement( selectors.deleteMetaMetricsDataButton, ); await ( deleteMetaMetricsDataButton as WebElementWithWaitForElementState ).waitForElementState('disabled'); - - const events = await getEventPayloads( - driver, - mockedEndpoints as MockedEndpoint[], - ); - assert.equal(events.length, 2); - - await driver.clickElementAndWaitToDisappear( - '.mm-box button[aria-label="Close"]', - ); - await driver.clickElement(selectors.accountOptionsMenuButton); - await driver.clickElement(selectors.globalMenuSettingsButton); - await driver.clickElement(selectors.securityAndPrivacySettings); - - const deleteMetaMetricsDataButtonRefreshed = await driver.findElement( - selectors.deleteMetaMetricsDataButton, - ); - await ( - deleteMetaMetricsDataButtonRefreshed as WebElementWithWaitForElementState - ).waitForElementState('disabled'); }, ); }); + it('when the user has never opted in for metrics', async function () { await withFixtures( { @@ -230,7 +197,6 @@ describe('Delete MetaMetrics Data @no-mmi', function (this: Suite) { await driver.clickElement(selectors.accountOptionsMenuButton); await driver.clickElement(selectors.globalMenuSettingsButton); await driver.clickElement(selectors.securityAndPrivacySettings); - await driver.findElement(selectors.deletMetaMetricsSettings); const deleteMetaMetricsDataButton = await driver.findElement( selectors.deleteMetaMetricsDataButton, diff --git a/test/e2e/tests/metrics/errors.spec.js b/test/e2e/tests/metrics/errors.spec.js index 12a44e26fbf1..aaa5c0536485 100644 --- a/test/e2e/tests/metrics/errors.spec.js +++ b/test/e2e/tests/metrics/errors.spec.js @@ -904,6 +904,13 @@ describe('Sentry errors', function () { // the "resetState" method swapsFeatureFlags: true, }, + // Part of the AuthenticationController store, but initialized as undefined + // Only populated once the client is authenticated + sessionData: { + accessToken: false, + expiresIn: true, + profile: true, + }, // This can get erased due to a bug in the app state controller's // preferences state change handler timeoutMinutes: true, diff --git a/test/e2e/tests/metrics/signature-approved.spec.js b/test/e2e/tests/metrics/signature-approved.spec.js index d0d1bb9c32c3..56e376f878ff 100644 --- a/test/e2e/tests/metrics/signature-approved.spec.js +++ b/test/e2e/tests/metrics/signature-approved.spec.js @@ -10,8 +10,6 @@ const { clickSignOnSignatureConfirmation, tempToggleSettingRedesignedConfirmations, validateContractDetails, - clickSignOnRedesignedSignatureConfirmation, - WINDOW_TITLES, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); @@ -60,10 +58,6 @@ const expectedEventPropertiesBase = { security_alert_response: 'loading', }; -const additionalRedesignEventProperties = { - ui_customizations: ['redesigned_confirmation'], -}; - describe('Signature Approved Event @no-mmi', function () { describe('Old confirmation screens', function () { it('Successfully tracked for signTypedData_v4', async function () { @@ -230,172 +224,4 @@ describe('Signature Approved Event @no-mmi', function () { ); }); }); - - describe('Redesigned confirmation screens', function () { - it('Successfully tracked for signTypedData_v4', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withMetaMetricsController({ - metaMetricsId: 'fake-metrics-id', - participateInMetaMetrics: true, - }) - .build(), - defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockSegment, - }, - async ({ driver, mockedEndpoint: mockedEndpoints }) => { - await unlockWallet(driver); - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#signTypedDataV4'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await clickSignOnRedesignedSignatureConfirmation({ driver }); - const events = await getEventPayloads(driver, mockedEndpoints); - - assert.deepStrictEqual(events[0].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData_v4', - eip712_primary_type: 'Mail', - }); - - assert.deepStrictEqual(events[1].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData_v4', - eip712_primary_type: 'Mail', - security_alert_response: 'Benign', - }); - }, - ); - }); - - it('Successfully tracked for signTypedData_v3', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withMetaMetricsController({ - metaMetricsId: 'fake-metrics-id', - participateInMetaMetrics: true, - }) - .build(), - defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockSegment, - }, - async ({ driver, mockedEndpoint: mockedEndpoints }) => { - await unlockWallet(driver); - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#signTypedDataV3'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await clickSignOnRedesignedSignatureConfirmation({ driver }); - const events = await getEventPayloads(driver, mockedEndpoints); - - assert.deepStrictEqual(events[0].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData_v3', - }); - - assert.deepStrictEqual(events[1].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData_v3', - security_alert_response: 'Benign', - }); - }, - ); - }); - - it('Successfully tracked for signTypedData', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withMetaMetricsController({ - metaMetricsId: 'fake-metrics-id', - participateInMetaMetrics: true, - }) - .build(), - defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockSegment, - }, - async ({ driver, mockedEndpoint: mockedEndpoints }) => { - await unlockWallet(driver); - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#signTypedData'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await clickSignOnRedesignedSignatureConfirmation({ driver }); - const events = await getEventPayloads(driver, mockedEndpoints); - - assert.deepStrictEqual(events[0].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData', - }); - - assert.deepStrictEqual(events[1].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'eth_signTypedData', - security_alert_response: 'Benign', - }); - }, - ); - }); - - it('Successfully tracked for personalSign', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withMetaMetricsController({ - metaMetricsId: 'fake-metrics-id', - participateInMetaMetrics: true, - }) - .build(), - defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockSegment, - }, - async ({ driver, mockedEndpoint: mockedEndpoints }) => { - await unlockWallet(driver); - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement('#personalSign'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await clickSignOnRedesignedSignatureConfirmation({ driver }); - const events = await getEventPayloads(driver, mockedEndpoints); - - assert.deepStrictEqual(events[0].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'personal_sign', - }); - - assert.deepStrictEqual(events[1].properties, { - ...expectedEventPropertiesBase, - ...additionalRedesignEventProperties, - signature_type: 'personal_sign', - security_alert_response: 'Benign', - }); - }, - ); - }); - }); }); diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index cae1a6ae8951..0df251bd7661 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -63,14 +63,10 @@ "bridgeState": { "bridgeFeatureFlags": { "extensionConfig": { - "maxRefreshCount": "number", "refreshRate": "number", + "maxRefreshCount": "number", "support": "boolean", - "chains": { - "0x1": "object", - "0xa4b1": "object", - "0xe708": "object" - } + "chains": { "0x1": "object", "0xa4b1": "object", "0xe708": "object" } } }, "srcTokens": {}, @@ -86,7 +82,7 @@ } }, "BridgeStatusController": { "bridgeStatusState": { "txHistory": "object" } }, - "CronjobController": { "jobs": "object" }, + "CronjobController": { "jobs": "object", "events": "object" }, "CurrencyController": { "currentCurrency": "usd", "currencyRates": { @@ -215,7 +211,6 @@ "useNftDetection": false, "use4ByteResolution": true, "useCurrencyRateCheck": true, - "useRequestQueue": true, "openSeaEnabled": false, "securityAlertsEnabled": "boolean", "watchEthereumAccountEnabled": "boolean", @@ -242,11 +237,9 @@ "isRedesignedConfirmationsDeveloperEnabled": "boolean", "tokenSortConfig": "object", "shouldShowAggregatedBalancePopover": "boolean", - "tokenNetworkFilter": { - "0x539": "boolean" - }, + "tokenNetworkFilter": { "0x539": "boolean" }, "redesignedConfirmationsEnabled": true, - "redesignedTransactionsEnabled": "boolean" + "smartTransactionsMigrationApplied": "boolean" }, "ipfsGateway": "string", "isIpfsGatewayEnabled": "boolean", @@ -264,7 +257,7 @@ }, "QueuedRequestController": { "queuedRequestCount": 0 }, "RemoteFeatureFlagController": { - "remoteFeatureFlags": { "feature1": true, "feature2": false }, + "remoteFeatureFlags": {}, "cacheTimestamp": "number" }, "SelectedNetworkController": { "domains": "object" }, @@ -330,9 +323,7 @@ "TokenBalancesController": { "tokenBalances": "object" }, "TokenListController": { "tokenList": "object", - "tokensChainsCache": { - "0x539": "object" - }, + "tokensChainsCache": { "0x539": "object" }, "preventPollingOnNetworkRestart": false }, "TokenRatesController": { "marketData": "object" }, @@ -355,6 +346,7 @@ "isProfileSyncingEnabled": null, "isProfileSyncingUpdateLoading": "boolean", "hasAccountSyncingSyncedAtLeastOnce": "boolean", - "isAccountSyncingReadyToBeDispatched": "boolean" + "isAccountSyncingReadyToBeDispatched": "boolean", + "isAccountSyncingInProgress": "boolean" } } diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index a306c63c70b6..ab3681c55088 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -1,7 +1,71 @@ { "DNS": "object", "activeTab": "object", - "appState": "object", + "appState": { + "customNonceValue": "", + "isAccountMenuOpen": false, + "isNetworkMenuOpen": false, + "nextNonce": null, + "pendingTokens": "object", + "welcomeScreenSeen": false, + "confirmationExchangeRates": {}, + "shouldClose": "boolean", + "menuOpen": "boolean", + "modal": "object", + "alertOpen": "boolean", + "alertMessage": null, + "qrCodeData": null, + "networkDropdownOpen": "boolean", + "importNftsModal": "object", + "showPermittedNetworkToastOpen": "boolean", + "showIpfsModalOpen": "boolean", + "showBasicFunctionalityModal": "boolean", + "externalServicesOnboardingToggleState": "boolean", + "keyringRemovalSnapModal": "object", + "showKeyringRemovalSnapModal": "boolean", + "importTokensModalOpen": "boolean", + "deprecatedNetworkModalOpen": "boolean", + "accountDetail": "object", + "isLoading": "boolean", + "isNftStillFetchingIndication": "boolean", + "showNftDetectionEnablementToast": "boolean", + "loadingMessage": "undefined", + "warning": "string", + "buyView": "object", + "defaultHdPaths": "object", + "networksTabSelectedRpcUrl": "string", + "requestAccountTabs": "object", + "openMetaMaskTabs": "object", + "currentWindowTab": "object", + "showWhatsNewPopup": "boolean", + "showTermsOfUsePopup": "boolean", + "singleExceptions": "object", + "gasLoadingAnimationIsShowing": "boolean", + "smartTransactionsError": null, + "smartTransactionsErrorMessageDismissed": "boolean", + "ledgerWebHidConnectedStatus": "string", + "ledgerTransportStatus": "string", + "newNftAddedMessage": "string", + "removeNftMessage": "string", + "newNetworkAddedName": "string", + "editedNetwork": "undefined", + "newNetworkAddedConfigurationId": "string", + "selectedNetworkConfigurationId": "string", + "sendInputCurrencySwitched": "boolean", + "newTokensImported": "string", + "newTokensImportedError": "string", + "onboardedInThisUISession": "boolean", + "customTokenAmount": "string", + "scrollToBottom": "boolean", + "txId": null, + "accountDetailsAddress": "string", + "showDeleteMetaMetricsDataModal": "boolean", + "showDataDeletionErrorModal": "boolean", + "snapsInstallPrivacyWarningShown": "boolean", + "isAddingNewNetwork": "boolean", + "isMultiRpcOnboarding": "boolean", + "errorInSettings": null + }, "bridge": "object", "confirmAlerts": "object", "confirmTransaction": "object", @@ -12,18 +76,12 @@ "metamask": { "isInitialized": true, "isUnlocked": true, - "isAccountMenuOpen": false, - "isNetworkMenuOpen": false, "internalAccounts": { "accounts": "object", "selectedAccount": "string" }, "transactions": "object", "networkConfigurations": "object", "addressBook": "object", - "confirmationExchangeRates": {}, - "pendingTokens": "object", - "customNonceValue": "", "useBlockie": false, "featureFlags": {}, - "welcomeScreenSeen": false, "currentLocale": "en", "preferences": { "hideZeroBalanceTokens": false, @@ -37,11 +95,9 @@ "isRedesignedConfirmationsDeveloperEnabled": "boolean", "tokenSortConfig": "object", "shouldShowAggregatedBalancePopover": "boolean", - "tokenNetworkFilter": { - "0x539": "boolean" - }, + "tokenNetworkFilter": { "0x539": "boolean" }, "redesignedConfirmationsEnabled": true, - "redesignedTransactionsEnabled": "boolean" + "smartTransactionsMigrationApplied": "boolean" }, "firstTimeFlowType": "import", "completedOnboarding": true, @@ -49,7 +105,6 @@ "use4ByteResolution": true, "participateInMetaMetrics": true, "dataCollectionForMarketing": "boolean", - "nextNonce": null, "currencyRates": { "ETH": { "conversionDate": "number", @@ -122,7 +177,6 @@ "useTokenDetection": true, "useNftDetection": false, "useCurrencyRateCheck": true, - "useRequestQueue": true, "openSeaEnabled": false, "securityAlertsEnabled": "boolean", "watchEthereumAccountEnabled": "boolean", @@ -176,9 +230,7 @@ "gasEstimateType": "none", "nonRPCGasFeeApisDisabled": "boolean", "tokenList": "object", - "tokensChainsCache": { - "0x539": "object" - }, + "tokensChainsCache": { "0x539": "object" }, "preventPollingOnNetworkRestart": false, "tokens": "object", "ignoredTokens": "object", @@ -210,6 +262,7 @@ "cryptocurrencies": ["btc", "sol"], "snaps": "object", "jobs": "object", + "events": "object", "database": null, "lastUpdated": null, "databaseUnavailable": "boolean", @@ -223,6 +276,7 @@ "isProfileSyncingUpdateLoading": "boolean", "hasAccountSyncingSyncedAtLeastOnce": "boolean", "isAccountSyncingReadyToBeDispatched": "boolean", + "isAccountSyncingInProgress": "boolean", "subscriptionAccountsSeen": "object", "isMetamaskNotificationsFeatureSeen": "boolean", "isNotificationServicesEnabled": "boolean", @@ -235,7 +289,7 @@ "isCheckingAccountsPresence": "boolean", "queuedRequestCount": 0, "fcmToken": "string", - "remoteFeatureFlags": { "feature1": true, "feature2": false }, + "remoteFeatureFlags": {}, "cacheTimestamp": "number", "accounts": "object", "accountsByChainId": "object", @@ -280,14 +334,10 @@ "bridgeState": { "bridgeFeatureFlags": { "extensionConfig": { - "maxRefreshCount": "number", "refreshRate": "number", + "maxRefreshCount": "number", "support": "boolean", - "chains": { - "0x1": "object", - "0xa4b1": "object", - "0xe708": "object" - } + "chains": { "0x1": "object", "0xa4b1": "object", "0xe708": "object" } } }, "srcTokens": {}, diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json index c443b0fe84ec..c85bf92f4334 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json @@ -125,7 +125,6 @@ "useTokenDetection": false, "useCurrencyRateCheck": true, "useMultiAccountBalanceChecker": true, - "useRequestQueue": true, "isMultiAccountBalancesEnabled": "boolean", "showIncomingTransactions": "object" }, diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json index 012ccabe6f2f..f86a5278e054 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json @@ -125,7 +125,6 @@ "useTokenDetection": false, "useCurrencyRateCheck": true, "useMultiAccountBalanceChecker": true, - "useRequestQueue": true, "isMultiAccountBalancesEnabled": "boolean", "showIncomingTransactions": "object" }, diff --git a/test/e2e/tests/metrics/swaps.spec.js b/test/e2e/tests/metrics/swaps.spec.js index 6b73e3f400b7..df2137b0157f 100644 --- a/test/e2e/tests/metrics/swaps.spec.js +++ b/test/e2e/tests/metrics/swaps.spec.js @@ -90,6 +90,7 @@ async function mockSegmentAndMetaswapRequests(mockServer) { ]; } +// TODO: (MM-PENDING) These tests are planned for deprecation as part of swaps testing revamp describe('Swap Eth for another Token @no-mmi', function () { it('Completes a Swap between ETH and DAI after changing initial rate', async function () { const { initialBalanceInHex } = genRandInitBal(); diff --git a/test/e2e/tests/multichain/all-permissions-page.spec.ts b/test/e2e/tests/multichain/all-permissions-page.spec.ts index 756bae735f15..4c481520ce81 100644 --- a/test/e2e/tests/multichain/all-permissions-page.spec.ts +++ b/test/e2e/tests/multichain/all-permissions-page.spec.ts @@ -21,7 +21,9 @@ describe('Permissions Page', function () { await loginWithoutBalanceValidation(driver); const testDapp = new TestDapp(driver); await testDapp.openTestDappPage(); - await testDapp.connectAccount(DEFAULT_FIXTURE_ACCOUNT); + await testDapp.connectAccount({ + publicAddress: DEFAULT_FIXTURE_ACCOUNT, + }); // switch to extension window and check the site permissions await driver.switchToWindowWithTitle( @@ -60,7 +62,6 @@ describe('Permissions Page', function () { const experimentalSettings = new ExperimentalSettings(driver); await experimentalSettings.check_pageIsLoaded(); - await experimentalSettings.toggleRequestQueue(); await settingsPage.closeSettingsPage(); // go to homepage and check site permissions diff --git a/test/e2e/tests/network/network-error.spec.js b/test/e2e/tests/network/network-error.spec.js deleted file mode 100644 index 61842f482151..000000000000 --- a/test/e2e/tests/network/network-error.spec.js +++ /dev/null @@ -1,83 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - logInWithBalanceValidation, - openActionMenuAndStartSendFlow, - generateGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); -const { GAS_API_BASE_URL } = require('../../../../shared/constants/swaps'); - -describe('Gas API fallback', function () { - async function mockGasApiDown(mockServer) { - await mockServer - .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) - .always() - .thenCallback(() => { - return { - statusCode: 200, - json: { - low: { - minWaitTimeEstimate: 180000, - maxWaitTimeEstimate: 300000, - suggestedMaxPriorityFeePerGas: '3', - suggestedMaxFeePerGas: '53', - }, - medium: { - minWaitTimeEstimate: 15000, - maxWaitTimeEstimate: 60000, - suggestedMaxPriorityFeePerGas: '7', - suggestedMaxFeePerGas: '70', - }, - high: { - minWaitTimeEstimate: 0, - maxWaitTimeEstimate: 15000, - suggestedMaxPriorityFeePerGas: '10', - suggestedMaxFeePerGas: '100', - }, - estimatedBaseFee: '50', - networkCongestion: 0.9, - latestPriorityFeeRange: ['1', '20'], - historicalPriorityFeeRange: ['2', '125'], - historicalBaseFeeRange: ['50', '100'], - priorityFeeTrend: 'up', - baseFeeTrend: 'down', - }, - }; - }); - } - - it('network error message is displayed if network is congested', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - testSpecificMock: mockGasApiDown, - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - const inputAmount = await driver.findElement('input[placeholder="0"]'); - await inputAmount.fill('1'); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - const error = await driver.isElementPresent( - '[data-testid="network-busy-tooltip"]', - ); - - assert.equal(error, true, 'Network error is present'); - }, - ); - }); -}); diff --git a/test/e2e/tests/petnames/petnames-signatures.spec.js b/test/e2e/tests/petnames/petnames-signatures.spec.js index 4641424e053f..1ca7f47340d7 100644 --- a/test/e2e/tests/petnames/petnames-signatures.spec.js +++ b/test/e2e/tests/petnames/petnames-signatures.spec.js @@ -169,7 +169,7 @@ describe('Petnames - Signatures', function () { await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V4); await switchToNotificationWindow(driver, 3); await expectName(driver, 'test.lens', true); - await expectName(driver, 'Test Token 2', true); + await expectName(driver, 'Test Toke...', true); await showThirdPartyDetails(driver); await expectName(driver, 'Custom Name', true); }, @@ -269,7 +269,7 @@ describe('Petnames - Signatures', function () { await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V4); await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); await expectName(driver, 'test.lens', true); - await expectName(driver, 'Test Token 2', true); + await expectName(driver, 'Test Toke...', true); await expectName(driver, 'Custom Name', true); }, ); diff --git a/test/e2e/tests/petnames/petnames-transactions.spec.js b/test/e2e/tests/petnames/petnames-transactions.spec.js index 5546de0b4b82..e6ddf0229e99 100644 --- a/test/e2e/tests/petnames/petnames-transactions.spec.js +++ b/test/e2e/tests/petnames/petnames-transactions.spec.js @@ -5,13 +5,11 @@ const { unlockWallet, defaultGanacheOptions, openActionMenuAndStartSendFlow, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); const { expectName, focusTestDapp, - rejectSignatureOrTransactionRequest, saveName, rejectRedesignedSignatureOrTransactionRequest, } = require('./petnames-helpers'); @@ -38,196 +36,86 @@ const CUSTOM_NAME_MOCK = 'Custom Name'; const PROPOSED_NAME_MOCK = 'test4.lens'; describe('Petnames - Transactions', function () { - describe('Old confirmation screens', function () { - it('can save petnames for addresses in dapp send transactions', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withNoNames() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); - - // Test custom name. - await saveName( - driver, - ABBREVIATED_ADDRESS_MOCK, - CUSTOM_NAME_MOCK, - undefined, - ); - await rejectSignatureOrTransactionRequest(driver); - await focusTestDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, CUSTOM_NAME_MOCK, true); - - // Test proposed name. - await saveName( - driver, - CUSTOM_NAME_MOCK, - undefined, - PROPOSED_NAME_MOCK, - ); - await rejectSignatureOrTransactionRequest(driver); - await focusTestDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, PROPOSED_NAME_MOCK, true); - }, - ); - }); - - it('can save petnames for addresses in wallet send transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .withNoNames() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); - - // Test custom name. - await saveName( - driver, - ABBREVIATED_ADDRESS_MOCK, - CUSTOM_NAME_MOCK, - undefined, - ); - await rejectSignatureOrTransactionRequest(driver); - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, CUSTOM_NAME_MOCK, true); - - // Test proposed name. - await saveName( - driver, - CUSTOM_NAME_MOCK, - undefined, - PROPOSED_NAME_MOCK, - ); - await rejectSignatureOrTransactionRequest(driver); - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, PROPOSED_NAME_MOCK, true); - }, - ); - }); + it('can save petnames for addresses in dapp send transactions', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .withNoNames() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await openDapp(driver); + await createDappSendTransaction(driver); + await switchToNotificationWindow(driver, 3); + await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); + + // Test custom name. + await saveName( + driver, + ABBREVIATED_ADDRESS_MOCK, + CUSTOM_NAME_MOCK, + undefined, + ); + await rejectRedesignedSignatureOrTransactionRequest(driver); + await focusTestDapp(driver); + await createDappSendTransaction(driver); + await switchToNotificationWindow(driver, 3); + await expectName(driver, CUSTOM_NAME_MOCK, true); + + // Test proposed name. + await saveName(driver, CUSTOM_NAME_MOCK, undefined, PROPOSED_NAME_MOCK); + await rejectRedesignedSignatureOrTransactionRequest(driver); + await focusTestDapp(driver); + await createDappSendTransaction(driver); + await switchToNotificationWindow(driver, 3); + await expectName(driver, PROPOSED_NAME_MOCK, true); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('can save petnames for addresses in dapp send transactions', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withNoNames() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); - - // Test custom name. - await saveName( - driver, - ABBREVIATED_ADDRESS_MOCK, - CUSTOM_NAME_MOCK, - undefined, - ); - await rejectRedesignedSignatureOrTransactionRequest(driver); - await focusTestDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, CUSTOM_NAME_MOCK, true); - - // Test proposed name. - await saveName( - driver, - CUSTOM_NAME_MOCK, - undefined, - PROPOSED_NAME_MOCK, - ); - await rejectRedesignedSignatureOrTransactionRequest(driver); - await focusTestDapp(driver); - await createDappSendTransaction(driver); - await switchToNotificationWindow(driver, 3); - await expectName(driver, PROPOSED_NAME_MOCK, true); - }, - ); - }); - - it('can save petnames for addresses in wallet send transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .withNoNames() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); - - // Test custom name. - await saveName( - driver, - ABBREVIATED_ADDRESS_MOCK, - CUSTOM_NAME_MOCK, - undefined, - ); - await rejectRedesignedSignatureOrTransactionRequest(driver); - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, CUSTOM_NAME_MOCK, true); - - // Test proposed name. - await saveName( - driver, - CUSTOM_NAME_MOCK, - undefined, - PROPOSED_NAME_MOCK, - ); - await rejectRedesignedSignatureOrTransactionRequest(driver); - await createWalletSendTransaction(driver, ADDRESS_MOCK); - await expectName(driver, PROPOSED_NAME_MOCK, true); - }, - ); - }); + it('can save petnames for addresses in wallet send transactions', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesController({ + featureFlags: { + sendHexData: true, + }, + }) + .withNoNames() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createWalletSendTransaction(driver, ADDRESS_MOCK); + await expectName(driver, ABBREVIATED_ADDRESS_MOCK, false); + + // Test custom name. + await saveName( + driver, + ABBREVIATED_ADDRESS_MOCK, + CUSTOM_NAME_MOCK, + undefined, + ); + await rejectRedesignedSignatureOrTransactionRequest(driver); + await createWalletSendTransaction(driver, ADDRESS_MOCK); + await expectName(driver, CUSTOM_NAME_MOCK, true); + + // Test proposed name. + await saveName(driver, CUSTOM_NAME_MOCK, undefined, PROPOSED_NAME_MOCK); + await rejectRedesignedSignatureOrTransactionRequest(driver); + await createWalletSendTransaction(driver, ADDRESS_MOCK); + await expectName(driver, PROPOSED_NAME_MOCK, true); + }, + ); }); }); diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.js b/test/e2e/tests/portfolio/portfolio-site.spec.js deleted file mode 100644 index cba9c0452522..000000000000 --- a/test/e2e/tests/portfolio/portfolio-site.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -const { - withFixtures, - unlockWallet, - defaultGanacheOptions, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); -const { emptyHtmlPage } = require('../../mock-e2e'); - -describe('Portfolio site', function () { - async function mockPortfolioSite(mockServer) { - return await mockServer - .forGet('https://portfolio.metamask.io/') - .withQuery({ - metamaskEntry: 'ext_portfolio_button', - metametricsId: 'null', - }) - .thenCallback(() => { - return { - statusCode: 200, - body: emptyHtmlPage(), - }; - }); - } - - it('should link to the portfolio site @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockPortfolioSite, - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Click Portfolio site - await driver.clickElement('[data-testid="portfolio-link"]'); - await driver.waitUntilXWindowHandles(2); - const windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle('E2E Test Page', windowHandles); - - // Verify site - await driver.waitForUrl({ - url: 'https://portfolio.metamask.io/?metamaskEntry=ext_portfolio_button&metametricsId=null&metricsEnabled=false&marketingEnabled=false', - }); - }, - ); - }); -}); diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.ts b/test/e2e/tests/portfolio/portfolio-site.spec.ts new file mode 100644 index 000000000000..d7952b5f1baa --- /dev/null +++ b/test/e2e/tests/portfolio/portfolio-site.spec.ts @@ -0,0 +1,50 @@ +import { MockttpServer } from 'mockttp'; +import { withFixtures } from '../../helpers'; +import { PORTFOLIO_PAGE_TITLE, MOCK_META_METRICS_ID } from '../../constants'; +import FixtureBuilder from '../../fixture-builder'; +import { emptyHtmlPage } from '../../mock-e2e'; +import HomePage from '../../page-objects/pages/home/homepage'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +describe('Portfolio site', function () { + async function mockPortfolioSite(mockServer: MockttpServer) { + return await mockServer + .forGet('https://portfolio.metamask.io/') + .withQuery({ + metamaskEntry: 'ext_portfolio_button', + metametricsId: 'null', + }) + .thenCallback(() => { + return { + statusCode: 200, + body: emptyHtmlPage(), + }; + }); + } + + it('should link to the portfolio site @no-mmi', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withMetaMetricsController({ + metaMetricsId: MOCK_META_METRICS_ID, + participateInMetaMetrics: true, + }) + .build(), + title: this.test?.fullTitle(), + testSpecificMock: mockPortfolioSite, + }, + async ({ driver }) => { + await loginWithBalanceValidation(driver); + await new HomePage(driver).openPortfolioPage(); + await driver.switchToWindowWithTitle(PORTFOLIO_PAGE_TITLE); + + // Verify site + await driver.waitForUrl({ + url: `https://portfolio.metamask.io/?metamaskEntry=ext_portfolio_button&metametricsId=${MOCK_META_METRICS_ID}&metricsEnabled=true&marketingEnabled=false`, + }); + }, + ); + }); +}); diff --git a/test/e2e/tests/ppom/ppom-blockaid-alert-contract-interaction.spec.js b/test/e2e/tests/ppom/ppom-blockaid-alert-contract-interaction.spec.js index e35c23f22c49..f499bd13abbc 100644 --- a/test/e2e/tests/ppom/ppom-blockaid-alert-contract-interaction.spec.js +++ b/test/e2e/tests/ppom/ppom-blockaid-alert-contract-interaction.spec.js @@ -195,7 +195,6 @@ describe('PPOM Blockaid Alert - Malicious Contract interaction @no-mmi', functio .withPreferencesController({ securityAlertsEnabled: true, preferences: { - redesignedTransactionsEnabled: true, redesignedConfirmationsEnabled: true, isRedesignedConfirmationsDeveloperEnabled: true, }, diff --git a/test/e2e/tests/ppom/ppom-blockaid-alert-simple-send.spec.js b/test/e2e/tests/ppom/ppom-blockaid-alert-simple-send.spec.js index 370aab17a499..d3d0da9020cd 100644 --- a/test/e2e/tests/ppom/ppom-blockaid-alert-simple-send.spec.js +++ b/test/e2e/tests/ppom/ppom-blockaid-alert-simple-send.spec.js @@ -6,7 +6,6 @@ const { sendScreenToConfirmScreen, logInWithBalanceValidation, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const { mockMultiNetworkBalancePolling, @@ -119,157 +118,113 @@ async function mockInfuraWithFailedResponses(mockServer) { * @see {@link https://wobbly-nutmeg-8a5.notion.site/MM-E2E-Testing-1e51b617f79240a49cd3271565c6e12d} */ describe('Simple Send Security Alert - Blockaid @no-mmi', function () { - describe('Old confirmation screens', function () { - it('should show "Be careful" if the PPOM request fails to check transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerOnMainnet() - .withPreferencesController({ - securityAlertsEnabled: true, - }) - .build(), - defaultGanacheOptions, - testSpecificMock: mockInfuraWithFailedResponses, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await logInWithBalanceValidation(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await sendScreenToConfirmScreen( - driver, - '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', - '1.1', - ); - const expectedTitle = 'Be careful'; - - const bannerAlert = await driver.findElement({ - css: bannerAlertSelector, - text: expectedTitle, - }); - - assert( - bannerAlert, - `Banner alert not found. Expected Title: ${expectedTitle}`, - ); - }, - ); - }); + it('should not show security alerts for benign requests', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerOnMainnet() + .withPreferencesController({ + securityAlertsEnabled: true, + }) + .build(), + defaultGanacheOptions, + testSpecificMock: mockInfuraWithBenignResponses, + title: this.test.fullTitle(), + }, + + async ({ driver }) => { + await logInWithBalanceValidation(driver); + + await sendScreenToConfirmScreen(driver, mockBenignAddress, '1'); + + const isPresent = await driver.isElementPresent(bannerAlertSelector); + assert.equal(isPresent, false, `Banner alert unexpectedly found.`); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should not show security alerts for benign requests', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerOnMainnet() - .withPreferencesController({ - securityAlertsEnabled: true, - }) - .build(), - defaultGanacheOptions, - testSpecificMock: mockInfuraWithBenignResponses, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await logInWithBalanceValidation(driver); - - await sendScreenToConfirmScreen(driver, mockBenignAddress, '1'); - - const isPresent = await driver.isElementPresent(bannerAlertSelector); - assert.equal(isPresent, false, `Banner alert unexpectedly found.`); - }, - ); - }); - - /** - * Disclaimer: This test does not test all reason types. e.g. 'blur_farming', - * 'malicious_domain'. Some other tests are found in other files: - * e.g. test/e2e/flask/ppom-blockaid-alert-.spec.js - */ - it('should show security alerts for malicious requests', async function () { - await withFixtures( - // we need to use localhost instead of the ip - // see issue: https://github.com/MetaMask/MetaMask-planning/issues/3560 - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerOnMainnet() - .withPermissionControllerConnectedToTestDapp({ - useLocalhostHostname: true, - }) - .withPreferencesController({ - securityAlertsEnabled: true, - }) - .build(), - defaultGanacheOptions, - testSpecificMock: mockInfuraWithMaliciousResponses, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await logInWithBalanceValidation(driver); - - await driver.openNewPage('http://localhost:8080'); - - await driver.clickElement('#maliciousRawEthButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector({ - css: '.mm-text--body-lg-medium', - text: expectedMaliciousTitle, - }); - - await driver.waitForSelector({ - css: '.mm-text--body-md', - text: expectedMaliciousDescription, - }); - }, - ); - }); - - it('should show "Be careful" if the PPOM request fails to check transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerOnMainnet() - .withPreferencesController({ - securityAlertsEnabled: true, - }) - .build(), - defaultGanacheOptions, - testSpecificMock: mockInfuraWithFailedResponses, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await logInWithBalanceValidation(driver); - - await sendScreenToConfirmScreen( - driver, - '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', - '1.1', - ); - const expectedTitle = 'Be careful'; - - const bannerAlert = await driver.findElement({ - css: '[data-testid="confirm-banner-alert"]', - text: expectedTitle, - }); + /** + * Disclaimer: This test does not test all reason types. e.g. 'blur_farming', + * 'malicious_domain'. Some other tests are found in other files: + * e.g. test/e2e/flask/ppom-blockaid-alert-.spec.js + */ + it('should show security alerts for malicious requests', async function () { + await withFixtures( + // we need to use localhost instead of the ip + // see issue: https://github.com/MetaMask/MetaMask-planning/issues/3560 + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerOnMainnet() + .withPermissionControllerConnectedToTestDapp({ + useLocalhostHostname: true, + }) + .withPreferencesController({ + securityAlertsEnabled: true, + }) + .build(), + defaultGanacheOptions, + testSpecificMock: mockInfuraWithMaliciousResponses, + title: this.test.fullTitle(), + }, + + async ({ driver }) => { + await logInWithBalanceValidation(driver); + + await driver.openNewPage('http://localhost:8080'); + + await driver.clickElement('#maliciousRawEthButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.waitForSelector({ + css: '.mm-text--body-lg-medium', + text: expectedMaliciousTitle, + }); + + await driver.waitForSelector({ + css: '.mm-text--body-md', + text: expectedMaliciousDescription, + }); + }, + ); + }); - assert( - bannerAlert, - `Banner alert not found. Expected Title: ${expectedTitle}`, - ); - }, - ); - }); + it('should show "Be careful" if the PPOM request fails to check transaction', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerOnMainnet() + .withPreferencesController({ + securityAlertsEnabled: true, + }) + .build(), + defaultGanacheOptions, + testSpecificMock: mockInfuraWithFailedResponses, + title: this.test.fullTitle(), + }, + + async ({ driver }) => { + await logInWithBalanceValidation(driver); + + await sendScreenToConfirmScreen( + driver, + '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', + '1.1', + ); + const expectedTitle = 'Be careful'; + + const bannerAlert = await driver.findElement({ + css: '[data-testid="confirm-banner-alert"]', + text: expectedTitle, + }); + + assert( + bannerAlert, + `Banner alert not found. Expected Title: ${expectedTitle}`, + ); + }, + ); }); }); diff --git a/test/e2e/tests/privacy-mode/privacy-mode.spec.js b/test/e2e/tests/privacy-mode/privacy-mode.spec.js deleted file mode 100644 index ede37f900e66..000000000000 --- a/test/e2e/tests/privacy-mode/privacy-mode.spec.js +++ /dev/null @@ -1,106 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - unlockWallet, - defaultGanacheOptions, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Privacy Mode', function () { - it('should activate privacy mode, then deactivate it', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withPreferencesController().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - async function checkForHeaderValue(value) { - const balanceElement = await driver.findElement( - '[data-testid="account-value-and-suffix"]', - ); - const surveyText = await balanceElement.getText(); - assert.equal( - surveyText, - value, - `Header balance should be "${value}"`, - ); - } - - async function checkForTokenValue(value) { - const balanceElement = await driver.findElement( - '[data-testid="multichain-token-list-item-value"]', - ); - const surveyText = await balanceElement.getText(); - assert.equal(surveyText, value, `Token balance should be "${value}"`); - } - - async function checkForPrivacy() { - await checkForHeaderValue('••••••'); - await checkForTokenValue('••••••'); - } - - async function checkForNoPrivacy() { - await checkForHeaderValue('25'); - await checkForTokenValue('25 ETH'); - } - - async function togglePrivacy() { - const balanceElement = await driver.findElement( - '[data-testid="account-value-and-suffix"]', - ); - const initialText = await balanceElement.getText(); - - await driver.clickElement('[data-testid="sensitive-toggle"]'); - await driver.wait(async () => { - const currentText = await balanceElement.getText(); - return currentText !== initialText; - }, 2e3); - } - - await unlockWallet(driver); - await checkForNoPrivacy(); - await togglePrivacy(); - await checkForPrivacy(); - await togglePrivacy(); - await checkForNoPrivacy(); - }, - ); - }); - - it('should hide fiat balance and token balance when privacy mode is activated', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().withPreferencesController().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - async function togglePrivacy() { - const balanceElement = await driver.findElement( - '[data-testid="account-value-and-suffix"]', - ); - const initialText = await balanceElement.getText(); - - await driver.clickElement('[data-testid="sensitive-toggle"]'); - await driver.wait(async () => { - const currentText = await balanceElement.getText(); - return currentText !== initialText; - }, 2e3); - } - - await togglePrivacy(); - await driver.clickElement('[data-testid="account-menu-icon"]'); - const valueText = await driver.findElement( - '[data-testid="account-value-and-suffix"]', - ); - const valueTextContent = await valueText.getText(); - - assert.equal(valueTextContent, '••••••'); - }, - ); - }); -}); diff --git a/test/e2e/tests/privacy-mode/privacy-mode.spec.ts b/test/e2e/tests/privacy-mode/privacy-mode.spec.ts new file mode 100644 index 000000000000..60d9faedc080 --- /dev/null +++ b/test/e2e/tests/privacy-mode/privacy-mode.spec.ts @@ -0,0 +1,74 @@ +import { Driver } from '../../webdriver/driver'; +import { defaultGanacheOptions, withFixtures } from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; +import AccountListPage from '../../page-objects/pages/account-list-page'; +import HeaderNavbar from '../../page-objects/pages/header-navbar'; +import HomePage from '../../page-objects/pages/home/homepage'; +import { + loginWithBalanceValidation, + loginWithoutBalanceValidation, +} from '../../page-objects/flows/login.flow'; +import { Ganache } from '../../seeder/ganache'; + +describe('Privacy Mode', function () { + it('should hide fiat balance and token balance when privacy mode is activated', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ + driver, + ganacheServer, + }: { + driver: Driver; + ganacheServer: Ganache; + }) => { + await loginWithBalanceValidation(driver, ganacheServer); + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.togglePrivacyBalance(); + await homePage.check_expectedBalanceIsDisplayed('••••••', '••••••'); + + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.openAccountMenu(); + + const accountList = new AccountListPage(driver); + await accountList.check_pageIsLoaded(); + await accountList.check_balanceIsPrivateEverywhere(); + }, + ); + }); + + it('should show fiat balance and token balance when privacy mode is deactivated', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesController({ + preferences: { + privacyMode: true, + }, + }) + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ driver }: { driver: Driver }) => { + await loginWithoutBalanceValidation(driver); + + const homePage = new HomePage(driver); + await homePage.check_pageIsLoaded(); + await homePage.togglePrivacyBalance(); + await homePage.check_expectedBalanceIsDisplayed('25 ETH'); + + const headerNavbar = new HeaderNavbar(driver); + await headerNavbar.openAccountMenu(); + + const accountList = new AccountListPage(driver); + await accountList.check_pageIsLoaded(); + await accountList.check_accountBalanceDisplayed('25'); + }, + ); + }); +}); diff --git a/test/e2e/tests/remote-feature-flag/mock-data.ts b/test/e2e/tests/remote-feature-flag/mock-data.ts index 5d05dc9367f9..f9da6d052f19 100644 --- a/test/e2e/tests/remote-feature-flag/mock-data.ts +++ b/test/e2e/tests/remote-feature-flag/mock-data.ts @@ -1,4 +1,8 @@ export const MOCK_REMOTE_FEATURE_FLAGS_RESPONSE = { feature1: true, feature2: false, + feature3: { + name: 'groupC', + value: 'valueC', + }, }; diff --git a/test/e2e/tests/remote-feature-flag/remote-feature-flag.spec.ts b/test/e2e/tests/remote-feature-flag/remote-feature-flag.spec.ts index d8d6878e37c4..42ebe7dc762c 100644 --- a/test/e2e/tests/remote-feature-flag/remote-feature-flag.spec.ts +++ b/test/e2e/tests/remote-feature-flag/remote-feature-flag.spec.ts @@ -4,13 +4,19 @@ import { getCleanAppState, withFixtures } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; import { TestSuiteArguments } from '../confirmations/transactions/shared'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; +import { MOCK_META_METRICS_ID } from '../../constants'; import { MOCK_REMOTE_FEATURE_FLAGS_RESPONSE } from './mock-data'; describe('Remote feature flag', function (this: Suite) { - it('should be fetched when basic functionality toggle is on', async function () { + it('should be fetched with threshold value when basic functionality toggle is on', async function () { await withFixtures( { - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder() + .withMetaMetricsController({ + metaMetricsId: MOCK_META_METRICS_ID, + participateInMetaMetrics: true, + }) + .build(), title: this.test?.fullTitle(), }, async ({ driver }: TestSuiteArguments) => { diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js index 958c1351d8b3..659ed4cfbc41 100644 --- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js +++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js @@ -9,246 +9,119 @@ const { WINDOW_TITLES, defaultGanacheOptions, largeDelayMs, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing for Multiple Dapps and Txs on different networks', function () { - describe('Old confirmation screens', function () { - it('should batch confirmation txs for different dapps on different networks.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should batch confirmation txs for different dapps on different networks.', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, + title: this.test.fullTitle(), + }, - async ({ driver }) => { - await unlockWallet(driver); + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Connect to dapp 1 + await driver.clickElement({ text: 'Connect', tag: 'button' }); - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); + // Wait for the first dapp's connect confirmation to disappear + await driver.waitUntilXWindowHandles(2); - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); + // Connect to dapp 2 + await driver.clickElement({ text: 'Connect', tag: 'button' }); - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + // Dapp one send tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); - // Dapp one send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); + await driver.delay(largeDelayMs); - await driver.delay(largeDelayMs); + // Dapp two send tx + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); - // Dapp two send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Reject all', + tag: 'button', + }); - // Reject All Transactions - await driver.clickElement('.page-container__footer-secondary a'); + // Wait for confirmation to close + await driver.delay(2000); - // TODO: Do we want to confirm here? - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); + // Wait for new confirmations queued from second dapp to open + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Wait for confirmation to close - // TODO: find a better way to handle different dialog ids - await driver.delay(2000); + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); - // Wait for new confirmations queued from second dapp to open - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - }, - ); - }); - }); - - describe('Redesigned confirmation screens', function () { - it('should batch confirmation txs for different dapps on different networks.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Dapp one send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.delay(largeDelayMs); - - // Dapp two send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); - - // Wait for confirmation to close - await driver.delay(2000); - - // Wait for new confirmations queued from second dapp to open - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); - }, - ); - }); + // Check correct network on confirm tx. + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js index 066acacab23a..2c56b23e03cc 100644 --- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js +++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js @@ -9,326 +9,159 @@ const { unlockWallet, WINDOW_TITLES, withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing for Multiple Dapps and Txs on different networks', function () { - describe('Old confirmation flows', function () { - it('should batch confirmation txs for different dapps on different networks adds extra tx after.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should batch confirmation txs for different dapps on different networks adds extra tx after.', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Ensure Dapp One is on Localhost 8546 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Should auto switch without prompt since already approved via connect - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // Dapp 1 send 2 tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); - - // Dapp 2 send 2 tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - // We cannot wait for the dialog, since it is already opened from before - await driver.delay(largeDelayMs); - - // Dapp 1 send 1 tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - // We cannot switch directly, as the dialog is sometimes closed and re-opened - await driver.delay(largeDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); - - // Reject All Transactions - await driver.clickElement('.page-container__footer-secondary a'); - - // TODO: Do we want to confirm here? - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - // Wait for new confirmations queued from second dapp to open - // We need a big delay to make sure dialog is not invalidated - // TODO: find a better way to handle different dialog ids - await driver.delay(2000); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - - // Reject All Transactions - await driver.clickElement('.page-container__footer-secondary a'); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); - - // Wait for new confirmations queued from second dapp to open - // We need a big delay to make sure dialog is not invalidated - // TODO: find a better way to handle different dialog ids - await driver.delay(2000); - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - }, - ); - }); - }); - - describe('Redesigned confirmation flows', function () { - it('should batch confirmation txs for different dapps on different networks adds extra tx after.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Ensure Dapp One is on Localhost 8546 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Should auto switch without prompt since already approved via connect - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // Dapp 1 send 2 tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); - - // Dapp 2 send 2 tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - // We cannot wait for the dialog, since it is already opened from before - await driver.delay(largeDelayMs); - - // Dapp 1 send 1 tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - // We cannot switch directly, as the dialog is sometimes closed and re-opened - await driver.delay(largeDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - // Reject All Transactions - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - // Wait for new confirmations queued from second dapp to open - // We need a big delay to make sure dialog is not invalidated - // TODO: find a better way to handle different dialog ids - await driver.delay(2000); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); - - // Reject All Transactions - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject all', - tag: 'button', - }); - - // Wait for new confirmations queued from second dapp to open - // We need a big delay to make sure dialog is not invalidated - // TODO: find a better way to handle different dialog ids - await driver.delay(2000); - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - }, - ); - }); + title: this.test.fullTitle(), + }, + + async ({ driver }) => { + await unlockWallet(driver); + + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); + + // Connect to dapp 1 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + await driver.switchToWindowWithUrl(DAPP_URL); + + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x53a' }], + }); + + // Ensure Dapp One is on Localhost 8546 + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + + // Should auto switch without prompt since already approved via connect + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Wait for the first dapp's connect confirmation to disappear + await driver.waitUntilXWindowHandles(2); + + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); + + // Connect to dapp 2 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + // Dapp 1 send 2 tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x53a', + }); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); + + await driver.waitUntilXWindowHandles(4); + + // Dapp 2 send 2 tx + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x53a', + }); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); + // We cannot wait for the dialog, since it is already opened from before + await driver.delay(largeDelayMs); + + // Dapp 1 send 1 tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x53a', + }); + await driver.clickElement('#sendButton'); + // We cannot switch directly, as the dialog is sometimes closed and re-opened + await driver.delay(largeDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); + + // Reject All Transactions + await driver.clickElementAndWaitForWindowToClose({ + text: 'Reject all', + tag: 'button', + }); + + await driver.switchToWindowWithUrl(DAPP_URL); + + // Wait for new confirmations queued from second dapp to open + // We need a big delay to make sure dialog is not invalidated + // TODO: find a better way to handle different dialog ids + await driver.delay(2000); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); + + // Check correct network on confirm tx. + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); + + // Reject All Transactions + await driver.clickElementAndWaitForWindowToClose({ + text: 'Reject all', + tag: 'button', + }); + + // Wait for new confirmations queued from second dapp to open + // We need a big delay to make sure dialog is not invalidated + // TODO: find a better way to handle different dialog ids + await driver.delay(2000); + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js index d3241c95c9d5..7ba5ca579298 100644 --- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js +++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js @@ -10,317 +10,156 @@ const { WINDOW_TITLES, defaultGanacheOptions, largeDelayMs, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing for Multiple Dapps and Txs on same networks', function () { - describe('Old confirmation screens', function () { - it('should batch confirmation txs for different dapps on same networks ', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 3 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should batch confirmation txs for different dapps on same networks ', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + .build(), + dappOptions: { numberOfDapps: 3 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, + title: this.test.fullTitle(), + }, - async ({ driver }) => { - await unlockWallet(driver); + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Connect to dapp 1 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - // Connect to dapp 1 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + await driver.delay(regularDelayMs); - await driver.delay(regularDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithUrl(DAPP_URL); - await driver.switchToWindowWithUrl(DAPP_URL); + let switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x3e8' }], + }); - let switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x3e8' }], - }); + // Ensure Dapp One is on Localhost 7777 + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); - // Ensure Dapp One is on Localhost 7777 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); + // Should auto switch without prompt since already approved via connect - // Should auto switch without prompt since already approved via connect + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + // Wait for the first dapp's connect confirmation to disappear + await driver.waitUntilXWindowHandles(2); - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); + // Connect to dapp 2 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + await driver.delay(regularDelayMs); - await driver.delay(regularDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); + switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x53a' }], + }); - switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); + // Ensure Dapp Two is on Localhost 8545 + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); - // Ensure Dapp Two is on Localhost 8545 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); + // Should auto switch without prompt since already approved via connect - // Should auto switch without prompt since already approved via connect + // Dapp one send two tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); - // Dapp one send two tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); + await driver.delay(largeDelayMs); - await driver.delay(largeDelayMs); + // Dapp two send two tx + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); - // Dapp two send two tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); + // Check correct network on confirm tx. + await driver.findElement({ + css: 'p', + text: 'Localhost 7777', + }); - // Check correct network on confirm tx. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 7777', - }); + // Reject All Transactions + await driver.clickElement({ text: 'Reject all', tag: 'button' }); - // Reject All Transactions - await driver.clickElement('.page-container__footer-secondary a'); + // Wait for confirmation to close + await driver.waitUntilXWindowHandles(4); - await driver.clickElement({ text: 'Reject all', tag: 'button' }); // TODO: Do we want to confirm here? + // Wait for new confirmations queued from second dapp to open + await driver.delay(largeDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Wait for confirmation to close - await driver.waitUntilXWindowHandles(4); + await driver.waitForSelector( + By.xpath("//p[normalize-space(.)='1 of 2']"), + ); - // Wait for new confirmations queued from second dapp to open - await driver.delay(largeDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//div[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - }, - ); - }); - }); - - describe('Redesigned confirmation screens', function () { - it('should batch confirmation txs for different dapps on same networks ', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 3 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - let switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x3e8' }], - }); - - // Ensure Dapp One is on Localhost 7777 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Should auto switch without prompt since already approved via connect - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Ensure Dapp Two is on Localhost 8545 - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - // Should auto switch without prompt since already approved via connect - - // Dapp one send two tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.delay(largeDelayMs); - - // Dapp two send two tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: 'p', - text: 'Localhost 7777', - }); - - // Reject All Transactions - await driver.clickElement({ text: 'Reject all', tag: 'button' }); - - // Wait for confirmation to close - await driver.waitUntilXWindowHandles(4); - - // Wait for new confirmations queued from second dapp to open - await driver.delay(largeDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector( - By.xpath("//p[normalize-space(.)='1 of 2']"), - ); - - // Check correct network on confirm tx. - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); - }, - ); - }); + // Check correct network on confirm tx. + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/chainid-check.spec.js b/test/e2e/tests/request-queuing/chainid-check.spec.js index 1579a8ae5aa4..95ed3ca6bd8c 100644 --- a/test/e2e/tests/request-queuing/chainid-check.spec.js +++ b/test/e2e/tests/request-queuing/chainid-check.spec.js @@ -13,304 +13,145 @@ const { const { PAGES } = require('../../webdriver/driver'); describe('Request Queueing chainId proxy sync', function () { - describe('request queue is on', function () { - it('should preserve per dapp network selections after connecting and switching without refresh calls @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should preserve per dapp network selections after connecting and switching without refresh calls @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + + .withSelectedNetworkControllerPerDomain() + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - // Navigate to extension home screen - await driver.navigate(PAGES.HOME); + // Navigate to extension home screen + await driver.navigate(PAGES.HOME); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - await driver.delay(regularDelayMs); + await driver.delay(regularDelayMs); - const chainIdRequest = JSON.stringify({ - method: 'eth_chainId', - }); + const chainIdRequest = JSON.stringify({ + method: 'eth_chainId', + }); - const chainIdBeforeConnect = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); - - assert.equal(chainIdBeforeConnect, '0x539'); // 1337 - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Ethereum Mainnet', - css: 'p', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + const chainIdBeforeConnect = await driver.executeScript( + `return window.ethereum.request(${chainIdRequest})`, + ); - const chainIdBeforeConnectAfterManualSwitch = - await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); + assert.equal(chainIdBeforeConnect, '0x539'); // 1337 - // before connecting the chainId should change with the wallet - assert.equal(chainIdBeforeConnectAfterManualSwitch, '0x1'); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await switchToNotificationWindow(driver); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const chainIdAfterConnect = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - // should still be on the same chainId as the wallet after connecting - assert.equal(chainIdAfterConnect, '0x1'); + // Switch to second network + await driver.clickElement({ + text: 'Ethereum Mainnet', + css: 'p', + }); - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + const chainIdBeforeConnectAfterManualSwitch = await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - await switchToNotificationWindow(driver); - await driver.findClickableElements({ - text: 'Confirm', - tag: 'button', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const chainIdAfterDappSwitch = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); - - // should be on the new chainId that was requested - assert.equal(chainIdAfterDappSwitch, '0x539'); // 1337 - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const chainIdAfterManualSwitch = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); - // after connecting the dapp should now have its own selected network - // independent from the globally selected and therefore should not have changed when - // the globally selected network was manually changed via the wallet UI - assert.equal(chainIdAfterManualSwitch, '0x539'); // 1337 - }, - ); - }); - }); - - describe('request queue is off', function () { - it('should always follow the globally selected network after connecting and switching without refresh calls @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await driver.clickElement( - '[data-testid="account-options-menu-button"]', - ); - await driver.clickElement({ text: 'Settings', tag: 'div' }); - await driver.clickElement({ text: 'Experimental', tag: 'div' }); - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - - // Navigate to extension home screen - await driver.navigate(PAGES.HOME); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - await driver.delay(regularDelayMs); - - const chainIdRequest = JSON.stringify({ - method: 'eth_chainId', - }); - - const chainIdBeforeConnect = await driver.executeScript( `return window.ethereum.request(${chainIdRequest})`, ); - assert.equal(chainIdBeforeConnect, '0x539'); // 1337 - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); + // before connecting the chainId should change with the wallet + assert.equal(chainIdBeforeConnectAfterManualSwitch, '0x1'); - // Switch to second network - await driver.clickElement({ - text: 'Ethereum Mainnet', - css: 'p', - }); + // Connect to dapp + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + await driver.delay(regularDelayMs); - const chainIdBeforeConnectAfterManualSwitch = - await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); + await switchToNotificationWindow(driver); - // before connecting the chainId should change with the wallet - assert.equal(chainIdBeforeConnectAfterManualSwitch, '0x1'); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); - // Connect to dapp - await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const chainIdAfterConnect = await driver.executeScript( + `return window.ethereum.request(${chainIdRequest})`, + ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + // should still be on the same chainId as the wallet after connecting + assert.equal(chainIdAfterConnect, '0x1'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); - const chainIdAfterConnect = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); - // should still be on the same chainId as the wallet after connecting - assert.equal(chainIdAfterConnect, '0x1'); - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x1', - }); + await switchToNotificationWindow(driver); + await driver.findClickableElements({ + text: 'Confirm', + tag: 'button', + }); - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const chainIdAfterDappSwitch = await driver.executeScript( + `return window.ethereum.request(${chainIdRequest})`, + ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); + // should be on the new chainId that was requested + assert.equal(chainIdAfterDappSwitch, '0x539'); // 1337 - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - const chainIdAfterDappSwitch = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - // should be on the new chainId that was requested - assert.equal(chainIdAfterDappSwitch, '0x539'); // 1337 + // Switch network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x539', - }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - // TODO: check that the wallet network has changed too - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch network - await driver.clickElement({ - text: 'Ethereum Mainnet', - css: 'p', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const chainIdAfterManualSwitch = await driver.executeScript( - `return window.ethereum.request(${chainIdRequest})`, - ); - // after connecting the dapp should still be following the - // globally selected network and therefore should have changed when - // the globally selected network was manually changed via the wallet UI - assert.equal(chainIdAfterManualSwitch, '0x1'); - }, - ); - }); + const chainIdAfterManualSwitch = await driver.executeScript( + `return window.ethereum.request(${chainIdRequest})`, + ); + // after connecting the dapp should now have its own selected network + // independent from the globally selected and therefore should not have changed when + // the globally selected network was manually changed via the wallet UI + assert.equal(chainIdAfterManualSwitch, '0x539'); // 1337 + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js b/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js index 28b19efbeb04..d716b8bf1f12 100644 --- a/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js +++ b/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js @@ -7,303 +7,148 @@ const { DAPP_ONE_URL, regularDelayMs, defaultGanacheOptions, - tempToggleSettingRedesignedConfirmations, WINDOW_TITLES, largeDelayMs, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); -const { PAGES } = require('../../webdriver/driver'); describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () { - describe('Old confirmation screens', function () { - it('should queue signTypedData tx after eth_sendTransaction confirmation and signTypedData confirmation should target the correct network after eth_sendTransaction is confirmed @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should queue signTypedData tx after eth_sendTransaction confirmation and signTypedData confirmation should target the correct network after eth_sendTransaction is confirmed @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + .withSelectedNetworkControllerPerDomain() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); - await tempToggleSettingRedesignedConfirmations(driver); - - // Navigate to extension home screen - await driver.navigate(PAGES.HOME); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open and connect Dapp One - await openDapp(driver, undefined, DAPP_URL); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - // Open and connect to Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // Switch Dapp Two to Localhost 8546 - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - let switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Initiate switchEthereumChain on Dapp one - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x53a', - }); - - // Should auto switch without prompt since already approved via connect - - // Switch back to Dapp One - await driver.switchToWindowWithUrl(DAPP_URL); - - // switch chain for Dapp One - switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x3e8' }], - }); - - // Initiate switchEthereumChain on Dapp one - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x3e8', - }); - // Should auto switch without prompt since already approved via connect - - await driver.switchToWindowWithUrl(DAPP_URL); - - // eth_sendTransaction request - await driver.clickElement('#sendButton'); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - // signTypedData request - await driver.clickElement('#signTypedData'); - - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the send confirmation. - await driver.waitForSelector({ - css: '[data-testid="network-display"]', - text: 'Localhost 7777', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.delay(largeDelayMs); - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the signTypedData confirmation. - await driver.waitForSelector({ - css: '[data-testid="signature-request-network-display"]', - text: 'Localhost 8546', - }); - - await driver.clickElement({ text: 'Reject', tag: 'button' }); - }, - ); - }); - }); - - describe('Redesigned confirmation screens', function () { - it('should queue signTypedData tx after eth_sendTransaction confirmation and signTypedData confirmation should target the correct network after eth_sendTransaction is confirmed @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open and connect Dapp One - await openDapp(driver, undefined, DAPP_URL); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - // Open and connect to Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // Switch Dapp Two to Localhost 8546 - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - let switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x53a' }], - }); - - // Initiate switchEthereumChain on Dapp one - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x53a', - }); - - // Should auto switch without prompt since already approved via connect - - // Switch back to Dapp One - await driver.switchToWindowWithUrl(DAPP_URL); - - // switch chain for Dapp One - switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x3e8' }], - }); - - // Initiate switchEthereumChain on Dapp one - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x3e8', - }); - // Should auto switch without prompt since already approved via connect - - await driver.switchToWindowWithUrl(DAPP_URL); - - // eth_sendTransaction request - await driver.clickElement('#sendButton'); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - // signTypedData request - await driver.clickElement('#signTypedData'); - - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the send confirmation. - await driver.waitForSelector({ - css: 'p', - text: 'Localhost 7777', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.delay(largeDelayMs); - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the signTypedData confirmation. - await driver.waitForSelector({ - css: 'p', - text: 'Localhost 8546', - }); - - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - }, - ); - }); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open and connect Dapp One + await openDapp(driver, undefined, DAPP_URL); + + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.delay(regularDelayMs); + + await driver.waitUntilXWindowHandles(3); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + // Open and connect to Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); + + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.delay(regularDelayMs); + + await driver.waitUntilXWindowHandles(4); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); + + // Switch Dapp Two to Localhost 8546 + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + let switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x53a' }], + }); + + // Initiate switchEthereumChain on Dapp one + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + + await driver.waitForSelector({ + css: '[id="chainId"]', + text: '0x53a', + }); + + // Should auto switch without prompt since already approved via connect + + // Switch back to Dapp One + await driver.switchToWindowWithUrl(DAPP_URL); + + // switch chain for Dapp One + switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x3e8' }], + }); + + // Initiate switchEthereumChain on Dapp one + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + await driver.waitForSelector({ + css: '[id="chainId"]', + text: '0x3e8', + }); + // Should auto switch without prompt since already approved via connect + + await driver.switchToWindowWithUrl(DAPP_URL); + + // eth_sendTransaction request + await driver.clickElement('#sendButton'); + await driver.waitUntilXWindowHandles(3); + + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + + // signTypedData request + await driver.clickElement('#signTypedData'); + + await driver.waitUntilXWindowHandles(4); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // Check correct network on the send confirmation. + await driver.waitForSelector({ + css: 'p', + text: 'Localhost 7777', + }); + + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.delay(largeDelayMs); + await driver.waitUntilXWindowHandles(4); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // Check correct network on the signTypedData confirmation. + await driver.waitForSelector({ + css: 'p', + text: 'Localhost 8546', + }); + + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js b/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js deleted file mode 100644 index 53c763d8891f..000000000000 --- a/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js +++ /dev/null @@ -1,95 +0,0 @@ -const { strict: assert } = require('assert'); -const FixtureBuilder = require('../../fixture-builder'); -const { - withFixtures, - openDapp, - unlockWallet, - DAPP_URL, - regularDelayMs, - WINDOW_TITLES, - switchToNotificationWindow, - defaultGanacheOptions, -} = require('../../helpers'); - -describe('Request Queueing', function () { - it('should keep subscription on dapp network when switching different mm network', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - await switchToNotificationWindow(driver); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - // Navigate to test dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const subscribeRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'eth_subscribe', - params: ['newHeads'], - }); - - const subscribe = await driver.executeScript( - `return window.ethereum.request(${subscribeRequest})`, - ); - - const subscriptionMessage = await driver.executeAsyncScript( - `const callback = arguments[arguments.length - 1];` + - `window.ethereum.on('message', (message) => callback(message))`, - ); - - assert.strictEqual(subscribe, subscriptionMessage.data.subscription); - assert.strictEqual(subscriptionMessage.type, 'eth_subscription'); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - assert.strictEqual(subscribe, subscriptionMessage.data.subscription); - assert.strictEqual(subscriptionMessage.type, 'eth_subscription'); - }, - ); - }); -}); diff --git a/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.ts b/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.ts new file mode 100644 index 000000000000..6b87a7142fbe --- /dev/null +++ b/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.ts @@ -0,0 +1,97 @@ +import { strict as assert } from 'assert'; +import FixtureBuilder from '../../fixture-builder'; +import { + defaultGanacheOptions, + WINDOW_TITLES, + withFixtures, +} from '../../helpers'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import { loginWithoutBalanceValidation } from '../../page-objects/flows/login.flow'; +import { switchToNetworkFlow } from '../../page-objects/flows/network.flow'; + +describe('Request Queueing', function () { + it('should keep subscription on dapp network when switching different mm network', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], + }, + title: this.test?.fullTitle(), + }, + + async ({ driver, ganacheServer }) => { + await loginWithoutBalanceValidation(driver); + + // Connect to dapp + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_pageIsLoaded(); + await testDapp.connectAccount({}); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + + // Subscribe to newHeads event + const subscribeRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_subscribe', + params: ['newHeads'], + }); + + await driver.executeScript( + `return window.ethereum.request(${subscribeRequest})`, + ); + + // Save event logs into the messages variable in the window context, to access it later + await driver.executeScript(` + window.messages = []; + window.ethereum.on('message', (message) => { + if (message.type === 'eth_subscription') { + console.log('New block header:', message.data.result); + window.messages.push(message.data.result); + } + }); + `); + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Switch networks + await switchToNetworkFlow(driver, 'Localhost 8546'); + + // Navigate back to the test dapp + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + + // Access to the window messages variable + const messagesBeforeMining = await driver.executeScript( + 'return window.messages;', + ); + + // Mine a block deterministically + await ganacheServer.mineBlock(); + + // Wait a couple of seconds for the logs to populate into the messages window variable + await driver.delay(5000); + + // Access the window messages variable and check there are more events than before mining + const messagesAfterMining = await driver.executeScript( + 'return window.messages;', + ); + + assert.ok(messagesBeforeMining.length < messagesAfterMining.length); + }, + ); + }); +}); diff --git a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js index 67efbfe6fee9..d6a95d44e530 100644 --- a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js +++ b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js @@ -9,247 +9,148 @@ const { regularDelayMs, WINDOW_TITLES, defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing Dapp 1 Send Tx -> Dapp 2 Request Accounts Tx', function () { - describe('Old confirmation screens', function () { - it('should queue `eth_requestAccounts` requests when the requesting dapp does not already have connected accounts', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should queue `eth_requestAccounts` requests when the requesting dapp does not already have connected accounts', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withPermissionControllerConnectedToTestDapp() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Dapp Send Button + await driver.clickElement('#sendButton'); + await driver.delay(regularDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Dapp Send Button - await driver.clickElement('#sendButton'); - await driver.delay(regularDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector({ + text: 'Cancel', + tag: 'button', + }); - await driver.waitForSelector({ - text: 'Reject', - tag: 'button', - }); + await driver.delay(regularDelayMs); - await driver.delay(regularDelayMs); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + // Leave the confirmation pending + await openDapp(driver, undefined, DAPP_ONE_URL); - // Leave the confirmation pending - await openDapp(driver, undefined, DAPP_ONE_URL); + const accountsOnload = await ( + await driver.findElement('#accounts') + ).getText(); + assert.deepStrictEqual(accountsOnload, ''); - const accountsOnload = await ( - await driver.findElement('#accounts') - ).getText(); - assert.deepStrictEqual(accountsOnload, ''); + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + await driver.delay(regularDelayMs); - await driver.delay(regularDelayMs); + const accountsBeforeConnect = await ( + await driver.findElement('#accounts') + ).getText(); + assert.deepStrictEqual(accountsBeforeConnect, ''); - const accountsBeforeConnect = await ( - await driver.findElement('#accounts') - ).getText(); - assert.deepStrictEqual(accountsBeforeConnect, ''); + // Reject the pending confirmation from the first dapp + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Reject the pending confirmation from the first dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Reject', - tag: 'button', - }); + await driver.clickElement({ + text: 'Cancel', + tag: 'button', + }); - // Wait for switch confirmation to close then request accounts confirmation to show for the second dapp - await driver.delay(regularDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // Wait for switch confirmation to close then request accounts confirmation to show for the second dapp + await driver.delay(regularDelayMs); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); + await driver.clickElement({ + text: 'Connect', + tag: 'button', + }); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.waitForSelector({ - text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - css: '#accounts', - }); - }, - ); - }); + await driver.waitForSelector({ + text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + css: '#accounts', + }); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should queue `eth_requestAccounts` requests when the requesting dapp does not already have connected accounts', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Dapp Send Button - await driver.clickElement('#sendButton'); - await driver.delay(regularDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector({ - text: 'Cancel', - tag: 'button', - }); - - await driver.delay(regularDelayMs); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Leave the confirmation pending - await openDapp(driver, undefined, DAPP_ONE_URL); - - const accountsOnload = await ( - await driver.findElement('#accounts') - ).getText(); - assert.deepStrictEqual(accountsOnload, ''); - - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.delay(regularDelayMs); - - const accountsBeforeConnect = await ( - await driver.findElement('#accounts') - ).getText(); - assert.deepStrictEqual(accountsBeforeConnect, ''); - - // Reject the pending confirmation from the first dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Cancel', - tag: 'button', - }); - - // Wait for switch confirmation to close then request accounts confirmation to show for the second dapp - await driver.delay(regularDelayMs); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - await driver.waitForSelector({ - text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - css: '#accounts', - }); + it('should not queue the `eth_requestAccounts` requests when the requesting dapp already has connected accounts', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withPermissionControllerConnectedToTwoTestDapps() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - ); - }); - - it('should not queue the `eth_requestAccounts` requests when the requesting dapp already has connected accounts', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withPermissionControllerConnectedToTwoTestDapps() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Dapp Send Button - await driver.clickElement('#sendButton'); + // Dapp Send Button + await driver.clickElement('#sendButton'); - // Leave the confirmation pending + // Leave the confirmation pending - await openDapp(driver, undefined, DAPP_ONE_URL); + await openDapp(driver, undefined, DAPP_ONE_URL); - const ethRequestAccounts = JSON.stringify({ - jsonrpc: '2.0', - method: 'eth_requestAccounts', - }); + const ethRequestAccounts = JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_requestAccounts', + }); - const accounts = await driver.executeScript( - `return window.ethereum.request(${ethRequestAccounts})`, - ); + const accounts = await driver.executeScript( + `return window.ethereum.request(${ethRequestAccounts})`, + ); - assert.deepStrictEqual(accounts, [ - '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - ]); - }, - ); - }); + assert.deepStrictEqual(accounts, [ + '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', + ]); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js index 24c09ee18d09..e0aa4f7fa538 100644 --- a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js +++ b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js @@ -7,619 +7,302 @@ const { unlockWallet, WINDOW_TITLES, withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () { - describe('Old confirmation screens', function () { - it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is confirmed', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is confirmed', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + .withSelectedNetworkControllerPerDomain() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Connect to dapp + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const editButtons = await driver.findElements('[data-testid="edit"]'); - const editButtons = await driver.findElements('[data-testid="edit"]'); + await editButtons[1].click(); - await editButtons[1].click(); + // Disconnect Localhost 8545 + await driver.clickElement({ + text: 'Localhost 8545', + tag: 'p', + }); - // Disconnect Localhost 8545 - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); + await driver.clickElement('[data-testid="connect-more-chains-button"]'); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp One - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findElement({ - text: 'Use your enabled networks', - tag: 'p', - }); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - // Wait for switch confirmation to close then tx confirmation to show. - // There is an extra window appearing and disappearing - // so we leave this delay until the issue is fixed (#27360) - await driver.delay(5000); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - // Check correct network on the send confirmation. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); + // Connect to dapp 2 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); - - it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is cancelled.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + await driver.switchToWindowWithUrl(DAPP_URL); - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const editButtons = await driver.findElements('[data-testid="edit"]'); + // Initiate switchEthereumChain on Dapp One + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); - await editButtons[1].click(); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.findElement({ + text: 'Use your enabled networks', + tag: 'p', + }); - // Disconnect Localhost 8545 - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.clickElement('#sendButton'); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); + // Wait for switch confirmation to close then tx confirmation to show. + // There is an extra window appearing and disappearing + // so we leave this delay until the issue is fixed (#27360) + await driver.delay(5000); - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // Check correct network on the send confirmation. + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Confirm', + tag: 'button', + }); - await driver.switchToWindowWithUrl(DAPP_URL); + // Switch back to the extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); - // Initiate switchEthereumChain on Dapp One - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, + // Check for transaction + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - // Wait for switch confirmation to close then tx confirmation to show. - // There is an extra window appearing and disappearing - // so we leave this delay until the issue is fixed (#27360) - await driver.delay(5000); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the send confirmation. - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); + return confirmedTxes.length === 1; + }, 10000); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is confirmed', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is cancelled.', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + .withSelectedNetworkControllerPerDomain() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + // Connect to dapp + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const editButtons = await driver.findElements('[data-testid="edit"]'); - const editButtons = await driver.findElements('[data-testid="edit"]'); + await editButtons[1].click(); - await editButtons[1].click(); + // Disconnect Localhost 8545 + await driver.clickElement({ + text: 'Localhost 8545', + tag: 'p', + }); - // Disconnect Localhost 8545 - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); + await driver.clickElement('[data-testid="connect-more-chains-button"]'); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // Connect to dapp 2 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithUrl(DAPP_URL); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); + await driver.switchToWindowWithUrl(DAPP_URL); - // Initiate switchEthereumChain on Dapp One - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x539' }], + }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.findElement({ - text: 'Use your enabled networks', - tag: 'p', - }); + // Initiate switchEthereumChain on Dapp One + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.clickElement('#sendButton'); + await driver.clickElement('#sendButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); + // Wait for switch confirmation to close then tx confirmation to show. + // There is an extra window appearing and disappearing + // so we leave this delay until the issue is fixed (#27360) + await driver.delay(5000); - // Wait for switch confirmation to close then tx confirmation to show. - // There is an extra window appearing and disappearing - // so we leave this delay until the issue is fixed (#27360) - await driver.delay(5000); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // Check correct network on the send confirmation. + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); - // Check correct network on the send confirmation. - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Confirm', + tag: 'button', + }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); + // Switch back to the extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', + // Check for transaction + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); - - it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is cancelled.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const editButtons = await driver.findElements('[data-testid="edit"]'); - - await editButtons[1].click(); - - // Disconnect Localhost 8545 - await driver.clickElement({ - text: 'Localhost 8545', - tag: 'p', - }); - - await driver.clickElement( - '[data-testid="connect-more-chains-button"]', - ); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.findClickableElement({ text: 'Connect', tag: 'button' }); - await driver.clickElement('#connectButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithUrl(DAPP_URL); - - // switchEthereumChain request - const switchEthereumChainRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_switchEthereumChain', - params: [{ chainId: '0x539' }], - }); - - // Initiate switchEthereumChain on Dapp One - await driver.executeScript( - `window.ethereum.request(${switchEthereumChainRequest})`, - ); - - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - await driver.clickElement('#sendButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - - // Wait for switch confirmation to close then tx confirmation to show. - // There is an extra window appearing and disappearing - // so we leave this delay until the issue is fixed (#27360) - await driver.delay(5000); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Check correct network on the send confirmation. - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); + return confirmedTxes.length === 1; + }, 10000); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/enable-queuing.spec.js b/test/e2e/tests/request-queuing/enable-queuing.spec.js deleted file mode 100644 index ccc5f7cec2c7..000000000000 --- a/test/e2e/tests/request-queuing/enable-queuing.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -const { - withFixtures, - defaultGanacheOptions, - unlockWallet, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Toggle Request Queuing Setting', function () { - it('enables the request queuing experimental setting', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - failOnConsoleError: false, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open account menu button - const accountOptionsMenuSelector = - '[data-testid="account-options-menu-button"]'; - await driver.waitForSelector(accountOptionsMenuSelector); - await driver.clickElement(accountOptionsMenuSelector); - - // Click settings from dropdown menu - const globalMenuSettingsSelector = - '[data-testid="global-menu-settings"]'; - await driver.waitForSelector(globalMenuSettingsSelector); - await driver.clickElement(globalMenuSettingsSelector); - - // Click Experimental tab - const securityAndPrivacyTabRawLocator = { - text: 'Experimental', - tag: 'div', - }; - await driver.clickElement(securityAndPrivacyTabRawLocator); - - // Toggle request queue setting - await driver.clickElement( - '[data-testid="experimental-setting-toggle-request-queue"]', - ); - }, - ); - }); -}); diff --git a/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js b/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js index 3a413f147e06..f147b8d87fc8 100644 --- a/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js +++ b/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js @@ -7,247 +7,122 @@ const { DAPP_ONE_URL, WINDOW_TITLES, defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing for Multiple Dapps and Txs on different networks revokePermissions', function () { - describe('Old confirmation screens', function () { - it('should close transaction for revoked permission of eth_accounts but show queued tx from second dapp on a different network.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should close transaction for revoked permission of eth_accounts but show queued tx from second dapp on a different network.', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Dapp 1 send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x539', - }); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); - await driver.delay(3000); - - // Dapp 2 send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.waitUntilXWindowHandles(4); - - // Dapp 1 revokePermissions - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x539', - }); - await driver.assertElementNotPresent({ - css: '[id="chainId"]', - text: '0x53a', - }); - - // Confirmation will close then reopen - await driver.clickElement('#revokeAccountsPermission'); - // TODO: find a better way to handle different dialog ids - await driver.delay(3000); - - // Check correct network on confirm tx. - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - }, - ); - }); - }); - - describe('New confirmation screens', function () { - it('should close transaction for revoked permission of eth_accounts but show queued tx from second dapp on a different network.', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - - async ({ driver }) => { - await unlockWallet(driver); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // Wait for the first dapp's connect confirmation to disappear - await driver.waitUntilXWindowHandles(2); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Dapp 1 send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x539', - }); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); - await driver.delay(3000); - - // Dapp 2 send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x53a', - }); - await driver.clickElement('#sendButton'); - await driver.waitUntilXWindowHandles(4); - - // Dapp 1 revokePermissions - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.findElement({ - css: '[id="chainId"]', - text: '0x539', - }); - await driver.assertElementNotPresent({ - css: '[id="chainId"]', - text: '0x53a', - }); - - // Confirmation will close then reopen - await driver.clickElement('#revokeAccountsPermission'); - // TODO: find a better way to handle different dialog ids - await driver.delay(3000); - - // Check correct network on confirm tx. - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.findElement({ - css: 'p', - text: 'Localhost 8546', - }); - }, - ); - }); + title: this.test.fullTitle(), + }, + + async ({ driver }) => { + await unlockWallet(driver); + + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); + + // Connect to dapp 1 + await driver.clickElement({ text: 'Connect', tag: 'button' }); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); + + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); + + // Wait for the first dapp's connect confirmation to disappear + await driver.waitUntilXWindowHandles(2); + + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); + + // Connect to dapp 2 + await driver.clickElement({ text: 'Connect', tag: 'button' }); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); + + // Dapp 1 send tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x539', + }); + await driver.clickElement('#sendButton'); + + await driver.waitUntilXWindowHandles(4); + await driver.delay(3000); + + // Dapp 2 send tx + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x53a', + }); + await driver.clickElement('#sendButton'); + await driver.waitUntilXWindowHandles(4); + + // Dapp 1 revokePermissions + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.findElement({ + css: '[id="chainId"]', + text: '0x539', + }); + await driver.assertElementNotPresent({ + css: '[id="chainId"]', + text: '0x53a', + }); + + // Confirmation will close then reopen + await driver.clickElement('#revokeAccountsPermission'); + // TODO: find a better way to handle different dialog ids + await driver.delay(3000); + + // Check correct network on confirm tx. + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await driver.findElement({ + css: 'p', + text: 'Localhost 8546', + }); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js b/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js index f831ff1ff38d..000727f8bd5c 100644 --- a/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js +++ b/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js @@ -8,277 +8,135 @@ const { WINDOW_TITLES, defaultGanacheOptions, largeDelayMs, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); describe('Request Queuing for Multiple Dapps and Txs on different networks.', function () { - describe('Old confirmation screens', function () { - it('should switch to the dapps network automatically when handling sendTransaction calls @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should switch to the dapps network automatically when handling sendTransaction calls @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withSelectedNetworkControllerPerDomain() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Connect to dapp 1 + await driver.clickElement({ text: 'Connect', tag: 'button' }); - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Dapp one send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - // Dapp two send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - // First switch network - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); - // Wait for confirm tx after switch network confirmation. - await driver.delay(largeDelayMs); + // Connect to dapp 2 + await driver.clickElement({ text: 'Connect', tag: 'button' }); - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Reject Transaction - await driver.findClickableElement({ text: 'Reject', tag: 'button' }); - await driver.clickElement( - '[data-testid="page-container-footer-cancel"]', - ); - - // TODO: No second confirmation from dapp two will show, have to go back to the extension to see the switch chain & dapp two's tx. - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - // Check for unconfirmed transaction in tx list - await driver.wait(async () => { - const unconfirmedTxes = await driver.findElements( - '.transaction-list-item--unconfirmed', - ); - return unconfirmedTxes.length === 1; - }, 10000); + await driver.clickElementAndWaitForWindowToClose({ + text: 'Connect', + tag: 'button', + }); - // Click Unconfirmed Tx - await driver.clickElement('.transaction-list-item--unconfirmed'); + // Dapp one send tx + await driver.switchToWindowWithUrl(DAPP_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); - await driver.assertElementNotPresent({ - tag: 'p', - text: 'Network switched to Localhost 8546', - }); + await driver.waitUntilXWindowHandles(4); - // Confirm Tx - await driver.clickElement( - '[data-testid="page-container-footer-next"]', - ); - - // Check for Confirmed Transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); - }); + // Dapp two send tx + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + await driver.delay(largeDelayMs); + await driver.clickElement('#sendButton'); - describe('Redesigned confirmation screens', function () { - it('should switch to the dapps network automatically when handling sendTransaction calls @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - dappOptions: { numberOfDapps: 2 }, - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + // First switch network + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); + // Wait for confirm tx after switch network confirmation. + await driver.delay(largeDelayMs); - // Connect to dapp 1 - await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.waitUntilXWindowHandles(4); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + // Reject Transaction + await driver.findClickableElement({ text: 'Cancel', tag: 'button' }); + await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); + // TODO: No second confirmation from dapp two will show, have to go back to the extension to see the switch chain & dapp two's tx. + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, + // Check for unconfirmed transaction in tx list + await driver.wait(async () => { + const unconfirmedTxes = await driver.findElements( + '.transaction-list-item--unconfirmed', ); + return unconfirmedTxes.length === 1; + }, 10000); - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. - // Open Dapp Two - await openDapp(driver, undefined, DAPP_ONE_URL); - - // Connect to dapp 2 - await driver.clickElement({ text: 'Connect', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Connect', - tag: 'button', - }); - - // Dapp one send tx - await driver.switchToWindowWithUrl(DAPP_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); - - await driver.waitUntilXWindowHandles(4); - - // Dapp two send tx - await driver.switchToWindowWithUrl(DAPP_ONE_URL); - await driver.delay(largeDelayMs); - await driver.clickElement('#sendButton'); + // Click Unconfirmed Tx + await driver.clickElement('.transaction-list-item--unconfirmed'); - // First switch network - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.assertElementNotPresent({ + tag: 'p', + text: 'Network switched to Localhost 8546', + }); - // Wait for confirm tx after switch network confirmation. - await driver.delay(largeDelayMs); + // Confirm Tx + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(4); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Reject Transaction - await driver.findClickableElement({ text: 'Cancel', tag: 'button' }); - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - - // TODO: No second confirmation from dapp two will show, have to go back to the extension to see the switch chain & dapp two's tx. - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', + // Check for Confirmed Transaction + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - - // Check for unconfirmed transaction in tx list - await driver.wait(async () => { - const unconfirmedTxes = await driver.findElements( - '.transaction-list-item--unconfirmed', - ); - return unconfirmedTxes.length === 1; - }, 10000); - - // Click Unconfirmed Tx - await driver.clickElement('.transaction-list-item--unconfirmed'); - - await driver.assertElementNotPresent({ - tag: 'p', - text: 'Network switched to Localhost 8546', - }); - - // Confirm Tx - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Check for Confirmed Transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); + return confirmedTxes.length === 1; + }, 10000); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.js b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.js deleted file mode 100644 index 363f7c94cc74..000000000000 --- a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -const FixtureBuilder = require('../../fixture-builder'); -const { - withFixtures, - openDapp, - unlockWallet, - DAPP_URL, - defaultGanacheOptions, -} = require('../../helpers'); -const { PAGES } = require('../../webdriver/driver'); - -describe('Request Queuing', function () { - it('should clear tx confirmation when revokePermission is called from origin dapp', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerUseRequestQueueEnabled() - .withSelectedNetworkControllerPerDomain() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Navigate to extension home screen - await driver.navigate(PAGES.HOME); - - // Open Dapp One - await openDapp(driver, undefined, DAPP_URL); - - // wallet_revokePermissions request - const revokePermissionsRequest = JSON.stringify({ - jsonrpc: '2.0', - method: 'wallet_revokePermissions', - params: [ - { - eth_accounts: {}, - }, - ], - }); - - await driver.executeScript( - `return window.ethereum.request(${revokePermissionsRequest})`, - ); - - // Should have cleared the tx confirmation - await driver.waitUntilXWindowHandles(2); - - // Cleared eth_accounts account label - await driver.findElement({ xpath: '//span[@id="accounts"][.=""]' }); - }, - ); - }); -}); diff --git a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts new file mode 100644 index 000000000000..620735761c69 --- /dev/null +++ b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts @@ -0,0 +1,75 @@ +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import TransactionConfirmation from '../../page-objects/pages/confirmations/redesign/transaction-confirmation'; +import { Ganache } from '../../seeder/ganache'; +import { Driver } from '../../webdriver/driver'; +import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants'; +import FixtureBuilder from '../../fixture-builder'; +import { + withFixtures, + defaultGanacheOptions, + WINDOW_TITLES, +} from '../../helpers'; + +describe('Request Queuing', function () { + // TODO: add a new spec which checks that after revoking and connecting again + // a pending tx is still closed when using revokePermissions. + // To be done once this bug is fixed: #29272 + it('should clear tx confirmation when revokePermission is called from origin dapp', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .withSelectedNetworkControllerPerDomain() + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + }, + title: this.test?.fullTitle(), + }, + async ({ + driver, + ganacheServer, + }: { + driver: Driver; + ganacheServer?: Ganache; + }) => { + await loginWithBalanceValidation(driver, ganacheServer); + + // Open test dapp + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT); + + // Trigger a tx + await testDapp.clickSimpleSendButton(); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + const transactionConfirmation = new TransactionConfirmation(driver); + await transactionConfirmation.check_dappInitiatedHeadingTitle(); + + // wallet_revokePermissions request + const revokePermissionsRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_revokePermissions', + params: [ + { + eth_accounts: {}, + }, + ], + }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + await driver.executeScript( + `return window.ethereum.request(${revokePermissionsRequest})`, + ); + + // Should have cleared the tx confirmation + await driver.waitUntilXWindowHandles(2); + + // Cleared eth_accounts account label + await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT, false); + }, + ); + }); +}); diff --git a/test/e2e/tests/request-queuing/sendTx-switchChain-sendTx.spec.js b/test/e2e/tests/request-queuing/sendTx-switchChain-sendTx.spec.js index 5b0c4dca2f07..13d34ecbbb66 100644 --- a/test/e2e/tests/request-queuing/sendTx-switchChain-sendTx.spec.js +++ b/test/e2e/tests/request-queuing/sendTx-switchChain-sendTx.spec.js @@ -21,7 +21,7 @@ describe('Request Queuing Send Tx -> SwitchChain -> SendTx', function () { fixtures: new FixtureBuilder() .withNetworkControllerDoubleGanache() .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerUseRequestQueueEnabled() + .build(), ganacheOptions: { ...defaultGanacheOptions, diff --git a/test/e2e/tests/request-queuing/switch-network.spec.js b/test/e2e/tests/request-queuing/switch-network.spec.js index 913bdf459a26..8e813869ca6d 100644 --- a/test/e2e/tests/request-queuing/switch-network.spec.js +++ b/test/e2e/tests/request-queuing/switch-network.spec.js @@ -7,178 +7,87 @@ const { regularDelayMs, WINDOW_TITLES, defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const { PAGES } = require('../../webdriver/driver'); describe('Request Queuing Switch Network on Dapp Send Tx while on different networks.', function () { - describe('Old confirmation screens', function () { - it('should switch to the dapps network automatically when mm network differs, dapp tx is on correct network', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), + it('should switch to the dapps network automatically when mm network differs, dapp tx is on correct network', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + // Open dapp + await openDapp(driver, undefined, DAPP_URL); - // Open dapp - await openDapp(driver, undefined, DAPP_URL); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); - // Queue confirm tx should first auto switch network - await driver.clickElement('#sendButton'); + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm Transaction - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="page-container-footer-next"]', - ); + // Queue confirm tx should first auto switch network + await driver.clickElement('#sendButton'); - await driver.delay(regularDelayMs); + await driver.delay(regularDelayMs); - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.navigate(PAGES.HOME); + await driver.waitUntilXWindowHandles(3); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - // Check correct network switched and on the correct network - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8545', - }); + // Confirm Transaction + await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); - }); + await driver.delay(regularDelayMs); - describe('Redesigned confirmation screens', function () { - it('should switch to the dapps network automatically when mm network differs, dapp tx is on correct network', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + // Switch back to the extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.navigate(PAGES.HOME); - // Open dapp - await openDapp(driver, undefined, DAPP_URL); + // Check correct network switched and on the correct network + await driver.findElement({ + css: '[data-testid="network-display"]', + text: 'Localhost 8545', + }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, + // Check for transaction + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - - // Network Selector - await driver.clickElement('[data-testid="network-display"]'); - - // Switch to second network - await driver.clickElement({ - text: 'Localhost 8546', - css: 'p', - }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // Queue confirm tx should first auto switch network - await driver.clickElement('#sendButton'); - - await driver.delay(regularDelayMs); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm Transaction - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.delay(regularDelayMs); - - // Switch back to the extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.navigate(PAGES.HOME); - - // Check correct network switched and on the correct network - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8545', - }); - - // Check for transaction - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - }, - ); - }); + return confirmedTxes.length === 1; + }, 10000); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js b/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js index df33600413e1..dd34215fe007 100644 --- a/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js +++ b/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js @@ -16,7 +16,7 @@ describe('Request Queuing SwitchChain -> SendTx', function () { dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .build(), ganacheOptions: { ...defaultGanacheOptions, diff --git a/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js b/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js index 5767bd26def5..080d9ef38903 100644 --- a/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js +++ b/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js @@ -20,7 +20,7 @@ describe('Request Queue SwitchChain -> WatchAsset', function () { dapp: true, fixtures: new FixtureBuilder() .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() + .build(), ganacheOptions: { ...defaultGanacheOptions, diff --git a/test/e2e/tests/request-queuing/ui.spec.js b/test/e2e/tests/request-queuing/ui.spec.js index 707c252396b7..a2b36784e65b 100644 --- a/test/e2e/tests/request-queuing/ui.spec.js +++ b/test/e2e/tests/request-queuing/ui.spec.js @@ -11,10 +11,8 @@ const { regularDelayMs, WINDOW_TITLES, defaultGanacheOptions, - tempToggleSettingRedesignedConfirmations, veryLargeDelayMs, DAPP_TWO_URL, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const { PAGES } = require('../../webdriver/driver'); const { @@ -103,40 +101,6 @@ async function selectDappClickPersonalSign(driver, dappUrl) { await driver.clickElement('#personalSign'); } -async function switchToDialogPopoverValidateDetails(driver, expectedDetails) { - // Switches to the MetaMask Dialog window for confirmation - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.findElement({ - css: '[data-testid="network-display"], [data-testid="signature-request-network-display"]', - text: expectedDetails.networkText, - }); - - await driver.findElement({ - css: '.confirm-page-container-summary__origin bdi, .request-signature__origin .chip__label', - text: expectedDetails.originText, - }); - - // Get state details - await driver.waitForControllersLoaded(); - const notificationWindowState = await driver.executeScript(() => - window.stateHooks?.getCleanAppState?.(), - ); - - const { - metamask: { selectedNetworkClientId, networkConfigurationsByChainId }, - } = notificationWindowState; - - const { chainId } = Object.values(networkConfigurationsByChainId).find( - ({ rpcEndpoints }) => - rpcEndpoints.some( - ({ networkClientId }) => networkClientId === selectedNetworkClientId, - ), - ); - - assert.equal(chainId, expectedDetails.chainId); -} - async function switchToDialogPopoverValidateDetailsRedesign( driver, expectedDetails, @@ -169,13 +133,6 @@ async function switchToDialogPopoverValidateDetailsRedesign( assert.equal(chainId, expectedDetails.chainId); } -async function rejectTransaction(driver) { - await driver.clickElementAndWaitForWindowToClose({ - tag: 'button', - text: 'Reject', - }); -} - async function rejectTransactionRedesign(driver) { await driver.clickElementAndWaitForWindowToClose({ tag: 'button', @@ -230,1036 +187,552 @@ async function validateBalanceAndActivity( } describe('Request-queue UI changes', function () { - describe('Old confirmation screens', function () { - it('should show network specific to domain @no-mmi', async function () { - const port = 8546; - const chainId = 1338; // 0x53a - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - - // Go to the first dapp, ensure it uses localhost - await selectDappClickSend(driver, DAPP_URL); - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); - await rejectTransaction(driver); - - // Go to the second dapp, ensure it uses Ethereum Mainnet - await selectDappClickSend(driver, DAPP_ONE_URL); - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x53a', - networkText: 'Localhost 8546', - originText: DAPP_ONE_URL, - }); - await rejectTransaction(driver); - }, - ); - }); - - it('handles three confirmations on three confirmations concurrently @no-mmi', async function () { - const port = 8546; - const chainId = 1338; // 0x53a - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - // Ganache for network 1 - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - // Ganache for network 3 - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 3 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); - - if (!IS_FIREFOX) { - // Open the third dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_TWO_URL, '0x3e8'); - } - - // Trigger a send confirmation on the first dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_URL); - - // Trigger a send confirmation on the second dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_ONE_URL); - - if (!IS_FIREFOX) { - // Trigger a send confirmation on the third dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_TWO_URL); - } - - // Switch to the Notification window, ensure first transaction still showing - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); - - // Confirm transaction, wait for first confirmation window to close, second to display - await confirmTransaction(driver); - await driver.delay(veryLargeDelayMs); - - // Switch to the new Notification window, ensure second transaction showing - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x53a', - networkText: 'Localhost 8546', - originText: DAPP_ONE_URL, - }); - - // Reject this transaction, wait for second confirmation window to close, third to display - await rejectTransaction(driver); - await driver.delay(veryLargeDelayMs); - - if (!IS_FIREFOX) { - // Switch to the new Notification window, ensure third transaction showing - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x3e8', - networkText: 'Localhost 7777', - originText: DAPP_TWO_URL, - }); - - // Confirm transaction - await confirmTransaction(driver); - } - - // With first and last confirmations confirmed, and second rejected, - // Ensure only first and last network balances were affected - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Wait for transaction to be completed on final confirmation - await driver.delay(veryLargeDelayMs); - - if (!IS_FIREFOX) { - // Start on the last joined network, whose send transaction was just confirmed - await validateBalanceAndActivity(driver, '24.9998'); - } - - // Switch to second network, ensure full balance - await switchToNetworkByName(driver, 'Localhost 8546'); - await validateBalanceAndActivity(driver, '25', 0); - - // Turn on test networks in Networks menu so Localhost 8545 is available - await driver.clickElement('[data-testid="network-display"]'); - await driver.clickElement('.mm-modal-content__dialog .toggle-button'); - await driver.clickElement( - '.mm-modal-content__dialog button[aria-label="Close"]', - ); - - // Switch to first network, whose send transaction was just confirmed - await switchToNetworkByName(driver, 'Localhost 8545'); - await validateBalanceAndActivity(driver, '24.9998'); - }, - ); - }); - - it('should gracefully handle deleted network @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesController({ - preferences: { showTestNetworks: true }, - }) - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - await driver.clickElement('[data-testid="network-display"]'); - - const networkRow = await driver.findElement({ - css: '.multichain-network-list-item', - text: 'Localhost 8545', - }); - - const networkMenu = await driver.findNestedElement( - networkRow, - `[data-testid="network-list-item-options-button-${CHAIN_IDS.LOCALHOST}"]`, - ); - - await networkMenu.click(); - await driver.clickElement( - '[data-testid="network-list-item-options-delete"]', - ); - - await driver.clickElement({ tag: 'button', text: 'Delete' }); - - // Go back to first dapp, try an action, ensure deleted network doesn't block UI - // The current globally selected network, Ethereum Mainnet, should be used - await selectDappClickSend(driver, DAPP_URL); - await driver.delay(veryLargeDelayMs); - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x1', - networkText: 'Ethereum Mainnet', - originText: DAPP_URL, - }); - }, - ); - }); - - it('should autoswitch networks when last confirmation from another network is rejected', async function () { - const port = 8546; - const chainId = 1338; - - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - driverOptions: { constrainWindowSize: true }, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp which starts on chain '0x539 - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open tab 2, switch to Ethereum Mainnet - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - await driver.waitForSelector({ - css: '.error-message-text', - text: 'You are on the Ethereum Mainnet.', - }); - await driver.delay(veryLargeDelayMs); - - // Start a Send on Ethereum Mainnet - await driver.clickElement('#sendButton'); - await driver.delay(regularDelayMs); - - // Open the popup with shimmed activeTabOrigin - await openPopupWithActiveTabOrigin(driver, DAPP_URL); - - // Ensure the confirmation pill shows Ethereum Mainnet - await driver.waitForSelector({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - // Reject the confirmation - await driver.clickElement( - '[data-testid="page-container-footer-cancel"]', - ); - - // Wait for network to automatically change to localhost - await driver.waitForSelector({ - css: '.multichain-app-header__contents--avatar-network .mm-text', - text: 'Localhost 8545', - }); - - // Ensure toast is shown to the user - await driver.waitForSelector({ - css: '.toast-text', - text: 'Localhost 8545 is now active on 127.0.0.1:8080', - }); - }, - ); - }); - - it('should gracefully handle network connectivity failure for signatures @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - // This test intentionally quits Ganache while the extension is using it, causing - // PollingBlockTracker errors and others. These are expected. - ignoredConsoleErrors: ['ignore-all'], - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer, secondaryGanacheServer }) => { - await unlockWallet(driver); - await tempToggleSettingRedesignedConfirmations(driver); - - // Navigate to extension home screen - await driver.navigate(PAGES.HOME); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.waitForSelector({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - // Kill ganache servers - await ganacheServer.quit(); - await secondaryGanacheServer[0].quit(); - - // Go back to first dapp, try an action, ensure network connection failure doesn't block UI - await selectDappClickPersonalSign(driver, DAPP_URL); - - // When the network is down, there is a performance degradation that causes the - // popup to take a few seconds to open in MV3 (issue #25690) - await driver.waitUntilXWindowHandles(4, 1000, 15000); - - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); + it('should show network specific to domain @no-mmi', async function () { + const port = 8546; + const chainId = 1338; // 0x53a + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - ); - }); - - it('should gracefully handle network connectivity failure for confirmations @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - // Presently confirmations take up to 10 seconds to display on a dead network - driverOptions: { timeOut: 30000 }, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - // This test intentionally quits Ganache while the extension is using it, causing - // PollingBlockTracker errors and others. These are expected. - ignoredConsoleErrors: ['ignore-all'], - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer, secondaryGanacheServer }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - // Kill ganache servers - await ganacheServer.quit(); - await secondaryGanacheServer[0].quit(); - - // Go back to first dapp, try an action, ensure network connection failure doesn't block UI - await selectDappClickSend(driver, DAPP_URL); - - // When the network is down, there is a performance degradation that causes the - // popup to take a few seconds to open in MV3 (issue #25690) - await driver.waitUntilXWindowHandles(4, 1000, 15000); - - await switchToDialogPopoverValidateDetails(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); - }, - ); - }); + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open the first dapp + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open the second dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); + + // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.findElement({ + css: '[data-testid="network-display"]', + text: 'Localhost 8546', + }); + + // Go to the first dapp, ensure it uses localhost + await selectDappClickSend(driver, DAPP_URL); + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x539', + networkText: 'Localhost 8545', + originText: DAPP_URL, + }); + await rejectTransactionRedesign(driver); + + // Go to the second dapp, ensure it uses Ethereum Mainnet + await selectDappClickSend(driver, DAPP_ONE_URL); + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x53a', + networkText: 'Localhost 8546', + originText: DAPP_ONE_URL, + }); + await rejectTransactionRedesign(driver); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should show network specific to domain @no-mmi', async function () { - const port = 8546; - const chainId = 1338; // 0x53a - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Localhost 8546', - }); - - // Go to the first dapp, ensure it uses localhost - await selectDappClickSend(driver, DAPP_URL); - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); - await rejectTransactionRedesign(driver); - - // Go to the second dapp, ensure it uses Ethereum Mainnet - await selectDappClickSend(driver, DAPP_ONE_URL); - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x53a', - networkText: 'Localhost 8546', - originText: DAPP_ONE_URL, - }); - await rejectTransactionRedesign(driver); - }, - ); - }); - - it('handles three confirmations on three confirmations concurrently @no-mmi', async function () { - const port = 8546; - const chainId = 1338; // 0x53a - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerTripleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - // Ganache for network 1 - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - // Ganache for network 3 - { - port: 7777, - chainId: 1000, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 3 }, - title: this.test.fullTitle(), + it('handles three confirmations on three confirmations concurrently @no-mmi', async function () { + const port = 8546; + const chainId = 1338; // 0x53a + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + // Ganache for network 1 + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + // Ganache for network 3 + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); - - if (!IS_FIREFOX) { - // Open the third dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_TWO_URL, '0x3e8'); - } - - // Trigger a send confirmation on the first dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_URL); - - // Trigger a send confirmation on the second dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_ONE_URL); - - if (!IS_FIREFOX) { - // Trigger a send confirmation on the third dapp, do not confirm or reject - await selectDappClickSend(driver, DAPP_TWO_URL); - } - - // Switch to the Notification window, ensure first transaction still showing + dappOptions: { numberOfDapps: 3 }, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open the first dapp + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open the second dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a'); + + if (!IS_FIREFOX) { + // Open the third dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_TWO_URL, '0x3e8'); + } + + // Trigger a send confirmation on the first dapp, do not confirm or reject + await selectDappClickSend(driver, DAPP_URL); + + // Trigger a send confirmation on the second dapp, do not confirm or reject + await selectDappClickSend(driver, DAPP_ONE_URL); + + if (!IS_FIREFOX) { + // Trigger a send confirmation on the third dapp, do not confirm or reject + await selectDappClickSend(driver, DAPP_TWO_URL); + } + + // Switch to the Notification window, ensure first transaction still showing + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x539', + networkText: 'Localhost 8545', + originText: DAPP_URL, + }); + + // Confirm transaction, wait for first confirmation window to close, second to display + await confirmTransaction(driver); + await driver.delay(veryLargeDelayMs); + + // Switch to the new Notification window, ensure second transaction showing + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x53a', + networkText: 'Localhost 8546', + originText: DAPP_ONE_URL, + }); + + // Reject this transaction, wait for second confirmation window to close, third to display + await rejectTransactionRedesign(driver); + await driver.delay(veryLargeDelayMs); + + if (!IS_FIREFOX) { + // Switch to the new Notification window, ensure third transaction showing await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, + chainId: '0x3e8', + networkText: 'Localhost 7777', + originText: DAPP_TWO_URL, }); - // Confirm transaction, wait for first confirmation window to close, second to display + // Confirm transaction await confirmTransaction(driver); - await driver.delay(veryLargeDelayMs); + } - // Switch to the new Notification window, ensure second transaction showing - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x53a', - networkText: 'Localhost 8546', - originText: DAPP_ONE_URL, - }); - - // Reject this transaction, wait for second confirmation window to close, third to display - await rejectTransactionRedesign(driver); - await driver.delay(veryLargeDelayMs); - - if (!IS_FIREFOX) { - // Switch to the new Notification window, ensure third transaction showing - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x3e8', - networkText: 'Localhost 7777', - originText: DAPP_TWO_URL, - }); - - // Confirm transaction - await confirmTransaction(driver); - } - - // With first and last confirmations confirmed, and second rejected, - // Ensure only first and last network balances were affected - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Wait for transaction to be completed on final confirmation - await driver.delay(veryLargeDelayMs); - - if (!IS_FIREFOX) { - // Start on the last joined network, whose send transaction was just confirmed - await validateBalanceAndActivity(driver, '24.9998'); - } - - // Switch to second network, ensure full balance - await switchToNetworkByName(driver, 'Localhost 8546'); - await validateBalanceAndActivity(driver, '25', 0); - - // Turn on test networks in Networks menu so Localhost 8545 is available - await driver.clickElement('[data-testid="network-display"]'); - await driver.clickElement('.mm-modal-content__dialog .toggle-button'); - await driver.clickElement( - '.mm-modal-content__dialog button[aria-label="Close"]', - ); - - // Switch to first network, whose send transaction was just confirmed - await switchToNetworkByName(driver, 'Localhost 8545'); - await validateBalanceAndActivity(driver, '24.9998'); - }, - ); - }); - - it('should gracefully handle deleted network @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesController({ - preferences: { showTestNetworks: true }, - }) - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - await driver.clickElement('[data-testid="network-display"]'); - - const networkRow = await driver.findElement({ - css: '.multichain-network-list-item', - text: 'Localhost 8545', - }); - - const networkMenu = await driver.findNestedElement( - networkRow, - `[data-testid="network-list-item-options-button-${CHAIN_IDS.LOCALHOST}"]`, - ); - - await networkMenu.click(); - await driver.clickElement( - '[data-testid="network-list-item-options-delete"]', - ); + // With first and last confirmations confirmed, and second rejected, + // Ensure only first and last network balances were affected + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); - await driver.clickElement({ tag: 'button', text: 'Delete' }); + // Wait for transaction to be completed on final confirmation + await driver.delay(veryLargeDelayMs); - // Go back to first dapp, try an action, ensure deleted network doesn't block UI - // The current globally selected network, Ethereum Mainnet, should be used - await selectDappClickSend(driver, DAPP_URL); - await driver.delay(veryLargeDelayMs); - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x1', - networkText: 'Ethereum Mainnet', - originText: DAPP_URL, - }); - }, - ); - }); - - it('should signal from UI to dapp the network change @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - driverOptions: { constrainWindowSize: true }, - }, - async ({ driver }) => { - // Navigate to extension home screen - await unlockWallet(driver); - - // Open the first dapp which starts on chain '0x539 - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Ensure the dapp starts on the correct network - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x539', - }); - - // Open the popup with shimmed activeTabOrigin - await openPopupWithActiveTabOrigin(driver, DAPP_URL); - - // Switch to mainnet - await switchToNetworkByName(driver, 'Ethereum Mainnet'); - - // Switch back to the Dapp tab - await driver.switchToWindowWithUrl(DAPP_URL); - - // Check to make sure the dapp network changed - await driver.waitForSelector({ - css: '[id="chainId"]', - text: '0x1', - }); - }, - ); - }); - - it('should autoswitch networks to the last used network for domain', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - // Open fullscreen - await unlockWallet(driver); - - // Open the first dapp which starts on chain '0x539 - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open tab 2, switch to Ethereum Mainnet - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Open the popup with shimmed activeTabOrigin - await openPopupWithActiveTabOrigin(driver, DAPP_URL); - - // Ensure network was reset to original - await driver.findElement({ - css: '.multichain-app-header__contents--avatar-network .mm-text', - text: 'Localhost 8545', - }); - - // Ensure toast is shown to the user - await driver.findElement({ - css: '.toast-text', - text: 'Localhost 8545 is now active on 127.0.0.1:8080', - }); - }, - ); - }); + if (!IS_FIREFOX) { + // Start on the last joined network, whose send transaction was just confirmed + await validateBalanceAndActivity(driver, '24.9998'); + } + + // Switch to second network, ensure full balance + await switchToNetworkByName(driver, 'Localhost 8546'); + await validateBalanceAndActivity(driver, '25', 0); + + // Turn on test networks in Networks menu so Localhost 8545 is available + await driver.clickElement('[data-testid="network-display"]'); + await driver.clickElement('.mm-modal-content__dialog .toggle-button'); + await driver.clickElement( + '.mm-modal-content__dialog button[aria-label="Close"]', + ); + + // Switch to first network, whose send transaction was just confirmed + await switchToNetworkByName(driver, 'Localhost 8545'); + await validateBalanceAndActivity(driver, '24.9998'); + }, + ); + }); - it('should autoswitch networks when last confirmation from another network is rejected', async function () { - const port = 8546; - const chainId = 1338; - - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), - driverOptions: { constrainWindowSize: true }, + it('should gracefully handle deleted network @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + .withPreferencesController({ + preferences: { showTestNetworks: true }, + }) + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver }) => { - await unlockWallet(driver); - - // Open the first dapp which starts on chain '0x539 - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open tab 2, switch to Ethereum Mainnet - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - await driver.waitForSelector({ - css: '.error-message-text', - text: 'You are on the Ethereum Mainnet.', - }); - await driver.delay(veryLargeDelayMs); - - // Start a Send on Ethereum Mainnet - await driver.clickElement('#sendButton'); - await driver.delay(regularDelayMs); - - // Open the popup with shimmed activeTabOrigin - await openPopupWithActiveTabOrigin(driver, DAPP_URL); - - // Ensure the confirmation pill shows Ethereum Mainnet - await driver.waitForSelector({ - css: 'p', - text: 'Ethereum Mainnet', - }); - - // Reject the confirmation - await driver.clickElement({ css: 'button', text: 'Cancel' }); - - // Wait for network to automatically change to localhost - await driver.waitForSelector({ - css: '.multichain-app-header__contents--avatar-network .mm-text', - text: 'Localhost 8545', - }); + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open the first dapp + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open the second dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); + + // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.findElement({ + css: '[data-testid="network-display"]', + text: 'Ethereum Mainnet', + }); + + await driver.clickElement('[data-testid="network-display"]'); + + const networkRow = await driver.findElement({ + css: '.multichain-network-list-item', + text: 'Localhost 8545', + }); + + const networkMenu = await driver.findNestedElement( + networkRow, + `[data-testid="network-list-item-options-button-${CHAIN_IDS.LOCALHOST}"]`, + ); + + await networkMenu.click(); + await driver.clickElement( + '[data-testid="network-list-item-options-delete"]', + ); + + await driver.clickElement({ tag: 'button', text: 'Delete' }); + + // Go back to first dapp, try an action, ensure deleted network doesn't block UI + // The current globally selected network, Ethereum Mainnet, should be used + await selectDappClickSend(driver, DAPP_URL); + await driver.delay(veryLargeDelayMs); + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x1', + networkText: 'Ethereum Mainnet', + originText: DAPP_URL, + }); + }, + ); + }); - // Ensure toast is shown to the user - await driver.waitForSelector({ - css: '.toast-text', - text: 'Localhost 8545 is now active on 127.0.0.1:8080', - }); - }, - ); - }); + it('should signal from UI to dapp the network change @no-mmi', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + driverOptions: { constrainWindowSize: true }, + }, + async ({ driver }) => { + // Navigate to extension home screen + await unlockWallet(driver); + + // Open the first dapp which starts on chain '0x539 + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Ensure the dapp starts on the correct network + await driver.waitForSelector({ + css: '[id="chainId"]', + text: '0x539', + }); + + // Open the popup with shimmed activeTabOrigin + await openPopupWithActiveTabOrigin(driver, DAPP_URL); + + // Switch to mainnet + await switchToNetworkByName(driver, 'Ethereum Mainnet'); + + // Switch back to the Dapp tab + await driver.switchToWindowWithUrl(DAPP_URL); + + // Check to make sure the dapp network changed + await driver.waitForSelector({ + css: '[id="chainId"]', + text: '0x1', + }); + }, + ); + }); - it('should gracefully handle network connectivity failure for signatures @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - // This test intentionally quits Ganache while the extension is using it, causing - // PollingBlockTracker errors and others. These are expected. - ignoredConsoleErrors: ['ignore-all'], - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), + it('should autoswitch networks to the last used network for domain', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver, ganacheServer, secondaryGanacheServer }) => { - await unlockWallet(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.waitForSelector({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - // Kill ganache servers - await ganacheServer.quit(); - await secondaryGanacheServer[0].quit(); - - // Go back to first dapp, try an action, ensure network connection failure doesn't block UI - await selectDappClickPersonalSign(driver, DAPP_URL); - - // When the network is down, there is a performance degradation that causes the - // popup to take a few seconds to open in MV3 (issue #25690) - await driver.waitUntilXWindowHandles(4, 1000, 15000); + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + // Open fullscreen + await unlockWallet(driver); + + // Open the first dapp which starts on chain '0x539 + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open tab 2, switch to Ethereum Mainnet + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); + + // Open the popup with shimmed activeTabOrigin + await openPopupWithActiveTabOrigin(driver, DAPP_URL); + + // Ensure network was reset to original + await driver.findElement({ + css: '.multichain-app-header__contents--avatar-network .mm-text', + text: 'Localhost 8545', + }); + + // Ensure toast is shown to the user + await driver.findElement({ + css: '.toast-text', + text: 'Localhost 8545 is now active on 127.0.0.1:8080', + }); + }, + ); + }); - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); + it('should autoswitch networks when last confirmation from another network is rejected', async function () { + const port = 8546; + const chainId = 1338; + + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - ); - }); + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + driverOptions: { constrainWindowSize: true }, + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open the first dapp which starts on chain '0x539 + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open tab 2, switch to Ethereum Mainnet + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); + await driver.waitForSelector({ + css: '.error-message-text', + text: 'You are on the Ethereum Mainnet.', + }); + await driver.delay(veryLargeDelayMs); + + // Start a Send on Ethereum Mainnet + await driver.clickElement('#sendButton'); + await driver.delay(regularDelayMs); + + // Open the popup with shimmed activeTabOrigin + await openPopupWithActiveTabOrigin(driver, DAPP_URL); + + // Ensure the confirmation pill shows Ethereum Mainnet + await driver.waitForSelector({ + css: 'p', + text: 'Ethereum Mainnet', + }); + + // Reject the confirmation + await driver.clickElement({ css: 'button', text: 'Cancel' }); + + // Wait for network to automatically change to localhost + await driver.waitForSelector({ + css: '.multichain-app-header__contents--avatar-network .mm-text', + text: 'Localhost 8545', + }); + + // Ensure toast is shown to the user + await driver.waitForSelector({ + css: '.toast-text', + text: 'Localhost 8545 is now active on 127.0.0.1:8080', + }); + }, + ); + }); - it('should gracefully handle network connectivity failure for confirmations @no-mmi', async function () { - const port = 8546; - const chainId = 1338; - await withFixtures( - { - dapp: true, - // Presently confirmations take up to 10 seconds to display on a dead network - driverOptions: { timeOut: 30000 }, - fixtures: new FixtureBuilder() - .withNetworkControllerDoubleGanache() - .withPreferencesControllerUseRequestQueueEnabled() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - concurrent: [ - { - port, - chainId, - ganacheOptions2: defaultGanacheOptions, - }, - ], - }, - // This test intentionally quits Ganache while the extension is using it, causing - // PollingBlockTracker errors and others. These are expected. - ignoredConsoleErrors: ['ignore-all'], - dappOptions: { numberOfDapps: 2 }, - title: this.test.fullTitle(), + it('should gracefully handle network connectivity failure for signatures @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - async ({ driver, ganacheServer, secondaryGanacheServer }) => { - await unlockWallet(driver); - - // Open the first dapp - await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); - - // Open the second dapp and switch chains - await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); - - // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.findElement({ - css: '[data-testid="network-display"]', - text: 'Ethereum Mainnet', - }); - - // Kill ganache servers - await ganacheServer.quit(); - await secondaryGanacheServer[0].quit(); - - // Go back to first dapp, try an action, ensure network connection failure doesn't block UI - await selectDappClickSend(driver, DAPP_URL); - - // When the network is down, there is a performance degradation that causes the - // popup to take a few seconds to open in MV3 (issue #25690) - await driver.waitUntilXWindowHandles(4, 1000, 15000); + // This test intentionally quits Ganache while the extension is using it, causing + // PollingBlockTracker errors and others. These are expected. + ignoredConsoleErrors: ['ignore-all'], + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer, secondaryGanacheServer }) => { + await unlockWallet(driver); + + // Open the first dapp + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open the second dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); + + // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.waitForSelector({ + css: '[data-testid="network-display"]', + text: 'Ethereum Mainnet', + }); + + // Kill ganache servers + await ganacheServer.quit(); + await secondaryGanacheServer[0].quit(); + + // Go back to first dapp, try an action, ensure network connection failure doesn't block UI + await selectDappClickPersonalSign(driver, DAPP_URL); + + // When the network is down, there is a performance degradation that causes the + // popup to take a few seconds to open in MV3 (issue #25690) + await driver.waitUntilXWindowHandles(4, 1000, 15000); + + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x539', + networkText: 'Localhost 8545', + originText: DAPP_URL, + }); + }, + ); + }); - await switchToDialogPopoverValidateDetailsRedesign(driver, { - chainId: '0x539', - networkText: 'Localhost 8545', - originText: DAPP_URL, - }); + it('should gracefully handle network connectivity failure for confirmations @no-mmi', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + // Presently confirmations take up to 10 seconds to display on a dead network + driverOptions: { timeOut: 30000 }, + fixtures: new FixtureBuilder() + .withNetworkControllerDoubleGanache() + + .build(), + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + ], }, - ); - }); + // This test intentionally quits Ganache while the extension is using it, causing + // PollingBlockTracker errors and others. These are expected. + ignoredConsoleErrors: ['ignore-all'], + dappOptions: { numberOfDapps: 2 }, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer, secondaryGanacheServer }) => { + await unlockWallet(driver); + + // Open the first dapp + await openDappAndSwitchChain(driver, DAPP_URL, '0x539'); + + // Open the second dapp and switch chains + await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1'); + + // Go to wallet fullscreen, ensure that the global network changed to Ethereum Mainnet + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.findElement({ + css: '[data-testid="network-display"]', + text: 'Ethereum Mainnet', + }); + + // Kill ganache servers + await ganacheServer.quit(); + await secondaryGanacheServer[0].quit(); + + // Go back to first dapp, try an action, ensure network connection failure doesn't block UI + await selectDappClickSend(driver, DAPP_URL); + + // When the network is down, there is a performance degradation that causes the + // popup to take a few seconds to open in MV3 (issue #25690) + await driver.waitUntilXWindowHandles(4, 1000, 15000); + + await switchToDialogPopoverValidateDetailsRedesign(driver, { + chainId: '0x539', + networkText: 'Localhost 8545', + originText: DAPP_URL, + }); + }, + ); }); }); diff --git a/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js b/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js index 64ac781a20e0..c60d1d0a9278 100644 --- a/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js +++ b/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js @@ -22,7 +22,7 @@ describe('Request Queue WatchAsset -> SwitchChain -> WatchAsset', function () { fixtures: new FixtureBuilder() .withNetworkControllerDoubleGanache() .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerUseRequestQueueEnabled() + .build(), ganacheOptions: { ...defaultGanacheOptions, diff --git a/test/e2e/tests/responsive-ui/metamask-responsive-ui.spec.js b/test/e2e/tests/responsive-ui/metamask-responsive-ui.spec.js index 54236d84f2f5..4c682fafa402 100644 --- a/test/e2e/tests/responsive-ui/metamask-responsive-ui.spec.js +++ b/test/e2e/tests/responsive-ui/metamask-responsive-ui.spec.js @@ -6,239 +6,167 @@ const { logInWithBalanceValidation, openActionMenuAndStartSendFlow, withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('MetaMask Responsive UI', function () { - describe('Old confirmation screens', function () { - it('Send Transaction from responsive window', async function () { - const driverOptions = { constrainWindowSize: true }; - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - driverOptions, - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Send ETH from inside MetaMask - // starts to send a transaction - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - const inputAmount = await driver.fill('input[placeholder="0"]', '1'); - - const inputValue = await inputAmount.getProperty('value'); - assert.equal(inputValue, '1'); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // wait for transaction value to be rendered and confirm - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '1.000042', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // finds the transaction in the transactions list - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1 ETH', - }); - }, - ); - }); + it('Creating a new wallet @no-mmi', async function () { + const driverOptions = { constrainWindowSize: true }; + + await withFixtures( + { + fixtures: new FixtureBuilder({ onboarding: true }).build(), + driverOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await driver.navigate(); + + // agree to terms of use + await driver.clickElement('[data-testid="onboarding-terms-checkbox"]'); + + // welcome + await driver.clickElement('[data-testid="onboarding-create-wallet"]'); + + // metrics + await driver.clickElement('[data-testid="metametrics-no-thanks"]'); + + // create password + await driver.fill( + '[data-testid="create-password-new"]', + 'correct horse battery staple', + ); + await driver.fill( + '[data-testid="create-password-confirm"]', + 'correct horse battery staple', + ); + await driver.clickElement('[data-testid="create-password-terms"]'); + await driver.clickElement('[data-testid="create-password-wallet"]'); + + // secure wallet + await driver.clickElement('[data-testid="secure-wallet-recommended"]'); + + // review + await driver.clickElement('[data-testid="recovery-phrase-reveal"]'); + const chipTwo = await ( + await driver.findElement('[data-testid="recovery-phrase-chip-2"]') + ).getText(); + const chipThree = await ( + await driver.findElement('[data-testid="recovery-phrase-chip-3"]') + ).getText(); + const chipSeven = await ( + await driver.findElement('[data-testid="recovery-phrase-chip-7"]') + ).getText(); + await driver.clickElement('[data-testid="recovery-phrase-next"]'); + + // confirm + await driver.fill('[data-testid="recovery-phrase-input-2"]', chipTwo); + await driver.fill('[data-testid="recovery-phrase-input-3"]', chipThree); + await driver.fill('[data-testid="recovery-phrase-input-7"]', chipSeven); + await driver.clickElement('[data-testid="recovery-phrase-confirm"]'); + + // complete + await driver.clickElement('[data-testid="onboarding-complete-done"]'); + + // pin extension + await driver.clickElement('[data-testid="pin-extension-next"]'); + await driver.clickElement('[data-testid="pin-extension-done"]'); + await driver.assertElementNotPresent('.loading-overlay__spinner'); + // assert balance + await driver.waitForSelector({ + css: '[data-testid="eth-overview__primary-currency"]', + text: '0', + }); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('Creating a new wallet @no-mmi', async function () { - const driverOptions = { constrainWindowSize: true }; - - await withFixtures( - { - fixtures: new FixtureBuilder({ onboarding: true }).build(), - driverOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await driver.navigate(); - - // agree to terms of use - await driver.clickElement( - '[data-testid="onboarding-terms-checkbox"]', - ); - - // welcome - await driver.clickElement('[data-testid="onboarding-create-wallet"]'); - - // metrics - await driver.clickElement('[data-testid="metametrics-no-thanks"]'); - - // create password - await driver.fill( - '[data-testid="create-password-new"]', - 'correct horse battery staple', - ); - await driver.fill( - '[data-testid="create-password-confirm"]', - 'correct horse battery staple', - ); - await driver.clickElement('[data-testid="create-password-terms"]'); - await driver.clickElement('[data-testid="create-password-wallet"]'); - - // secure wallet - await driver.clickElement( - '[data-testid="secure-wallet-recommended"]', - ); - - // review - await driver.clickElement('[data-testid="recovery-phrase-reveal"]'); - const chipTwo = await ( - await driver.findElement('[data-testid="recovery-phrase-chip-2"]') - ).getText(); - const chipThree = await ( - await driver.findElement('[data-testid="recovery-phrase-chip-3"]') - ).getText(); - const chipSeven = await ( - await driver.findElement('[data-testid="recovery-phrase-chip-7"]') - ).getText(); - await driver.clickElement('[data-testid="recovery-phrase-next"]'); - - // confirm - await driver.fill('[data-testid="recovery-phrase-input-2"]', chipTwo); - await driver.fill( - '[data-testid="recovery-phrase-input-3"]', - chipThree, - ); - await driver.fill( - '[data-testid="recovery-phrase-input-7"]', - chipSeven, - ); - await driver.clickElement('[data-testid="recovery-phrase-confirm"]'); - - // complete - await driver.clickElement('[data-testid="onboarding-complete-done"]'); - - // pin extension - await driver.clickElement('[data-testid="pin-extension-next"]'); - await driver.clickElement('[data-testid="pin-extension-done"]'); - await driver.assertElementNotPresent('.loading-overlay__spinner'); - // assert balance - await driver.waitForSelector({ - css: '[data-testid="eth-overview__primary-currency"]', - text: '0', - }); - }, - ); - }); - - it('Importing existing wallet from lock page', async function () { - const driverOptions = { constrainWindowSize: true }; - - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - driverOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await driver.navigate(); - - // Import Secret Recovery Phrase - await driver.waitForSelector({ - tag: 'p', - text: 'Localhost 8545', - }); - await driver.clickElement({ - css: '.unlock-page__link', - text: 'Forgot password?', - }); - - await driver.pasteIntoField( - '[data-testid="import-srp__srp-word-0"]', - TEST_SEED_PHRASE_TWO, - ); - - await driver.fill('#password', 'correct horse battery staple'); - await driver.fill( - '#confirm-password', - 'correct horse battery staple', - ); - await driver.press('#confirm-password', driver.Key.ENTER); - - // balance renders - await locateAccountBalanceDOM(driver, ganacheServer); - }, - ); - }); - - it('Send Transaction from responsive window', async function () { - const driverOptions = { constrainWindowSize: true }; - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - driverOptions, - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Send ETH from inside MetaMask - // starts to send a transaction - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - const inputAmount = await driver.fill('input[placeholder="0"]', '1'); - - const inputValue = await inputAmount.getProperty('value'); - assert.equal(inputValue, '1'); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // wait for transaction value to be rendered and confirm - await driver.waitForSelector({ - css: 'h2', - text: '1 ETH', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); + it('Importing existing wallet from lock page', async function () { + const driverOptions = { constrainWindowSize: true }; + + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + driverOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await driver.navigate(); + + // Import Secret Recovery Phrase + await driver.waitForSelector({ + tag: 'p', + text: 'Localhost 8545', + }); + await driver.clickElement({ + css: '.unlock-page__link', + text: 'Forgot password?', + }); + + await driver.pasteIntoField( + '[data-testid="import-srp__srp-word-0"]', + TEST_SEED_PHRASE_TWO, + ); + + await driver.fill('#password', 'correct horse battery staple'); + await driver.fill('#confirm-password', 'correct horse battery staple'); + await driver.press('#confirm-password', driver.Key.ENTER); + + // balance renders + await locateAccountBalanceDOM(driver, ganacheServer); + }, + ); + }); - // finds the transaction in the transactions list - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', + it('Send Transaction from responsive window', async function () { + const driverOptions = { constrainWindowSize: true }; + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + driverOptions, + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Send ETH from inside MetaMask + // starts to send a transaction + await openActionMenuAndStartSendFlow(driver); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + const inputAmount = await driver.fill('input[placeholder="0"]', '1'); + + const inputValue = await inputAmount.getProperty('value'); + assert.equal(inputValue, '1'); + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // wait for transaction value to be rendered and confirm + await driver.waitForSelector({ + css: 'h2', + text: '1 ETH', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // finds the transaction in the transactions list + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1 ETH', - }); - }, - ); - }); + return confirmedTxes.length === 1; + }, 10000); + + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-1 ETH', + }); + }, + ); }); }); diff --git a/test/e2e/tests/settings/4byte-directory.spec.js b/test/e2e/tests/settings/4byte-directory.spec.js deleted file mode 100644 index b36f72f0575c..000000000000 --- a/test/e2e/tests/settings/4byte-directory.spec.js +++ /dev/null @@ -1,100 +0,0 @@ -const FixtureBuilder = require('../../fixture-builder'); -const { - logInWithBalanceValidation, - openDapp, - openMenuSafe, - unlockWallet, - withFixtures, - WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); - -describe('4byte setting', function () { - it('makes a call to 4byte when the setting is on', async function () { - const smartContract = SMART_CONTRACTS.PIGGYBANK; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // deploy contract - await openDapp(driver, contractAddress); - - // wait for deployed contract, calls and confirms a contract method where ETH is sent - await driver.clickElement('#depositButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - tag: 'span', - text: 'Deposit', - }); - await driver.assertElementNotPresent({ - tag: 'span', - text: 'Contract interaction', - }); - }, - ); - }); - - it('does not try to get contract method name from 4byte when the setting is off', async function () { - const smartContract = SMART_CONTRACTS.PIGGYBANK; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // goes to the settings screen - await openMenuSafe(driver); - await driver.clickElement({ text: 'Settings', tag: 'div' }); - await driver.clickElement({ text: 'Security & privacy', tag: 'div' }); - - // turns off 4Byte Directory contract method name resolution - await driver.clickElement( - '[data-testid="4byte-resolution-container"] .toggle-button', - ); - - // deploy contract - await openDapp(driver, contractAddress); - - // wait for deployed contract, calls and confirms a contract method where ETH is sent - await driver.clickElement('#depositButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.assertElementNotPresent({ - tag: 'span', - text: 'Deposit', - }); - await driver.waitForSelector({ - tag: 'span', - text: 'Contract interaction', - }); - }, - ); - }); -}); diff --git a/test/e2e/tests/settings/show-hex-data.spec.js b/test/e2e/tests/settings/show-hex-data.spec.js deleted file mode 100644 index 353847a544b4..000000000000 --- a/test/e2e/tests/settings/show-hex-data.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -const { - defaultGanacheOptions, - withFixtures, - logInWithBalanceValidation, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -const selectors = { - accountOptionsMenu: '[data-testid="account-options-menu-button"]', - settingsDiv: '[data-testid="global-menu-settings"]', - portfolioMenuOption: '[data-testid="global-menu-mmi-portfolio"]', - advancedDiv: { text: 'Advanced', tag: 'div' }, - hexDataToggle: '[data-testid="advanced-setting-hex-data"] .toggle-button', - appHeaderLogo: '[data-testid="app-header-logo"]', - ethOverviewSend: '[data-testid="eth-overview-send"]', - ensInput: '[data-testid="ens-input"]', - quantity: 'input[placeholder="0"]', - hexDataInput: '[data-testid="send-hex-textarea"]', - nextPageButton: { text: 'Continue', tag: 'button' }, - hexButton: { text: 'Hex', tag: 'button' }, - detailsTab: { text: 'Details', tag: 'button' }, - containerContent: '.confirm-page-container-content', - confirmButton: { text: 'Confirm', tag: 'button' }, -}; - -const inputData = { - recipientAddress: '0x985c30949c92df7a0bd42e0f3e3d539ece98db24', - hexDataText: '0x0abc', -}; - -// Function to click elements in sequence -async function clickElementsInSequence(driver, clickSelectors) { - for (const selector of clickSelectors) { - if (process.env.MMI && selector === selectors.settingsDiv) { - await driver.waitForSelector(selectors.portfolioMenuOption); - } else { - await driver.waitForSelector(selector); - } - await driver.clickElement(selector); - } -} - -// Function to perform the hex data toggle -async function toggleHexData(driver) { - const sequence = [ - selectors.accountOptionsMenu, - selectors.settingsDiv, - selectors.advancedDiv, - selectors.hexDataToggle, - ]; - - await clickElementsInSequence(driver, sequence); -} - -// Function to click on the app logo -async function clickOnLogo(driver) { - await driver.clickElement(selectors.appHeaderLogo); -} - -// Function to send a transaction and verify hex data text area appears. -async function sendTransactionAndVerifyHexData(driver) { - await driver.clickElement(selectors.ethOverviewSend); - await driver.fill(selectors.ensInput, inputData.recipientAddress); - await driver.fill(selectors.quantity, 1); - await driver.fill(selectors.hexDataInput, inputData.hexDataText); - await driver.clickElement(selectors.nextPageButton); - await driver.clickElement(selectors.hexButton); -} - -// Main test suite -describe('Check the toggle for hex data', function () { - it('Setting the hex data toggle and verify that the textbox appears', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await toggleHexData(driver); - await clickOnLogo(driver); - await sendTransactionAndVerifyHexData(driver); - - // Verify hex data in the container content - await driver.waitForSelector({ - tag: 'p', - text: '0x0abc', - }); - }, - ); - }); -}); diff --git a/test/e2e/tests/signature/personal-sign.spec.js b/test/e2e/tests/signature/personal-sign.spec.js index 092a9518ba01..908a422bfea0 100644 --- a/test/e2e/tests/signature/personal-sign.spec.js +++ b/test/e2e/tests/signature/personal-sign.spec.js @@ -116,43 +116,6 @@ describe('Personal sign', function () { }); describe('Redesigned confirmation screens', function () { - it('can initiate and confirm a personal sign', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - const addresses = await ganacheServer.getAccounts(); - const publicAddress = addresses[0]; - await unlockWallet(driver); - - await openDapp(driver); - await driver.clickElement('#personalSign'); - - await driver.waitUntilXWindowHandles(3); - const windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.findElement({ - css: 'p', - text: 'Example `personal_sign` message', - }); - - await driver.clickElement('[data-testid="confirm-footer-button"]'); - - await verifyAndAssertPersonalMessage(driver, publicAddress); - }, - ); - }); - it('can queue multiple personal signs and confirm', async function () { await withFixtures( { diff --git a/test/e2e/tests/signature/signature-request.spec.js b/test/e2e/tests/signature/signature-request.spec.js index 716ee1f98d95..7d37da3de0db 100644 --- a/test/e2e/tests/signature/signature-request.spec.js +++ b/test/e2e/tests/signature/signature-request.spec.js @@ -337,64 +337,6 @@ describe('Sign Typed Data Signature Request', function () { }); describe('Redesigned confirmation screens', function () { - testData.forEach((data) => { - it(`can initiate and confirm a Signature Request of ${data.type}`, async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - const addresses = await ganacheServer.getAccounts(); - const publicAddress = addresses[0]; - await unlockWallet(driver); - - await openDapp(driver); - - // creates a sign typed data signature request - await driver.clickElement(data.buttonId); - - await driver.waitUntilXWindowHandles(3); - let windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await verifyAndAssertRedesignedSignTypedData( - driver, - data.expectedMessage, - ); - - // Approve signing typed data - await finalizeSignatureRequest( - driver, - '.confirm-scroll-to-bottom__button', - 'Confirm', - ); - await driver.waitUntilXWindowHandles(2); - windowHandles = await driver.getAllWindowHandles(); - - // switch to the Dapp and verify the signed address - await driver.switchToWindowWithTitle( - 'E2E Test Dapp', - windowHandles, - ); - await driver.clickElement(data.verifyId); - const recoveredAddress = await driver.findElement( - data.verifyResultId, - ); - - assert.equal(await recoveredAddress.getText(), publicAddress); - }, - ); - }); - }); - testData.forEach((data) => { it(`can queue multiple Signature Requests of ${data.type} and confirm`, async function () { await withFixtures( diff --git a/test/e2e/tests/swaps/shared.ts b/test/e2e/tests/swaps/shared.ts index 3f3aff4447e5..75a965e1dbb6 100644 --- a/test/e2e/tests/swaps/shared.ts +++ b/test/e2e/tests/swaps/shared.ts @@ -216,9 +216,21 @@ export const checkNotification = async ( }; export const changeExchangeRate = async (driver: Driver) => { + // Ensure quote view button is present + await driver.waitForSelector('[data-testid="review-quote-view-all-quotes"]'); + + // Scroll button into view before clicking + await driver.executeScript(` + const element = document.querySelector('[data-testid="review-quote-view-all-quotes"]'); + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + `); + + // Add small delay allowing for smooth scroll + await driver.delay(500); + + // Try to click the element await driver.clickElement('[data-testid="review-quote-view-all-quotes"]'); await driver.waitForSelector({ text: 'Quote details', tag: 'h2' }); - const networkFees = await driver.findElements( '[data-testid*="select-quote-popover-row"]', ); diff --git a/test/e2e/tests/swaps/swap-eth.spec.ts b/test/e2e/tests/swaps/swap-eth.spec.ts index 18d049e5de16..69f21af426f0 100644 --- a/test/e2e/tests/swaps/swap-eth.spec.ts +++ b/test/e2e/tests/swaps/swap-eth.spec.ts @@ -9,51 +9,47 @@ import { mockEthDaiTrade, } from './shared'; +// TODO: (MM-PENDING) These tests are planned for deprecation as part of swaps testing revamp describe('Swap Eth for another Token @no-mmi', function () { - it('Completes second Swaps while first swap is processing', async function () { - withFixturesOptions.ganacheOptions.miner.blockTime = 10; - + it('Completes a Swap between ETH and DAI after changing initial rate', async function () { await withFixtures( { ...withFixturesOptions, + testSpecificMock: mockEthDaiTrade, title: this.test?.fullTitle(), }, async ({ driver }) => { await unlockWallet(driver); + await buildQuote(driver, { - amount: 0.001, - swapTo: 'USDC', + amount: 2, + swapTo: 'DAI', }); + await reviewQuote(driver, { - amount: 0.001, + amount: 2, swapFrom: 'TESTETH', - swapTo: 'USDC', - }); - await driver.clickElement({ text: 'Swap', tag: 'button' }); - await driver.clickElement({ text: 'View in activity', tag: 'button' }); - await buildQuote(driver, { - amount: 0.003, swapTo: 'DAI', }); + + // The changeExchangeRate function now includes scrolling logic + await changeExchangeRate(driver); + await reviewQuote(driver, { - amount: 0.003, + amount: 2, swapFrom: 'TESTETH', swapTo: 'DAI', + skipCounter: true, }); + await driver.clickElement({ text: 'Swap', tag: 'button' }); await waitForTransactionToComplete(driver, { tokenName: 'DAI' }); await checkActivityTransaction(driver, { index: 0, - amount: '0.003', + amount: '2', swapFrom: 'TESTETH', swapTo: 'DAI', }); - await checkActivityTransaction(driver, { - index: 1, - amount: '0.001', - swapFrom: 'TESTETH', - swapTo: 'USDC', - }); }, ); }); diff --git a/test/e2e/tests/swaps/swaps-notifications.spec.ts b/test/e2e/tests/swaps/swaps-notifications.spec.ts index 134741d3683c..d81beab6de2c 100644 --- a/test/e2e/tests/swaps/swaps-notifications.spec.ts +++ b/test/e2e/tests/swaps/swaps-notifications.spec.ts @@ -80,6 +80,7 @@ describe('Swaps - notifications @no-mmi', function () { amount: 2, swapTo: 'INUINU', }); + await checkNotification(driver, { title: 'Potentially inauthentic token', text: 'INUINU is only verified on 1 source. Consider verifying it on Etherscan before proceeding.', diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.js b/test/e2e/tests/tokens/add-multiple-tokens.spec.js deleted file mode 100644 index bc6ea5e6f2c0..000000000000 --- a/test/e2e/tests/tokens/add-multiple-tokens.spec.js +++ /dev/null @@ -1,114 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - defaultGanacheOptions, - openDapp, - switchToNotificationWindow, - WINDOW_TITLES, - DAPP_URL, - unlockWallet, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Multiple ERC20 Watch Asset', function () { - // TODO: This assertion will change once the method is fixed. - it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver, undefined, DAPP_URL); - - // Create Token 1 - const createToken = await driver.findElement({ - text: 'Create Token', - tag: 'button', - }); - await driver.scrollToElement(createToken); - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 1 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses !== ''; - }, 10000); - - // Create Token 2 - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 2 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses.split(',').length === 2; - }, 10000); - - // Create Token 3 - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 3 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses.split(',').length === 3; - }, 10000); - - // Watch all 3 tokens - await driver.clickElement({ - text: 'Add Token(s) to Wallet', - tag: 'button', - }); - - // Switch to watchAsset notification - await switchToNotificationWindow(driver); - const multipleSuggestedtokens = await driver.findElements( - '.confirm-add-suggested-token__token-list-item', - ); - - // Confirm all 3 tokens are present as suggested token list - assert.equal(multipleSuggestedtokens.length, 3); - await driver.findClickableElement({ text: 'Add token', tag: 'button' }); - await driver.clickElement({ text: 'Add token', tag: 'button' }); - - // Switch to fullscreen extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Check all three tokens have been added to the token list. - const addedTokens = await driver.findElements({ - tag: 'p', - text: 'TST', - }); - assert.equal(addedTokens.length, 3); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts new file mode 100644 index 000000000000..78daa2531da1 --- /dev/null +++ b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts @@ -0,0 +1,70 @@ +import AddTokensModal from '../../page-objects/pages/dialog/add-tokens'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import { + withFixtures, + defaultGanacheOptions, + openDapp, + WINDOW_TITLES, + DAPP_URL, + unlockWallet, +} from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; +import CreateContractModal from '../../page-objects/pages/dialog/create-contract'; + +describe('Multiple ERC20 Watch Asset', function () { + it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + await openDapp(driver, undefined, DAPP_URL); + const testDapp = new TestDapp(driver); + + // Create multiple tokens + for (let i = 0; i < 3; i++) { + // Create token + await testDapp.findAndClickCreateToken(); + + // Confirm token creation + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const createContractModal = new CreateContractModal(driver); + await createContractModal.check_pageIsLoaded(); + await createContractModal.clickConfirm(); + + // Wait for token address to populate in dapp + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + await testDapp.check_pageIsLoaded(); + await testDapp.check_TokenAddressesCount(i + 1); + } + + // Watch all 3 tokens + // Switch to watchAsset notification + await testDapp.clickAddTokenToWallet(); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const addTokensPopupModal = new AddTokensModal(driver); + await addTokensPopupModal.check_pageIsLoaded(); + await addTokensPopupModal.check_SuggestedTokensCount(3); + await addTokensPopupModal.confirmAddTokens(); + + // Switch to fullscreen extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Check all three tokens have been added to the token list. + const tokenList = new AssetListPage(driver); + await tokenList.check_tokenItemNumber(4); // 3 tokens plus ETH + await tokenList.check_tokenIsDisplayed('Ethereum'); + await tokenList.check_tokenIsDisplayed('TST'); + }, + ); + }); +}); diff --git a/test/e2e/tests/tokens/custom-token-add-approve.spec.js b/test/e2e/tests/tokens/custom-token-add-approve.spec.js deleted file mode 100644 index 9226ad1a36f1..000000000000 --- a/test/e2e/tests/tokens/custom-token-add-approve.spec.js +++ /dev/null @@ -1,458 +0,0 @@ -const { strict: assert } = require('assert'); -const { - clickNestedButton, - defaultGanacheOptions, - editGasFeeForm, - logInWithBalanceValidation, - openDapp, - WINDOW_TITLES, - withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); - -describe('Create token, approve token and approve token without gas', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('imports and renders the balance for the new token', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver, ganacheServer); - - // imports custom token from extension - await driver.clickElement( - `[data-testid="account-overview__asset-tab"]`, - ); - await clickNestedButton(driver, 'Tokens'); - - await driver.clickElement(`[data-testid="import-token-button"]`); - await driver.clickElement(`[data-testid="importTokens"]`); - await clickNestedButton(driver, 'Custom token'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-address"]', - contractAddress, - ); - await driver.waitForSelector( - '[data-testid="import-tokens-modal-custom-decimals"]', - ); - - await driver.clickElement({ - text: 'Next', - tag: 'button', - }); - - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - - // renders balance for newly created token - await driver.clickElement('.app-header__logo-container'); - - await clickNestedButton(driver, 'Tokens'); - await driver.waitForSelector({ - css: '[data-testid="multichain-token-list-item-value"]', - text: '10 TST', - }); - }, - ); - }); - - it('approves an already created token and displays the token approval data @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // create token - await openDapp(driver, contractAddress); - - let windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - - await driver.findClickableElement('#deployButton'); - // approve token from dapp - await driver.clickElement('#approveTokens'); - - await driver.waitUntilXWindowHandles(3); - windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.clickElement({ - text: 'Verify third-party details', - css: '.token-allowance-container__verify-link', - }); - - // Verification modal is opened - await driver.waitForSelector({ - text: 'Third-party details', - tag: 'h5', - }); - - await driver.clickElementAndWaitToDisappear({ - text: 'Got it', - tag: 'button', - }); - // back to approval modal - await driver.clickElement({ - text: 'View details', - css: '.token-allowance-container__view-details', - }); - - // Validate elements on approve token popup - await driver.waitForSelector({ - text: 'Function: Approve', - tag: 'h6', - }); - const confirmDataDiv = await driver.findElement( - '.approve-content-card-container__data__data-block', - ); - const confirmDataText = await confirmDataDiv.getText(); - assert( - confirmDataText.match( - /0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef4/u, - ), - ); - - await driver.clickElement({ text: 'Next', tag: 'button' }); - // Spending cap modal is opened - await driver.waitForSelector({ - text: '7 TST', - css: '.mm-box > h6', - }); - - await driver.clickElement({ - text: 'Approve', - tag: 'button', - }); - - // We want to wait until txn is finished, and the dialog is closed - // before checking it in the expanded view of extension - await driver.waitUntilXWindowHandles(2); - - // Moved to expanded window to validate the txn - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - // wait for txn in activity section - await driver.waitForSelector( - '[data-testid="activity-list-item-action"]', - ); - await driver.waitForSelector('.transaction-status-label--confirmed'); - }, - ); - }); - - it('set custom spending cap, customizes gas, edit spending cap and checks transaction in transaction list @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // create token - await openDapp(driver, contractAddress); - - let windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - - await driver.findClickableElement('#deployButton'); - - // approve token from dapp - await driver.clickElement({ text: 'Approve Tokens', tag: 'button' }); - - await driver.waitUntilXWindowHandles(3); - windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - // set custom spending cap - let setSpendingCap = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - await setSpendingCap.fill('5'); - - await driver.clickElement({ - text: 'View details', - css: '.token-allowance-container__view-details', - }); - - await driver.clickElement({ - text: 'Next', - tag: 'button', - }); - - let spendingCap = await driver.findElement({ - text: '5 TST', - css: '.mm-box > h6', - }); - - assert.equal( - await spendingCap.getText(), - '5 TST', - 'Default value is not correctly set', - ); - - // editing gas fee - const editBtn = await driver.findElement({ - text: 'Edit', - tag: 'h6', - }); - - editBtn.click(); - - await driver.waitForSelector({ - text: 'Edit priority', - tag: 'header', - }); - - await editGasFeeForm(driver, '60001', '10'); - - await driver.waitForSelector( - { - css: '.box--flex-direction-row > h6', - text: '0.0006 ETH', - }, - { timeout: 15000 }, - ); - - // editing spending cap - await driver.clickElement({ - class: '.review-spending-cap__heading-detail__button', - text: 'Edit', - }); - - setSpendingCap = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - await setSpendingCap.fill('9'); - - await driver.clickElement({ - text: 'Next', - tag: 'button', - }); - - spendingCap = await driver.findElement({ - text: '9 TST', - css: '.mm-box > h6', - }); - assert.equal( - await spendingCap.getText(), - '9 TST', - 'Default value is not correctly set', - ); - - // submits the transaction - await driver.clickElement({ text: 'Approve', tag: 'button' }); - - // finds the transaction in transaction list - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - - await driver.wait(async () => { - const pendingTxes = await driver.findElements('.activity-list-item'); - return pendingTxes.length === 1; - }, 10000); - const approveTokenTask = await driver.waitForSelector({ - // Select only the heading of the first entry in the transaction list. - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Approve TST spending cap', - }); - assert.equal( - await approveTokenTask.getText(), - 'Approve TST spending cap', - ); - }, - ); - }); - - it('set maximum spending cap, submits the transaction and finds the transaction in the transactions list @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // create token - await openDapp(driver, contractAddress); - const windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - - await driver.findClickableElement('#deployButton'); - - // approve token from dapp - await driver.clickElement({ text: 'Approve Tokens', tag: 'button' }); - - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - - const pendingTxes = await driver.findElements( - '.transaction-list__pending-transactions .activity-list-item', - ); - pendingTxes[0].click(); - - // set max spending cap - await driver.clickElement({ - css: '[data-testid="custom-spending-cap-max-button"]', - text: 'Max', - }); - - await driver.clickElement({ - tag: 'button', - text: 'Next', - }); - - // checks the balance - const balance = await driver.findElement({ - css: '.box--display-flex > h6', - text: '10 TST', - }); - - const maxSpendingCap = await driver.findElement({ - text: '10 TST', - css: '.mm-box > h6', - }); - - assert.equal( - await maxSpendingCap.getText(), - await balance.getText(), - 'Max spending cap is not set corectly', - ); - - await driver.clickElement({ - tag: 'button', - text: 'Approve', - }); - - const approveTokenTask = await driver.waitForSelector({ - // Select only the heading of the first entry in the transaction list. - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Approve TST spending cap', - }); - assert.equal( - await approveTokenTask.getText(), - 'Approve TST spending cap', - ); - }, - ); - }); - - it('approves token without gas, set site suggested spending cap, submits the transaction and finds the transaction in the transactions list @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry, ganacheServer }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver, contractAddress); - const windowHandles = await driver.getAllWindowHandles(); - const extension = windowHandles[0]; - - await driver.findClickableElement('#deployButton'); - // approve token without gas from dapp - await driver.clickElement({ - text: 'Approve Tokens Without Gas', - tag: 'button', - }); - - // switch to extension - await driver.switchToWindow(extension); - await clickNestedButton(driver, 'Activity'); - - const pendingTxes = await driver.findElements('.activity-list-item'); - pendingTxes[0].click(); - - // set custom spending cap - const spendingCap = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - await spendingCap.fill('5'); - - // set site suggested spending cap - await driver.clickElement({ - text: 'Use site suggestion', - css: '.mm-button-link', - }); - await driver.clickElement({ - text: 'Next', - tag: 'button', - }); - - await driver.delay(500); - await driver.clickElement({ text: 'Approve', tag: 'button' }); - - // check transaction in Activity tab - const approveTokenTask = await driver.waitForSelector({ - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Approve TST spending cap', - }); - assert.equal( - await approveTokenTask.getText(), - 'Approve TST spending cap', - ); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/custom-token-send-transfer.spec.js b/test/e2e/tests/tokens/custom-token-send-transfer.spec.js index 3774af82ae1c..ccb2a821825b 100644 --- a/test/e2e/tests/tokens/custom-token-send-transfer.spec.js +++ b/test/e2e/tests/tokens/custom-token-send-transfer.spec.js @@ -1,4 +1,3 @@ -const { strict: assert } = require('assert'); const { mockedSourcifyTokenSend, } = require('../confirmations/transactions/erc20-token-send-redesign.spec'); @@ -11,7 +10,6 @@ const { editGasFeeForm, WINDOW_TITLES, clickNestedButton, - tempToggleSettingRedesignedTransactionConfirmations, veryLargeDelayMs, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); @@ -22,408 +20,184 @@ const recipientAddress = '0x2f318C334780961FB129D2a6c30D0763d9a5C970'; describe('Transfer custom tokens @no-mmi', function () { const smartContract = SMART_CONTRACTS.HST; - describe('Old confirmation screens', function () { - it('send custom tokens from extension customizing gas values', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withTokensControllerERC20().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // go to custom tokens view on extension, perform send tokens - await driver.clickElement({ - css: '[data-testid="multichain-token-list-item-value"]', - text: '10 TST', - }); - await driver.delay(500); - await driver.clickElement('[data-testid="eth-overview-send"]'); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - recipientAddress, - ); - await driver.waitForSelector({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - await driver.fill('input[placeholder="0"]', '1'); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // check transaction details - await driver.waitForSelector({ - text: '1 TST', - tag: 'h1', - }); - await driver.waitForSelector({ - text: 'Transfer', - css: '.confirm-page-container-summary__action__name', - }); - const estimatedGasFee = await driver.findElements( - '.currency-display-component__text', - ); - assert.notEqual( - await estimatedGasFee[1].getText(), - '0', - 'Estimated gas fee should not be 0', - ); - - // check function name and hex data details in hex tab - await clickNestedButton(driver, 'Hex'); - await driver.waitForSelector({ - text: 'Transfer', - tag: 'span', - }); - await driver.waitForSelector({ - tag: 'p', - text: '0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97', - }); - - // edit gas fee - await clickNestedButton(driver, 'Details'); - await driver.clickElement({ text: 'Edit', tag: 'button' }); - await editGasFeeForm(driver, '60000', '10'); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // check that transaction has completed correctly and is displayed in the activity list - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Send TST', - }); - await driver.waitForSelector( - { - css: '.transaction-list__completed-transactions [data-testid="transaction-list-item-primary-currency"]', - text: '-1 TST', - }, - { timeout: 10000 }, - ); - }, - ); - }); - - it('transfer custom tokens from dapp customizing gas values', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // transfer token from dapp - await openDapp(driver, contractAddress); - await driver.delay(veryLargeDelayMs); - - await driver.clickElement({ text: 'Transfer Tokens', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ text: '1.5 TST', tag: 'h1' }); - - // edit gas fee - await driver.clickElement({ text: 'Edit', tag: 'button' }); - await editGasFeeForm(driver, '60000', '10'); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // in extension, check that transaction has completed correctly and is displayed in the activity list - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1.5 TST', - }); - - // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" - await driver.waitForSelector({ - text: 'Confirmed', - tag: 'div', - }); - - // check token amount is correct after transaction - await clickNestedButton(driver, 'Tokens'); - const tokenAmount = await driver.findElement( - { - css: '[data-testid="multichain-token-list-item-value"]', - text: '8.5 TST', - }, - { timeout: 10000 }, - ); - assert.ok(tokenAmount, 'Token amount is not correct'); - }, - ); - }); - - it('transfer custom tokens from dapp without specifying gas', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // transfer token from dapp - await openDapp(driver, contractAddress); - await driver.delay(veryLargeDelayMs); - await driver.clickElement({ - text: 'Transfer Tokens Without Gas', - tag: 'button', - }); - await switchToNotificationWindow(driver); - await driver.waitForSelector({ text: '1.5 TST', tag: 'h1' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // in extension, check that transaction has completed correctly and is displayed in the activity list - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1.5 TST', - }); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Send TST', - }); - - // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" - await driver.waitForSelector({ - text: 'Confirmed', - tag: 'div', - }); - - // check token amount is correct after transaction - await clickNestedButton(driver, 'Tokens'); - const tokenAmount = await driver.findElement( - { - css: '[data-testid="multichain-token-list-item-value"]', - text: '8.5 TST', - }, - { timeout: 10000 }, - ); - assert.ok(tokenAmount, 'Token amount is not correct'); - }, - ); - }); + it('send custom tokens from extension customizing gas values', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().withTokensControllerERC20().build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + testSpecificMock: mocks, + }, + async ({ driver }) => { + await unlockWallet(driver); + + // go to custom tokens view on extension, perform send tokens + await driver.clickElement({ + css: '[data-testid="multichain-token-list-item-value"]', + text: '10 TST', + }); + await driver.delay(500); + await driver.clickElement('[data-testid="eth-overview-send"]'); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + recipientAddress, + ); + await driver.waitForSelector({ + css: '.ens-input__selected-input__title', + text: '0x2f318...5C970', + }); + await driver.fill('input[placeholder="0"]', '1'); + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // check transaction details + await driver.waitForSelector({ + text: '1 TST', + tag: 'h2', + }); + + // edit gas fee + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await editGasFeeForm(driver, '60000', '10'); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // check that transaction has completed correctly and is displayed in the activity list + await driver.waitForSelector({ + css: '[data-testid="activity-list-item-action"]', + text: 'Send TST', + }); + await driver.waitForSelector( + { + css: '.transaction-list__completed-transactions [data-testid="transaction-list-item-primary-currency"]', + text: '-1 TST', + }, + { timeout: 10000 }, + ); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('send custom tokens from extension customizing gas values', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withTokensControllerERC20().build(), - ganacheOptions: defaultGanacheOptions, + it('transfer custom tokens from dapp customizing gas values', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .withTokensControllerERC20() + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + testSpecificMock: mocks, + }, + async ({ driver, contractRegistry }) => { + const contractAddress = await contractRegistry.getContractAddress( smartContract, - title: this.test.fullTitle(), - testSpecificMock: mocks, - }, - async ({ driver }) => { - await unlockWallet(driver); - - // go to custom tokens view on extension, perform send tokens - await driver.clickElement({ - css: '[data-testid="multichain-token-list-item-value"]', - text: '10 TST', - }); - await driver.delay(500); - await driver.clickElement('[data-testid="eth-overview-send"]'); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - recipientAddress, - ); - await driver.waitForSelector({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - await driver.fill('input[placeholder="0"]', '1'); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // check transaction details - await driver.waitForSelector({ - text: '1 TST', - tag: 'h2', - }); - - // edit gas fee - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await editGasFeeForm(driver, '60000', '10'); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // check that transaction has completed correctly and is displayed in the activity list - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Send TST', - }); - await driver.waitForSelector( - { - css: '.transaction-list__completed-transactions [data-testid="transaction-list-item-primary-currency"]', - text: '-1 TST', - }, - { timeout: 10000 }, - ); - }, - ); - }); - - it('transfer custom tokens from dapp customizing gas values', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - testSpecificMock: mocks, - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - // transfer token from dapp - await openDapp(driver, contractAddress); - await driver.delay(veryLargeDelayMs); - - await driver.clickElement({ text: 'Transfer Tokens', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ text: '1.5 TST', tag: 'h2' }); - - // edit gas fee - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await editGasFeeForm(driver, '60000', '10'); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // in extension, check that transaction has completed correctly and is displayed in the activity list - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1.5 TST', - }); - - // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" - await driver.waitForSelector({ - text: 'Confirmed', - tag: 'div', - }); - - // check token amount is correct after transaction - await clickNestedButton(driver, 'Tokens'); - const tokenAmount = await driver.findElement( - { - css: '[data-testid="multichain-token-list-item-value"]', - text: '8.5 TST', - }, - { timeout: 10000 }, - ); - assert.ok(tokenAmount, 'Token amount is not correct'); - }, - ); - }); + ); + await unlockWallet(driver); + + // transfer token from dapp + await openDapp(driver, contractAddress); + await driver.delay(veryLargeDelayMs); + + await driver.clickElement({ text: 'Transfer Tokens', tag: 'button' }); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector({ text: '1.5 TST', tag: 'h2' }); + + // edit gas fee + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await editGasFeeForm(driver, '60000', '10'); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // in extension, check that transaction has completed correctly and is displayed in the activity list + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await clickNestedButton(driver, 'Activity'); + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-1.5 TST', + }); + + // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" + await driver.waitForSelector({ + text: 'Confirmed', + tag: 'div', + }); + + // check token amount is correct after transaction + await clickNestedButton(driver, 'Tokens'); + await driver.waitForSelector({ + css: '[data-testid="multichain-token-list-item-value"]', + text: '8.5 TST', + }); + }, + ); + }); - it('transfer custom tokens from dapp without specifying gas', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, + it('transfer custom tokens from dapp without specifying gas', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .withTokensControllerERC20() + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + testSpecificMock: mocks, + }, + async ({ driver, contractRegistry }) => { + const contractAddress = await contractRegistry.getContractAddress( smartContract, - title: this.test.fullTitle(), - testSpecificMock: mocks, - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - // transfer token from dapp - await openDapp(driver, contractAddress); - await driver.delay(veryLargeDelayMs); - await driver.clickElement({ - text: 'Transfer Tokens Without Gas', - tag: 'button', - }); - await switchToNotificationWindow(driver); - await driver.waitForSelector({ text: '1.5 TST', tag: 'h2' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // in extension, check that transaction has completed correctly and is displayed in the activity list - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1.5 TST', - }); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Send TST', - }); - - // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" - await driver.waitForSelector({ - text: 'Confirmed', - tag: 'div', - }); - - // check token amount is correct after transaction - await clickNestedButton(driver, 'Tokens'); - const tokenAmount = await driver.findElement( - { - css: '[data-testid="multichain-token-list-item-value"]', - text: '8.5 TST', - }, - { timeout: 10000 }, - ); - assert.ok(tokenAmount, 'Token amount is not correct'); - }, - ); - }); - - async function mocks(server) { - return [await mockedSourcifyTokenSend(server)]; - } + ); + await unlockWallet(driver); + + // transfer token from dapp + await openDapp(driver, contractAddress); + await driver.delay(veryLargeDelayMs); + await driver.clickElement({ + text: 'Transfer Tokens Without Gas', + tag: 'button', + }); + await switchToNotificationWindow(driver); + await driver.waitForSelector({ text: '1.5 TST', tag: 'h2' }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // in extension, check that transaction has completed correctly and is displayed in the activity list + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await clickNestedButton(driver, 'Activity'); + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-1.5 TST', + }); + await driver.waitForSelector({ + css: '[data-testid="activity-list-item-action"]', + text: 'Send TST', + }); + + // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed" + await driver.waitForSelector({ + text: 'Confirmed', + tag: 'div', + }); + + // check token amount is correct after transaction + await clickNestedButton(driver, 'Tokens'); + await driver.waitForSelector({ + css: '[data-testid="multichain-token-list-item-value"]', + text: '8.5 TST', + }); + }, + ); }); + + async function mocks(server) { + return [await mockedSourcifyTokenSend(server)]; + } }); diff --git a/test/e2e/tests/tokens/import-tokens.spec.js b/test/e2e/tests/tokens/import-tokens.spec.ts similarity index 54% rename from test/e2e/tests/tokens/import-tokens.spec.js rename to test/e2e/tests/tokens/import-tokens.spec.ts index b15c9ffb100a..245381c8d285 100644 --- a/test/e2e/tests/tokens/import-tokens.spec.js +++ b/test/e2e/tests/tokens/import-tokens.spec.ts @@ -1,13 +1,16 @@ -const { strict: assert } = require('assert'); -const { +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import HomePage from '../../page-objects/pages/home/homepage'; + +import { defaultGanacheOptions, withFixtures, unlockWallet, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); +} from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; +import { Mockttp } from '../../mock-e2e'; describe('Import flow', function () { - async function mockPriceFetch(mockServer) { + async function mockPriceFetch(mockServer: Mockttp) { return [ await mockServer .forGet('https://price.api.cx.metamask.io/v2/chains/1/spot-prices') @@ -60,47 +63,28 @@ describe('Import flow', function () { }) .build(), ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), + title: this.test?.fullTitle(), testSpecificMock: mockPriceFetch, }, async ({ driver }) => { await unlockWallet(driver); - await driver.assertElementNotPresent('.loading-overlay'); - - await driver.clickElement('[data-testid="import-token-button"]'); - await driver.clickElement('[data-testid="importTokens"]'); - - await driver.fill('input[placeholder="Search tokens"]', 'cha'); - - await driver.clickElement('.token-list__token_component'); - await driver.clickElement( - '.token-list__token_component:nth-of-type(2)', - ); - await driver.clickElement( - '.token-list__token_component:nth-of-type(3)', - ); - - await driver.clickElement('[data-testid="import-tokens-button-next"]'); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - - // Wait for "loading tokens" to be gone - await driver.assertElementNotPresent( - '[data-testid="token-list-loading-message"]', - ); - - await driver.assertElementNotPresent( - '[data-testid="token-list-loading-message"]', - ); - - await driver.clickElement('[data-testid="sort-by-networks"]'); - await driver.clickElement('[data-testid="network-filter-current"]'); + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + await homePage.check_pageIsLoaded(); + await assetListPage.importMultipleTokensBySearch([ + 'CHAIN', + 'CHANGE', + 'CHAI', + ]); - const expectedTokenListElementsAreFound = - await driver.elementCountBecomesN('.multichain-token-list-item', 4); - assert.equal(expectedTokenListElementsAreFound, true); + const tokenList = new AssetListPage(driver); + await tokenList.check_tokenItemNumber(5); // Linea & Mainnet Eth + await tokenList.check_tokenIsDisplayed('Ethereum'); + await tokenList.check_tokenIsDisplayed('Chain Games'); + // TODO: add back this check once we figure out why tokens name displayed when running the test locally is changex but on CI it is ChangeX + // await tokenList.check_tokenIsDisplayed('Changex'); + await tokenList.check_tokenIsDisplayed('Chai'); }, ); }); diff --git a/test/e2e/tests/tokens/increase-token-allowance.spec.js b/test/e2e/tests/tokens/increase-token-allowance.spec.js deleted file mode 100644 index 9ce8db2cc065..000000000000 --- a/test/e2e/tests/tokens/increase-token-allowance.spec.js +++ /dev/null @@ -1,329 +0,0 @@ -const { strict: assert } = require('assert'); -const FixtureBuilder = require('../../fixture-builder'); -const { - defaultGanacheOptions, - openDapp, - sendTransaction, - unlockWallet, - withFixtures, - ACCOUNT_1, - ACCOUNT_2, - WINDOW_TITLES, - clickNestedButton, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); - -const DEFAULT_TEST_DAPP_INCREASE_ALLOWANCE_SPENDING_CAP = '1'; - -describe('Increase Token Allowance', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('increases token spending cap to allow other accounts to transfer tokens @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const ACCOUNT_1_NAME = 'Account 1'; - const ACCOUNT_2_NAME = '2nd Account'; - - const initialSpendingCap = '1'; - const additionalSpendingCap = '1'; - - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await openDapp(driver, contractAddress); - - await deployTokenContract(driver); - await approveTokenSpendingCapTo(driver, ACCOUNT_2, initialSpendingCap); - - await sendTransaction(driver, ACCOUNT_2, '1'); - await addAccount(driver, ACCOUNT_2_NAME); - - await triggerTransferFromTokens(driver, ACCOUNT_1, ACCOUNT_2); - // 'Transfer From Tokens' on the test dApp attempts to transfer 1.5 TST. - // Since this is higher than the 'initialSpendingCap', it should fail. - await pollForTokenAddressesError( - driver, - 'reverted ERC20: insufficient allowance', - ); - - await switchToAccountWithName(driver, ACCOUNT_1_NAME); - - await increaseTokenAllowance(driver, additionalSpendingCap); - - await switchToAccountWithName(driver, ACCOUNT_2_NAME); - await triggerTransferFromTokens(driver, ACCOUNT_1, ACCOUNT_2); - await confirmTransferFromTokensSuccess(driver); - }, - ); - }); - - async function deployTokenContract(driver) { - await driver.findClickableElement('#deployButton'); - } - - async function approveTokenSpendingCapTo( - driver, - accountToApproveFor, - initialSpendingCap, - ) { - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - const approveToFillEl = await driver.findElement('[id="approveTo"]'); - await approveToFillEl.clear(); - await approveToFillEl.fill(accountToApproveFor); - - await driver.clickElement({ text: 'Approve Tokens', tag: 'button' }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - - const pendingTransactions = await driver.findElements( - '.transaction-list__pending-transactions .activity-list-item', - ); - pendingTransactions[0].click(); - - const setSpendingCap = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - await setSpendingCap.fill(initialSpendingCap); - - await driver.clickElement({ - tag: 'button', - text: 'Next', - }); - await driver.waitForSelector({ - css: '.box--display-flex > h6', - text: `10 TST`, - }); - await driver.waitForSelector({ - text: `${initialSpendingCap} TST`, - css: '.mm-box > h6', - }); - await driver.clickElement({ - tag: 'button', - text: 'Approve', - }); - - await driver.waitForSelector({ - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Approve TST spending cap', - }); - } - - async function addAccount(driver, newAccountName) { - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-account"]', - ); - - await driver.fill('[placeholder="Account 2"]', newAccountName); - await driver.clickElement({ text: 'Add account', tag: 'button' }); - await driver.findElement({ - css: '[data-testid="account-menu-icon"]', - text: newAccountName, - }); - } - - async function triggerTransferFromTokens( - driver, - senderAccount, - recipientAccount, - ) { - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - const transferFromSenderInputEl = await driver.findElement( - '[id="transferFromSenderInput"]', - ); - await transferFromSenderInputEl.clear(); - await transferFromSenderInputEl.fill(senderAccount); - - const transferFromRecipientInputEl = await driver.findElement( - '[id="transferFromRecipientInput"]', - ); - await transferFromRecipientInputEl.clear(); - await transferFromRecipientInputEl.fill(recipientAccount); - - await driver.clickElement('#transferFromTokens'); - await driver.delay(2000); - } - - async function pollForTokenAddressesError( - driver, - errorMessagePart, - timeout = driver.timeout, - ) { - const pollInterval = 500; - let elapsedTime = 0; - - await new Promise((resolve, reject) => { - const pollInsufficientAllowanceError = setInterval(async () => { - try { - const tokenAddressesElement = await driver.findElement( - '#tokenMethodsResult', - ); - const tokenAddressesMsgText = await tokenAddressesElement.getText(); - const isErrorThrown = - tokenAddressesMsgText.includes(errorMessagePart); - - if (isErrorThrown) { - // Condition satisfied, stopping poll. - clearInterval(pollInsufficientAllowanceError); - resolve(); - } else { - elapsedTime += pollInterval; - if (elapsedTime >= timeout) { - // Timeout reached, stopping poll. - clearInterval(pollInsufficientAllowanceError); - reject( - new Error( - `Did not throw '${errorMessagePart}' error as expected. Timeout reached, stopping poll.`, - ), - ); - } - } - } catch (error) { - clearInterval(pollInsufficientAllowanceError); - reject(error); - } - }, pollInterval); - }); - } - - async function switchToAccountWithName(driver, accountName) { - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement('[data-testid="account-menu-icon"]'); - - await driver.findElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: accountName, - }); - - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: accountName, - }); - } - - async function increaseTokenAllowance(driver, finalSpendingCap) { - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.clickElement({ - text: 'Increase Token Allowance', - tag: 'button', - }); - await driver.delay(2000); - - // Windows: MetaMask, Test Dapp and Dialog - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - let spendingCapElement = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - - let spendingCapValue = await spendingCapElement.getProperty('value'); - assert.equal( - spendingCapValue, - DEFAULT_TEST_DAPP_INCREASE_ALLOWANCE_SPENDING_CAP, - 'Default Test Dapp Increase Allowance Spending Cap is unexpected', - ); - - spendingCapElement = await driver.findElement( - '[data-testid="custom-spending-cap-input"]', - ); - await spendingCapElement.clear(); - - await spendingCapElement.fill('0'); - - await driver.clickElement({ - text: 'Use site suggestion', - tag: 'button', - }); - - spendingCapValue = await spendingCapElement.getProperty('value'); - assert.equal( - spendingCapValue, - DEFAULT_TEST_DAPP_INCREASE_ALLOWANCE_SPENDING_CAP, - 'Test Dapp Suggestion Increase Allowance Spending Cap is unexpected', - ); - - await spendingCapElement.fill(finalSpendingCap); - - await driver.clickElement({ - tag: 'button', - text: 'Next', - }); - await driver.waitForSelector({ - css: '.box--display-flex > h6', - text: `10 TST`, - }); - await driver.assertElementNotPresent( - { - tag: 'h6', - text: '0.000054 ETH', - }, - { - waitAtLeastGuard: 2000, - }, - ); - await driver.waitForSelector({ - tag: 'h6', - text: '0.000062 ETH', - }); - await driver.waitForSelector({ - text: `${finalSpendingCap} TST`, - css: '.mm-box > h6', - }); - await driver.clickElementAndWaitForWindowToClose({ - tag: 'button', - text: 'Approve', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - await driver.waitForSelector({ - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Increase TST spending cap', - }); - - await driver.delay(2000); - } - - async function confirmTransferFromTokensSuccess(driver) { - // Windows: MetaMask, Test Dapp and Dialog - await driver.waitUntilXWindowHandles(3, 1000, 10000); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ text: '1.5 TST', tag: 'h1' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'Activity'); - - await driver.waitForSelector({ - css: '.transaction-list__completed-transactions .activity-list-item [data-testid="activity-list-item-action"]', - text: 'Send TST', - }); - } -}); diff --git a/test/e2e/tests/tokens/nft/auto-detect-nft.spec.ts b/test/e2e/tests/tokens/nft/auto-detect-nft.spec.ts index a1bc9005a2f3..5856ea7a7a3d 100644 --- a/test/e2e/tests/tokens/nft/auto-detect-nft.spec.ts +++ b/test/e2e/tests/tokens/nft/auto-detect-nft.spec.ts @@ -42,7 +42,7 @@ describe('NFT detection', function () { await homepage.goToNftTab(); const nftListPage = new NFTListPage(driver); await nftListPage.check_nftNameIsDisplayed( - 'ENS: Ethereum Name Service (1)', + 'ENS: Ethereum Name Service', ); await nftListPage.check_nftImageIsDisplayed(); }, diff --git a/test/e2e/tests/tokens/nft/erc1155-interaction.spec.js b/test/e2e/tests/tokens/nft/erc1155-interaction.spec.js deleted file mode 100644 index 388247bb3fcd..000000000000 --- a/test/e2e/tests/tokens/nft/erc1155-interaction.spec.js +++ /dev/null @@ -1,331 +0,0 @@ -const { strict: assert } = require('assert'); -const { mockNetworkStateOld } = require('../../../../stub/networks'); -const { - withFixtures, - DAPP_URL, - openDapp, - unlockWallet, - WINDOW_TITLES, - defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, - veryLargeDelayMs, -} = require('../../../helpers'); -const { SMART_CONTRACTS } = require('../../../seeder/smart-contracts'); -const FixtureBuilder = require('../../../fixture-builder'); - -describe('ERC1155 NFTs testdapp interaction', function () { - const smartContract = SMART_CONTRACTS.ERC1155; - - it('should mint ERC1155 token', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withNetworkController( - mockNetworkStateOld({ - chainId: '0x539', - nickname: 'Localhost 8545', - rpcUrl: 'http://localhost:8545', - ticker: 'ETH', - blockExplorerUrl: 'https://etherscan.io/', - }), - ) - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Mint - await driver.fill('#batchMintTokenIds', '1, 2, 3'); - await driver.fill('#batchMintIdAmounts', '1, 1, 1000000000000000'); - await driver.clickElement('#batchMintButton'); - - // Notification - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm Mint - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - await driver.clickElement('[data-testid="activity-list-item-action"]'); - await driver.clickElement({ - text: 'View on block explorer', - tag: 'a', - }); - - // Switch to block explorer - await driver.switchToWindowWithTitle('E2E Test Page'); - await driver.findElement('[data-testid="empty-page-body"]'); - // Verify block explorer - await driver.waitForUrl({ - url: 'https://etherscan.io/tx/0xfe4428397f7913875783c5c0dad182937b596148295bc33c7f08d74fdee8897f', - }); - - // switch to Dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.fill('#watchAssetInput', '1'); - await driver.clickElement('#watchAssetButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElementAndWaitForWindowToClose( - '[data-testid="page-container-footer-next"]', - ); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - await driver.clickElementSafe('[data-testid="popover-close"]'); - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - await driver.clickElement('[data-testid="nft-item"]'); - }, - ); - }); - - it('should batch transfers ERC1155 token', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openDapp(driver, contract); - - await driver.fill('#batchTransferTokenIds', '1, 2, 3'); - await driver.fill('#batchTransferTokenAmounts', '1, 1, 1000000000000'); - await driver.clickElement('#batchTransferFromButton'); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm Transfer - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - }, - ); - }); - - it('should enable approval for a third party address to manage all ERC1155 token', async function () { - // ERC1155 is the name of the test-dapp ERC1155 contract - const expectedMessageTitle = - 'Allow access to and transfer all of your NFTs from ERC1155?'; - const expectedDescription = - 'This allows a third party to access and transfer all of your NFTs from ERC1155 without further notice until you revoke its access.'; - const expectedWarningMessage = 'Your NFT may be at risk'; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Create a set approval for all erc1155 token request in test dapp - await openDapp(driver, contract); - await driver.clickElement('#setApprovalForAllERC1155Button'); - - // Wait for notification popup and check the displayed message - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '[data-testid="confirm-approve-title"]', - text: expectedMessageTitle, - }); - await driver.waitForSelector({ - css: '.confirm-approve-content h6', - text: DAPP_URL, - }); - - await driver.waitForSelector({ - css: '.confirm-approve-content__description', - text: expectedDescription, - }); - - // Check displayed transaction details - await driver.clickElement({ - text: 'View full transaction details', - css: '.confirm-approve-content__small-blue-text', - }); - const [func, params] = await driver.findElements( - '.confirm-approve-content__data .confirm-approve-content__small-text', - ); - assert.equal(await func.getText(), 'Function: SetApprovalForAll'); - assert.equal(await params.getText(), 'Parameters: true'); - - // Check the warning message and confirm set approval for all - await driver.clickElement('[data-testid="page-container-footer-next"]'); - const displayedWarning = await driver.findElement( - '.set-approval-for-all-warning__content__header', - ); - assert.equal(await displayedWarning.getText(), expectedWarningMessage); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Approve', - tag: 'button', - }); - - // Switch to extension and check set approval for all transaction is displayed in activity tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '.transaction-list__completed-transactions', - text: 'Approve Token with no spend limit', - }); - - // Switch back to the dapp and verify that set approval for all action completed message is displayed - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.waitForSelector({ - css: '#erc1155Status', - text: 'Set Approval For All completed', - }); - }, - ); - }); - - it('should revoke approval for a third party address to manage all ERC1155 token', async function () { - // ERC1155 is the name of the test-dapp ERC1155 contract - const expectedMessageTitle = - 'Revoke permission to access and transfer all of your NFTs from ERC1155?'; - const expectedDescription = - 'This revokes the permission for a third party to access and transfer all of your NFTs from ERC1155 without further notice.'; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Create a revoke approval for all erc1155 token request in test dapp - await openDapp(driver, contract); - - await driver.delay(veryLargeDelayMs); - - await driver.clickElement('#revokeERC1155Button'); - - // Wait for notification popup and check the displayed message - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await driver.waitForSelector({ - css: '.confirm-approve-content__title', - text: expectedMessageTitle, - }); - - await driver.waitForSelector({ - css: '.confirm-approve-content h6', - text: DAPP_URL, - }); - - await driver.waitForSelector({ - css: '.confirm-approve-content__description', - text: expectedDescription, - }); - - // Check displayed transaction details - await driver.clickElement({ - text: 'View full transaction details', - css: '.confirm-approve-content__small-blue-text', - }); - const [func, params] = await driver.findElements( - '.confirm-approve-content__data .confirm-approve-content__small-text', - ); - assert.equal(await func.getText(), 'Function: SetApprovalForAll'); - assert.equal(await params.getText(), 'Parameters: false'); - - // Click on extension popup to confirm revoke approval for all - await driver.clickElementAndWaitForWindowToClose( - '[data-testid="page-container-footer-next"]', - ); - - // Switch to extension and check revoke approval transaction is displayed in activity tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '.transaction-list__completed-transactions', - text: 'Approve Token with no spend limit', - }); - - // Switch back to the dapp and verify that revoke approval for all message is displayed - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - const revokeApprovalStatus = await driver.findElement({ - css: '#erc1155Status', - text: 'Revoke completed', - }); - assert.equal(await revokeApprovalStatus.isDisplayed(), true); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/nft/erc721-interaction.spec.js b/test/e2e/tests/tokens/nft/erc721-interaction.spec.js deleted file mode 100644 index ecd614f1b8a4..000000000000 --- a/test/e2e/tests/tokens/nft/erc721-interaction.spec.js +++ /dev/null @@ -1,1038 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - openDapp, - unlockWallet, - WINDOW_TITLES, - defaultGanacheOptions, - clickNestedButton, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../../helpers'); -const { SMART_CONTRACTS } = require('../../../seeder/smart-contracts'); -const FixtureBuilder = require('../../../fixture-builder'); - -// describe('Old confirmation screens', function () { -// // ... -// }); - -// describe('Redesigned confirmation screens', function () { -// // ... -// }); - -describe('ERC721 NFTs testdapp interaction', function () { - const smartContract = SMART_CONTRACTS.NFTS; - - describe('Old confirmation screens', function () { - it('should add NFTs to state by parsing tx logs without having to click on watch NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFTs - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.waitForSelector({ - css: '#nftsStatus', - text: 'Mint completed', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (5)' }); - const nftsListItemsFirstCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsFirstCheck.length, 5); - }, - ); - }); - - it('should prompt users to add their NFTs to their wallet (one by one) @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFT - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - const nftsMintStatus = await driver.findElement({ - css: '#nftsStatus', - text: 'Mint completed', - }); - assert.equal(await nftsMintStatus.isDisplayed(), true); - - // watch 3 of the nfts - await driver.fill('#watchNFTInput', '1'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '2'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '3'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // avoid race condition - await driver.waitForSelector({ - css: '.confirm-add-suggested-nft__nft-tokenId', - text: '#3', - }); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - await driver.clickElement({ text: 'Add NFTs', tag: 'button' }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - // Changed this check from 3 to 6, because after mint all nfts has been added to state, - await driver.findElement({ text: 'TestDappNFTs (6)' }); - const nftsListItemsFirstCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsFirstCheck.length, 6); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.fill('#watchNFTInput', '4'); - - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '5'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '6'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // avoid race condition - await driver.waitForSelector({ - css: '.confirm-add-suggested-nft__nft-tokenId', - text: '#6', - }); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - await driver.clickElement({ text: 'Add NFTs', tag: 'button' }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (6)' }); - const nftsListItemsSecondCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsSecondCheck.length, 6); - }, - ); - }); - - it('should prompt users to add their NFTs to their wallet (all at once)', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFT - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - css: '.confirm-page-container-summary__action__name', - text: 'Deposit', - }); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - // We need to wait until the transaction is confirmed before looking for the tx - // otherwise the element becomes stale, as it updates from 'pending' to 'confirmed' - await driver.waitForSelector('.transaction-status-label--confirmed'); - - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.waitForSelector({ - css: '#nftsStatus', - text: 'Mint completed', - }); - - // watch all nfts - await driver.clickElement({ text: 'Watch all NFTs', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - - await driver.findElements( - '.confirm-add-suggested-nft__nft-list-item', - ); - const suggestedNftListItems = await driver.findElements( - '.confirm-add-suggested-nft__nft-list-item', - ); - // there are 6 nfts to add because one is minted as part of the fixture - assert.equal(suggestedNftListItems.length, 6); - - // remove one nft from the list - const removeButtons = await driver.findElements( - '.confirm-add-suggested-nft__nft-remove', - ); - await removeButtons[0].click(); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Add NFTs', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (5)' }); - const nftsListItemsSecondCheck = await driver.findElements( - '.nft-item__container', - ); - - assert.equal(nftsListItemsSecondCheck.length, 5); - }, - ); - }); - - it('should transfer a single ERC721 NFT from one account to another', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Click Transfer - await driver.fill('#transferTokenInput', '1'); - await driver.clickElement('#transferFromButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm transfer - await driver.waitForSelector({ - css: '.mm-text--heading-md', - text: 'TestDappNFTs', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.findElement({ text: 'Send TDN' }); - }, - ); - }); - - it('should approve an address to transfer a single ERC721 NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Click Approve - const approveInput = await driver.findElement('#approveTokenInput'); - await approveInput.clear(); - await approveInput.sendKeys('1'); - await driver.clickElement('#approveButton'); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Verify dialog - const title = await driver.findElement( - '[data-testid="confirm-approve-title"]', - ); - await driver.clickElement({ - text: 'View full transaction details', - css: '.confirm-approve-content__small-blue-text', - }); - const [func] = await driver.findElements( - '.confirm-approve-content__data .confirm-approve-content__small-text', - ); - assert.equal( - await title.getText(), - 'Allow access to and transfer of your TestDappNFTs (#1)?', - ); - assert.equal(await func.getText(), 'Function: Approve'); - - // Confirm approval - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .transaction-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN spending cap', - }); - }, - ); - }); - - it('should enable approval for a third party address to manage all ERC721 NFTs @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Enable Set approval for all - await driver.clickElement('#setApprovalForAllButton'); - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Verify dialog - const title = await driver.findElement( - '[data-testid="confirm-approve-title"]', - ); - await driver.clickElement({ - text: 'View full transaction details', - css: '.confirm-approve-content__small-blue-text', - }); - const [func, params] = await driver.findElements( - '.confirm-approve-content__data .confirm-approve-content__small-text', - ); - assert.equal( - await title.getText(), - 'Allow access to and transfer of all your TestDappNFTs?', - ); - assert.equal(await func.getText(), 'Function: SetApprovalForAll'); - assert.equal(await params.getText(), 'Parameters: true'); - - // Confirm enabling set approval for all - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Approve', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN with no spend limit', - }); - }, - ); - }); - - it('should disable approval for a third party address to manage all ERC721 NFTs @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Disable Set approval for all - await driver.clickElement('#revokeButton'); - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Verify dialog - const title = await driver.findElement( - '[data-testid="confirm-approve-title"]', - ); - await driver.clickElement({ - text: 'View full transaction details', - css: '.confirm-approve-content__small-blue-text', - }); - const [func, params] = await driver.findElements( - '.confirm-approve-content__data .confirm-approve-content__small-text', - ); - const proceedWithCautionIsDisplayed = await driver.isElementPresent( - '.dialog--error', - ); - assert.equal( - await title.getText(), - 'Revoke permission to access and transfer all of your TestDappNFTs?', - ); - assert.equal(await func.getText(), 'Function: SetApprovalForAll'); - assert.equal(await params.getText(), 'Parameters: false'); - assert.equal(proceedWithCautionIsDisplayed, false); - - // Confirm disabling set approval for all - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .transaction-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN with no spend limit', - }); - }, - ); - }); - }); - - describe('Redesigned confirmation screens', function () { - it('should add NFTs to state by parsing tx logs without having to click on watch NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFTs - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.waitForSelector({ - css: '#nftsStatus', - text: 'Mint completed', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (5)' }); - const nftsListItemsFirstCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsFirstCheck.length, 5); - }, - ); - }); - - it('should prompt users to add their NFTs to their wallet (one by one) @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFT - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - const nftsMintStatus = await driver.findElement({ - css: '#nftsStatus', - text: 'Mint completed', - }); - assert.equal(await nftsMintStatus.isDisplayed(), true); - - // watch 3 of the nfts - await driver.fill('#watchNFTInput', '1'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '2'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '3'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // avoid race condition - await driver.waitForSelector({ - css: '.confirm-add-suggested-nft__nft-tokenId', - text: '#3', - }); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - await driver.clickElement({ text: 'Add NFTs', tag: 'button' }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - // Changed this check from 3 to 6, because after mint all nfts has been added to state, - await driver.findElement({ text: 'TestDappNFTs (6)' }); - const nftsListItemsFirstCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsFirstCheck.length, 6); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.fill('#watchNFTInput', '4'); - - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '5'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - await driver.fill('#watchNFTInput', '6'); - await driver.clickElement({ text: 'Watch NFT', tag: 'button' }); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // avoid race condition - await driver.waitForSelector({ - css: '.confirm-add-suggested-nft__nft-tokenId', - text: '#6', - }); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - await driver.clickElement({ text: 'Add NFTs', tag: 'button' }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (6)' }); - const nftsListItemsSecondCheck = await driver.findElements( - '.nft-item__container', - ); - assert.equal(nftsListItemsSecondCheck.length, 6); - }, - ); - }); - - it('should prompt users to add their NFTs to their wallet (all at once)', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // mint NFT - await driver.fill('#mintAmountInput', '5'); - await driver.clickElement({ text: 'Mint', tag: 'button' }); - - // Notification - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.clickElementAndWaitForWindowToClose({ - text: 'Confirm', - tag: 'button', - }); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - // We need to wait until the transaction is confirmed before looking for the tx - // otherwise the element becomes stale, as it updates from 'pending' to 'confirmed' - await driver.waitForSelector('.transaction-status-label--confirmed'); - - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Deposit', - }); - // verify the mint transaction has finished - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.waitForSelector({ - css: '#nftsStatus', - text: 'Mint completed', - }); - - // watch all nfts - await driver.clickElement({ text: 'Watch all NFTs', tag: 'button' }); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // confirm watchNFT - await driver.waitForSelector({ - css: '.mm-text--heading-lg', - text: 'Add suggested NFTs', - }); - - await driver.findElements( - '.confirm-add-suggested-nft__nft-list-item', - ); - const suggestedNftListItems = await driver.findElements( - '.confirm-add-suggested-nft__nft-list-item', - ); - // there are 6 nfts to add because one is minted as part of the fixture - assert.equal(suggestedNftListItems.length, 6); - - // remove one nft from the list - const removeButtons = await driver.findElements( - '.confirm-add-suggested-nft__nft-remove', - ); - await removeButtons[0].click(); - - await driver.clickElementAndWaitForWindowToClose({ - text: 'Add NFTs', - tag: 'button', - }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await clickNestedButton(driver, 'NFTs'); - await driver.findElement({ text: 'TestDappNFTs (5)' }); - const nftsListItemsSecondCheck = await driver.findElements( - '.nft-item__container', - ); - - assert.equal(nftsListItemsSecondCheck.length, 5); - }, - ); - }); - - it('should transfer a single ERC721 NFT from one account to another', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Click Transfer - await driver.fill('#transferTokenInput', '1'); - await driver.clickElement('#transferFromButton'); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm transfer - await driver.waitForSelector({ - css: 'h2', - text: 'TestDappNFTs', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.findElement({ text: 'Send TDN' }); - }, - ); - }); - - it('should approve an address to transfer a single ERC721 NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Click Approve - const approveInput = await driver.findElement('#approveTokenInput'); - await approveInput.clear(); - await approveInput.sendKeys('1'); - await driver.clickElement('#approveButton'); - - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm approval - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .transaction-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN spending cap', - }); - }, - ); - }); - - it('should enable approval for a third party address to manage all ERC721 NFTs @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Enable Set approval for all - await driver.clickElement('#setApprovalForAllButton'); - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm enabling set approval for all - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN with no spend limit', - }); - }, - ); - }); - - it('should disable approval for a third party address to manage all ERC721 NFTs @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, _, contractRegistry }) => { - const contract = contractRegistry.getContractAddress(smartContract); - await unlockWallet(driver); - - // Open Dapp and wait for deployed contract - await openDapp(driver, contract); - await driver.findClickableElement('#deployButton'); - - // Disable Set approval for all - await driver.clickElement('#revokeButton'); - await driver.waitUntilXWindowHandles(3); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // Confirm disabling set approval for all - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .transaction-list-item:nth-of-type(1)', - ); - - // Verify transaction - await driver.waitForSelector({ - css: '[data-testid="activity-list-item-action"]', - text: 'Approve TDN with no spend limit', - }); - }, - ); - }); - }); -}); diff --git a/test/e2e/tests/tokens/nft/import-erc1155.spec.js b/test/e2e/tests/tokens/nft/import-erc1155.spec.js index 0eab8a731b7c..2045743f52be 100644 --- a/test/e2e/tests/tokens/nft/import-erc1155.spec.js +++ b/test/e2e/tests/tokens/nft/import-erc1155.spec.js @@ -44,10 +44,9 @@ describe('Import ERC1155 NFT', function () { assert.equal(await newNftNotification.isDisplayed(), true); // Check the imported ERC1155 and its image are displayed in the ERC1155 tab - const importedERC1155 = await driver.waitForSelector({ - css: 'h5', - text: 'Unnamed collection', - }); + const importedERC1155 = await driver.findElement( + '[data-testid="nft-item"]', + ); assert.equal(await importedERC1155.isDisplayed(), true); const importedERC1155Image = await driver.findVisibleElement( diff --git a/test/e2e/tests/tokens/nft/import-nft.spec.ts b/test/e2e/tests/tokens/nft/import-nft.spec.ts index 5983d1002035..ec3503d1a8a4 100644 --- a/test/e2e/tests/tokens/nft/import-nft.spec.ts +++ b/test/e2e/tests/tokens/nft/import-nft.spec.ts @@ -1,4 +1,5 @@ import { defaultGanacheOptions, withFixtures } from '../../../helpers'; +import { ACCOUNT_TYPE } from '../../../constants'; import { SMART_CONTRACTS } from '../../../seeder/smart-contracts'; import FixtureBuilder from '../../../fixture-builder'; import AccountListPage from '../../../page-objects/pages/account-list-page'; @@ -31,7 +32,6 @@ describe('Import NFT', function () { const nftList = new NftListPage(driver); await nftList.importNft(contractAddress, '1'); await nftList.check_successImportNftMessageIsDisplayed(); - await nftList.check_nftNameIsDisplayed('TestDappNFTs'); await nftList.check_nftImageIsDisplayed(); }, ); @@ -59,7 +59,6 @@ describe('Import NFT', function () { const nftList = new NftListPage(driver); await nftList.importNft(contractAddress, '1'); await nftList.check_successImportNftMessageIsDisplayed(); - await nftList.check_nftNameIsDisplayed('TestDappNFTs'); await nftList.check_nftImageIsDisplayed(); // Create new account with default name Account 2 @@ -67,7 +66,9 @@ describe('Import NFT', function () { await headerNavbar.openAccountMenu(); const accountListPage = new AccountListPage(driver); await accountListPage.check_pageIsLoaded(); - await accountListPage.addNewAccount(); + await accountListPage.addAccount({ + accountType: ACCOUNT_TYPE.Ethereum, + }); await headerNavbar.check_accountLabel('Account 2'); await homepage.check_expectedBalanceIsDisplayed(); @@ -78,7 +79,6 @@ describe('Import NFT', function () { await accountListPage.switchToAccount('Account 1'); await headerNavbar.check_accountLabel('Account 1'); await homepage.check_localBlockchainBalanceIsDisplayed(ganacheServer); - await nftList.check_nftNameIsDisplayed('TestDappNFTs'); await nftList.check_nftImageIsDisplayed(); }, ); diff --git a/test/e2e/tests/tokens/nft/remove-erc1155.spec.js b/test/e2e/tests/tokens/nft/remove-erc1155.spec.js index b67540f49dfe..0ea7b3fb779b 100644 --- a/test/e2e/tests/tokens/nft/remove-erc1155.spec.js +++ b/test/e2e/tests/tokens/nft/remove-erc1155.spec.js @@ -35,7 +35,7 @@ describe('Remove ERC1155 NFT', function () { // Open the details page and click remove nft button await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - await driver.clickElement('[data-testid="nft-image"]'); + await driver.clickElement('.nft-item__container'); await driver.clickElement('[data-testid="nft-options__button"]'); await driver.clickElement('[data-testid="nft-item-remove"]'); diff --git a/test/e2e/tests/tokens/nft/send-nft.spec.js b/test/e2e/tests/tokens/nft/send-nft.spec.js deleted file mode 100644 index 13cb310f1416..000000000000 --- a/test/e2e/tests/tokens/nft/send-nft.spec.js +++ /dev/null @@ -1,187 +0,0 @@ -const { strict: assert } = require('assert'); -const { - defaultGanacheOptions, - logInWithBalanceValidation, - unlockWallet, - withFixtures, - tempToggleSettingRedesignedTransactionConfirmations, -} = require('../../../helpers'); -const { SMART_CONTRACTS } = require('../../../seeder/smart-contracts'); -const FixtureBuilder = require('../../../fixture-builder'); - -describe('Send NFT', function () { - const smartContract = SMART_CONTRACTS.NFTS; - const erc1155SmartContract = SMART_CONTRACTS.ERC1155; - - it('should be able to send ERC721 NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC721().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Fill the send NFT form and confirm the transaction - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - await driver.clickElement('.nft-item__container'); - // TODO: Update Test when Multichain Send Flow is added - await driver.clickElement({ text: 'Send', tag: 'button' }); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - ); - await driver.clickElement({ - text: 'Continue', - tag: 'button', - }); - - // Edit the NFT, ensure same address, and move forward - await driver.clickElement( - '[data-testid="confirm-page-back-edit-button"]', - ); - - const recipient = await driver.findElement( - '.ens-input__selected-input__title', - ); - - assert.equal( - await recipient.getText(), - '0xc427D...Acd28\n0xc427D...Acd28', - ); - - await driver.clickElement({ - text: 'Continue', - tag: 'button', - }); - - // Confirm the send - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // When transaction complete, check the send NFT is displayed in activity tab - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const sendNftItem = await driver.findElement({ - css: '[data-testid="activity-list-item-action"]', - text: 'Send Test Dapp NFTs', - }); - assert.equal(await sendNftItem.isDisplayed(), true); - - // Go back to NFTs tab and check the imported NFT is shown as previously owned - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - const previouslyOwnedNft = await driver.findElement({ - css: 'h5', - text: 'Previously Owned', - }); - assert.equal(await previouslyOwnedNft.isDisplayed(), true); - }, - ); - }); - - it('should be able to send ERC1155 NFT', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC1155().build(), - ganacheOptions: defaultGanacheOptions, - smartContract: erc1155SmartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Fill the send NFT form and confirm the transaction - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - - await driver.clickElement('[data-testid="nft-network-badge"]'); - - await driver.clickElement({ text: 'Send', tag: 'button' }); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ - text: 'Continue', - tag: 'button', - }); - - // Confirm the send - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // When transaction complete, check the send NFT is displayed in activity tab - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const sendNftItem = await driver.findElement({ - css: '[data-testid="activity-list-item-action"]', - text: 'Safe transfer from', - }); - assert.equal(await sendNftItem.isDisplayed(), true); - - // Go back to NFTs tab and check the imported NFT is shown as previously owned - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - - const previouslyOwnedNft = await driver.findElement({ - css: 'h5', - text: 'Previously Owned', - }); - assert.equal(await previouslyOwnedNft.isDisplayed(), true); - }, - ); - }); - - it('should not be able to send ERC1155 NFT with invalid amount', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC1155().build(), - ganacheOptions: defaultGanacheOptions, - smartContract: erc1155SmartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Fill the send NFT form and confirm the transaction - await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); - - await driver.clickElement('[data-testid="nft-network-badge"]'); - - await driver.clickElement({ text: 'Send', tag: 'button' }); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - ); - - await driver.assertElementNotPresent( - '[data-testid="send-page-amount-error"]', - ); - await driver.fill('input[placeholder="0"]', '0'); - assert.ok( - await driver.findElement({ - text: '1 token. Cannot send negative or zero amounts of asset.', - tag: 'p', - }), - ); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.js b/test/e2e/tests/tokens/send-erc20-to-contract.spec.js deleted file mode 100644 index 6e94b6377e67..000000000000 --- a/test/e2e/tests/tokens/send-erc20-to-contract.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -const { strict: assert } = require('assert'); -const { - defaultGanacheOptions, - withFixtures, - unlockWallet, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Send ERC20 token to contract address', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('should display the token contract warning to the user', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withTokensControllerERC20().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - - // Type contract address - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - contractAddress, - ); - - // Verify warning - const warningText = - 'Warning: you are about to send to a token contract which could result in a loss of funds. Learn more'; - const warning = await driver.findElement( - '[data-testid="send-warning"] .mm-box--min-width-0 span', - ); - assert.equal(await warning.getText(), warningText); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts new file mode 100644 index 000000000000..5c7b59cbc215 --- /dev/null +++ b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts @@ -0,0 +1,52 @@ +import { + defaultGanacheOptions, + withFixtures, + unlockWallet, +} from '../../helpers'; +import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; +import FixtureBuilder from '../../fixture-builder'; + +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import HomePage from '../../page-objects/pages/home/homepage'; +import SendTokenPage from '../../page-objects/pages/send/send-token-page'; +import TokenOverviewPage from '../../page-objects/pages/token-overview-page'; + +describe('Send ERC20 token to contract address', function () { + const smartContract = SMART_CONTRACTS.HST; + + it('should display the token contract warning to the user', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().withTokensControllerERC20().build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test?.fullTitle(), + }, + async ({ driver, contractRegistry }) => { + const contractAddress: string = + await contractRegistry.getContractAddress(smartContract); + await unlockWallet(driver); + + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + await homePage.check_pageIsLoaded(); + await assetListPage.clickOnAsset('TST'); + + // Send TST + const tokenOverviewPage = new TokenOverviewPage(driver); + await tokenOverviewPage.check_pageIsLoaded(); + await tokenOverviewPage.clickSend(); + + const sendTokenPage = new SendTokenPage(driver); + await sendTokenPage.check_pageIsLoaded(); + await sendTokenPage.fillRecipient(contractAddress); + + // Verify warning + const warningText = + 'Warning: you are about to send to a token contract which could result in a loss of funds. Learn more'; + await sendTokenPage.check_warningMessage(warningText); + }, + ); + }); +}); diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index f7b032c92a4c..4002142d595e 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -1,4 +1,3 @@ -import { strict as assert } from 'assert'; import { Mockttp } from 'mockttp'; import { Context } from 'mocha'; import { zeroAddress } from 'ethereumjs-util'; @@ -6,15 +5,17 @@ import { CHAIN_IDS } from '../../../../shared/constants/network'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import FixtureBuilder from '../../fixture-builder'; import { - clickNestedButton, defaultGanacheOptions, unlockWallet, withFixtures, } from '../../helpers'; import { Driver } from '../../webdriver/driver'; +import HomePage from '../../page-objects/pages/home/homepage'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; describe('Token List', function () { const chainId = CHAIN_IDS.MAINNET; + const lineaChainId = CHAIN_IDS.LINEA_MAINNET; const tokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; const symbol = 'foo'; @@ -26,88 +27,118 @@ describe('Token List', function () { }, }; - const importToken = async (driver: Driver) => { - await driver.clickElement(`[data-testid="import-token-button"]`); - await driver.clickElement(`[data-testid="importTokens"]`); - await clickNestedButton(driver, 'Custom token'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-address"]', - tokenAddress, - ); - await driver.waitForSelector('p.mm-box--color-error-default'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-symbol"]', - symbol, - ); - await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - await driver.findElement({ text: 'Token imported', tag: 'h6' }); + const mockEmptyPrices = async ( + mockServer: Mockttp, + chainIdToMock: string, + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v2/chains/${parseInt( + chainIdToMock, + 16, + )}/spot-prices`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: {}, + })); + }; + + const mockEmptyHistoricalPrices = async ( + mockServer: Mockttp, + address: string, + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${address}`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: {}, + })); + }; + + const mockSpotPrices = async ( + mockServer: Mockttp, + chainIdToMock: string, + prices: Record< + string, + { price: number; pricePercentChange1d: number; marketCap: number } + >, + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v2/chains/${parseInt( + chainIdToMock, + 16, + )}/spot-prices`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: prices, + })); + }; + + const mockHistoricalPrices = async ( + mockServer: Mockttp, + address: string, + price: number, + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${toChecksumHexAddress( + address, + )}`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: { + prices: [ + [1717566000000, price * 0.9], + [1717566322300, price], + [1717566611338, price * 1.1], + ], + }, + })); }; - it('should not shows percentage increase for an ERC20 token without prices available', async function () { + it('should not show percentage increase for an ERC20 token without prices available', async function () { await withFixtures( { ...fixtures, title: (this as Context).test?.fullTitle(), testSpecificMock: async (mockServer: Mockttp) => [ - // Mock no current price - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v2/chains/${parseInt( - chainId, - 16, - )}/spot-prices`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: {}, - })), - // Mock no historical prices - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${tokenAddress}`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: {}, - })), + await mockEmptyPrices(mockServer, chainId), + await mockEmptyPrices(mockServer, lineaChainId), + await mockEmptyHistoricalPrices(mockServer, tokenAddress), ], }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - // Verify native token increase - const testIdNative = `token-increase-decrease-percentage-${zeroAddress()}`; + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); - // Verify native token increase - const testId = `token-increase-decrease-percentage-${tokenAddress}`; + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken(tokenAddress, symbol); - const percentageNative = await ( - await driver.findElement(`[data-testid="${testIdNative}"]`) - ).getText(); - assert.equal(percentageNative, ''); - - const percentage = await ( - await driver.findElement(`[data-testid="${testId}"]`) - ).getText(); - assert.equal(percentage, ''); + await assetListPage.check_tokenGeneralChangePercentageNotPresent( + zeroAddress(), + ); + await assetListPage.check_tokenGeneralChangePercentageNotPresent( + tokenAddress, + ); }, ); }); it('shows percentage increase for an ERC20 token with prices available', async function () { const ethConversionInUsd = 10000; - - // Prices are in ETH const marketData = { price: 0.123, marketCap: 12, pricePercentChange1d: 0.05, }; - const marketDataNative = { price: 0.123, marketCap: 12, @@ -120,91 +151,35 @@ describe('Token List', function () { title: (this as Context).test?.fullTitle(), ethConversionInUsd, testSpecificMock: async (mockServer: Mockttp) => [ - // Mock current price - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v2/chains/${parseInt( - chainId, - 16, - )}/spot-prices`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: { - [zeroAddress()]: marketDataNative, - [tokenAddress.toLowerCase()]: marketData, - }, - })), - // Mock historical prices - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${toChecksumHexAddress( - tokenAddress, - )}`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: { - prices: [ - [1717566000000, marketData.price * 0.9], - [1717566322300, marketData.price], - [1717566611338, marketData.price * 1.1], - ], - }, - })), + await mockSpotPrices(mockServer, chainId, { + [zeroAddress()]: marketDataNative, + [tokenAddress.toLowerCase()]: marketData, + }), + await mockHistoricalPrices( + mockServer, + tokenAddress, + marketData.price, + ), ], }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - // Verify native token increase - const testIdBase = 'token-increase-decrease-percentage'; + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); - const isETHIncreaseDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: `[data-testid="${testIdBase}-${zeroAddress()}"]`, - text: '+0.02%', - }); - assert.equal( - isETHIncreaseDOMPresentAndVisible, - true, - 'Invalid eth increase dom text content', - ); - - const isTokenIncreaseDecreasePercentageDOMPresent = - await driver.isElementPresentAndVisible({ - css: `[data-testid="${testIdBase}-${tokenAddress}"]`, - text: '+0.05%', - }); - assert.equal( - isTokenIncreaseDecreasePercentageDOMPresent, - true, - 'Invalid token increase dom text content', - ); + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken(tokenAddress, symbol); - // check increase balance for native token eth - const isExpectedIncreaseDecreaseValueDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: '[data-testid="token-increase-decrease-value"]', - text: '+$50.00', - }); - assert.equal( - isExpectedIncreaseDecreaseValueDOMPresentAndVisible, - true, - 'Invalid increase-decrease-value dom text content', + await assetListPage.check_tokenGeneralChangePercentage( + zeroAddress(), + '+0.02%', ); - - const isExpectedIncreaseDecreasePercentageDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: '[data-testid="token-increase-decrease-percentage"]', - text: '(+0.02%)', - }); - assert.equal( - isExpectedIncreaseDecreasePercentageDOMPresentAndVisible, - true, - 'Invalid increase-decrease-percentage dom text content', + await assetListPage.check_tokenGeneralChangePercentage( + tokenAddress, + '+0.05%', ); + await assetListPage.check_tokenGeneralChangeValue('+$50.00'); }, ); }); diff --git a/test/e2e/tests/tokens/token-sort.spec.ts b/test/e2e/tests/tokens/token-sort.spec.ts index ff2d35a917dc..ddf9c33cceb1 100644 --- a/test/e2e/tests/tokens/token-sort.spec.ts +++ b/test/e2e/tests/tokens/token-sort.spec.ts @@ -3,102 +3,66 @@ import { Context } from 'mocha'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import FixtureBuilder from '../../fixture-builder'; import { - clickNestedButton, defaultGanacheOptions, - regularDelayMs, unlockWallet, withFixtures, + largeDelayMs, } from '../../helpers'; import { Driver } from '../../webdriver/driver'; +import HomePage from '../../page-objects/pages/home/homepage'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; -describe('Token List', function () { - const chainId = CHAIN_IDS.MAINNET; - const tokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; - const symbol = 'ABC'; +describe('Token List Sorting', function () { + const mainnetChainId = CHAIN_IDS.MAINNET; + const customTokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; + const customTokenSymbol = 'ABC'; - const fixtures = { - fixtures: new FixtureBuilder({ inputChainId: chainId }).build(), + const testFixtures = { + fixtures: new FixtureBuilder({ inputChainId: mainnetChainId }).build(), ganacheOptions: { ...defaultGanacheOptions, - chainId: parseInt(chainId, 16), + chainId: parseInt(mainnetChainId, 16), }, }; - const importToken = async (driver: Driver) => { - await driver.clickElement(`[data-testid="import-token-button"]`); - await driver.clickElement(`[data-testid="importTokens"]`); - await clickNestedButton(driver, 'Custom token'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-address"]', - tokenAddress, - ); - await driver.waitForSelector('p.mm-box--color-error-default'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-symbol"]', - symbol, - ); - await driver.delay(2000); - await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - await driver.findElement({ text: 'Token imported', tag: 'h6' }); - }; - - it('should sort alphabetically and by decreasing balance', async function () { + it('should sort tokens alphabetically and by decreasing balance', async function () { await withFixtures( { - ...fixtures, + ...testFixtures, title: (this as Context).test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - - const tokenListBeforeSorting = await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - const tokenSymbolsBeforeSorting = await Promise.all( - tokenListBeforeSorting.map(async (tokenElement) => { - return tokenElement.getText(); - }), - ); - - assert.ok(tokenSymbolsBeforeSorting[0].includes('Ethereum')); - await driver.clickElement('[data-testid="sort-by-popover-toggle"]'); - await driver.clickElement('[data-testid="sortByAlphabetically"]'); + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); - await driver.delay(regularDelayMs); - const tokenListAfterSortingAlphabetically = await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - const tokenListSymbolsAfterSortingAlphabetically = await Promise.all( - tokenListAfterSortingAlphabetically.map(async (tokenElement) => { - return tokenElement.getText(); - }), + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken( + customTokenAddress, + customTokenSymbol, ); - assert.ok( - tokenListSymbolsAfterSortingAlphabetically[0].includes('ABC'), - ); + const initialTokenList = await assetListPage.getTokenListNames(); + assert.ok(initialTokenList[0].includes('Ethereum')); + await assetListPage.sortTokenList('alphabetically'); - await driver.clickElement('[data-testid="sort-by-popover-toggle"]'); - await driver.clickElement('[data-testid="sortByDecliningBalance"]'); - - await driver.delay(regularDelayMs); - const tokenListBeforeSortingByDecliningBalance = - await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - - const tokenListAfterSortingByDecliningBalance = await Promise.all( - tokenListBeforeSortingByDecliningBalance.map(async (tokenElement) => { - return tokenElement.getText(); - }), + await driver.waitUntil( + async () => { + const sortedTokenList = await assetListPage.getTokenListNames(); + return sortedTokenList[0].includes(customTokenSymbol); + }, + { timeout: largeDelayMs, interval: 100 }, ); - assert.ok( - tokenListAfterSortingByDecliningBalance[0].includes('Ethereum'), + + await assetListPage.sortTokenList('decliningBalance'); + await driver.waitUntil( + async () => { + const sortedTokenListByBalance = + await assetListPage.getTokenListNames(); + return sortedTokenListByBalance[0].includes('Ethereum'); + }, + { timeout: largeDelayMs, interval: 100 }, ); }, ); diff --git a/test/e2e/tests/transaction/change-assets.spec.js b/test/e2e/tests/transaction/change-assets.spec.js index 33944f7a2160..391d64e28369 100644 --- a/test/e2e/tests/transaction/change-assets.spec.js +++ b/test/e2e/tests/transaction/change-assets.spec.js @@ -3,728 +3,349 @@ const { defaultGanacheOptions, withFixtures, logInWithBalanceValidation, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); const { tEn } = require('../../../lib/i18n-helpers'); describe('Change assets', function () { - describe('Old confirmation screens', function () { - it('sends the correct asset when switching from native currency to NFT', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC721().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Wait for balance to load - await driver.delay(500); - - // Click the Send button - await driver.clickElement('[data-testid="eth-overview-send"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '2.000042', - }); - - // Click edit - await driver.clickElement( - '[data-testid="confirm-page-back-edit-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose an NFT instead - await driver.clickElement({ css: 'button', text: 'NFTs' }); - await driver.clickElement('[data-testid="nft-default-image"]'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Click continue - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector( - '.confirm-page-container-summary__title img', - ); - await driver.waitForSelector({ - css: 'h3', - text: 'Test Dapp NFTs #1', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ - css: 'p', - text: 'Send Test Dapp NFTs #1', - }); - }, - ); - }); - - it('sends the correct asset when switching from ERC20 to NFT', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - const tokenContract = SMART_CONTRACTS.HST; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withTokensControllerERC20() - .withNftControllerERC721() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract: [smartContract, tokenContract], - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Click the Send button - await driver.clickElement({ - css: '[data-testid="multichain-token-list-button"] p', - text: 'TST', - }); - - // Wait for balance to load - await driver.delay(500); - - await driver.clickElement('[data-testid="eth-overview-send"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '0'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.00008455', - }); - - // Click edit - await driver.clickElement( - '[data-testid="confirm-page-back-edit-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose an NFT instead - await driver.clickElement({ css: 'button', text: 'NFTs' }); - await driver.clickElement('[data-testid="nft-default-image"]'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Click continue - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector( - '.confirm-page-container-summary__title img', - ); - await driver.waitForSelector({ - css: 'h3', - text: 'Test Dapp NFTs #1', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ - css: 'p', - text: 'Send Test Dapp NFTs #1', - }); - }, - ); - }); - - it('sends the correct asset when switching from NFT to native currency', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC721().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Choose the nft - await driver.clickElement( - '[data-testid="account-overview__nfts-tab"]', - ); - await driver.clickElement('[data-testid="nft-default-image"]'); - await driver.clickElement('[data-testid="nft-send-button"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector( - '.confirm-page-container-summary__title img', - ); - await driver.waitForSelector({ - css: 'h3', - text: 'Test Dapp NFTs #1', - }); - - // Click edit - await driver.clickElement( - '[data-testid="confirm-page-back-edit-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose tokens - await driver.clickElement({ css: 'button', text: 'Tokens' }); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - - // Ensure correct token selected - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '2.000042', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ css: 'p', text: 'Send' }); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-2 ETH', - }); - }, - ); - }); - - it('changes to native currency when switching accounts during a NFT send', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNftControllerERC721() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Create second account - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-account"]', - ); - await driver.fill('[placeholder="Account 2"]', 'Account 2'); - await driver.clickElement({ text: tEn('addAccount'), tag: 'button' }); - - // Go back to Account 1 - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 1', - }); - - // Choose the nft - await driver.clickElement( - '[data-testid="account-overview__nfts-tab"]', - ); - await driver.clickElement('[data-testid="nft-default-image"]'); - await driver.clickElement('[data-testid="nft-send-button"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Switch to Account 2 - await driver.clickElement('[data-testid="send-page-account-picker"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 2', - }); - - // Ensure that the AssetPicker shows native currency and 0 value - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Go back to Account 1 - await driver.clickElement('[data-testid="send-page-account-picker"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 1', - }); - - // Ensure that the AssetPicker shows native currency and 0 value - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - - // Make sure hex data is cleared after switching assets - const hexDataLocator = await driver.findElement( - '[data-testid="send-hex-textarea"]', - ); - const hexDataValue = await hexDataLocator.getProperty('value'); - assert.equal( - hexDataValue, - '', - 'Hex data has not been cleared after switching assets.', - ); - - // Make sure gas is updated by resetting amount and hex data - // Note: this is needed until the race condition is fixed on the wallet level (issue #25243) - await driver.fill('[data-testid="currency-input"]', '2.000042'); - await hexDataLocator.fill('0x'); - await hexDataLocator.fill(''); - - // Go to the last confirmation screen - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '2.000042', - }); - }, - ); - }); + it('sends the correct asset when switching from native currency to NFT', async function () { + const smartContract = SMART_CONTRACTS.NFTS; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().withNftControllerERC721().build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Wait for balance to load + await driver.delay(500); + + // Click the Send button + await driver.clickElement('[data-testid="eth-overview-send"]'); + + // Chose a recipient + await driver.clickElement('.multichain-account-list-item'); + + // Populate an amount, continue + await driver.clickElement('[data-testid="currency-input"]'); + await driver.press('[data-testid="currency-input"]', '2'); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Click edit + await driver.clickElement( + '[data-testid="wallet-initiated-header-back-button"]', + ); + + // Open the Amount modal + await driver.clickElement('.asset-picker__symbol'); + + // Choose an NFT instead + await driver.clickElement({ css: 'button', text: 'NFTs' }); + await driver.clickElement('[data-testid="nft-default-image"]'); + + // Validate that an NFT is chosen in the AssetAmountPicker + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'TDN', + }); + await driver.waitForSelector({ css: 'p', text: '#1' }); + + // Click continue + await driver.assertElementNotPresent('.mm-modal-content'); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Ensure NFT is showing + await driver.waitForSelector('[data-testid="nft-default-image"]'); + await driver.waitForSelector({ + css: 'h2', + text: 'Test Dapp NFTs #1', + }); + + // Send it! + await driver.clickElement({ text: 'Confirm', css: 'button' }); + + // Ensure it was sent + await driver.waitForSelector({ + css: 'p', + text: 'Send Test Dapp NFTs #1', + }); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('sends the correct asset when switching from native currency to NFT', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC721().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Wait for balance to load - await driver.delay(500); - - // Click the Send button - await driver.clickElement('[data-testid="eth-overview-send"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Click edit - await driver.clickElement( - '[data-testid="wallet-initiated-header-back-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose an NFT instead - await driver.clickElement({ css: 'button', text: 'NFTs' }); - await driver.clickElement('[data-testid="nft-default-image"]'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Click continue - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector('[data-testid="nft-default-image"]'); - await driver.waitForSelector({ - css: 'h2', - text: 'Test Dapp NFTs #1', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ - css: 'p', - text: 'Send Test Dapp NFTs #1', - }); - }, - ); - }); - - it('sends the correct asset when switching from ERC20 to NFT', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - const tokenContract = SMART_CONTRACTS.HST; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withTokensControllerERC20() - .withNftControllerERC721() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract: [smartContract, tokenContract], - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Click the Send button - await driver.clickElement({ - css: '[data-testid="multichain-token-list-button"] p', - text: 'TST', - }); - - // Wait for balance to load - await driver.delay(500); - - await driver.clickElement('[data-testid="eth-overview-send"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '0'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Click edit - await driver.clickElement( - '[data-testid="wallet-initiated-header-back-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose an NFT instead - await driver.clickElement({ css: 'button', text: 'NFTs' }); - await driver.clickElement('[data-testid="nft-default-image"]'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Click continue - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector('[data-testid="nft-default-image"]'); - await driver.waitForSelector({ - css: 'h2', - text: 'Test Dapp NFTs #1', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ - css: 'p', - text: 'Send Test Dapp NFTs #1', - }); - }, - ); - }); - - it('sends the correct asset when switching from NFT to native currency', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withNftControllerERC721().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Choose the nft - await driver.clickElement( - '[data-testid="account-overview__nfts-tab"]', - ); - await driver.clickElement('[data-testid="nft-default-image"]'); - await driver.clickElement('[data-testid="nft-send-button"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Ensure NFT is showing - await driver.waitForSelector('[data-testid="nft-default-image"]'); - await driver.waitForSelector({ - css: 'h2', - text: 'Test Dapp NFTs #1', - }); - - // Click edit - await driver.clickElement( - '[data-testid="wallet-initiated-header-back-button"]', - ); - - // Open the Amount modal - await driver.clickElement('.asset-picker__symbol'); - - // Choose tokens - await driver.clickElement({ css: 'button', text: 'Tokens' }); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - - // Ensure correct token selected - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - await driver.assertElementNotPresent('.mm-modal-content'); - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: 'h2', - text: '2', - }); - - // Send it! - await driver.clickElement({ text: 'Confirm', css: 'button' }); - - // Ensure it was sent - await driver.waitForSelector({ css: 'p', text: 'Send' }); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-2 ETH', - }); - }, - ); - }); - - it('changes to native currency when switching accounts during a NFT send', async function () { - const smartContract = SMART_CONTRACTS.NFTS; - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withNftControllerERC721() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Create second account - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-action-button"]', - ); - await driver.clickElement( - '[data-testid="multichain-account-menu-popover-add-account"]', - ); - await driver.fill('[placeholder="Account 2"]', 'Account 2'); - await driver.clickElement({ text: tEn('addAccount'), tag: 'button' }); - - // Go back to Account 1 - await driver.clickElement('[data-testid="account-menu-icon"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 1', - }); - - // Choose the nft - await driver.clickElement( - '[data-testid="account-overview__nfts-tab"]', - ); - await driver.clickElement('[data-testid="nft-default-image"]'); - await driver.clickElement('[data-testid="nft-send-button"]'); - - // Chose a recipient - await driver.clickElement('.multichain-account-list-item'); - - // Validate that an NFT is chosen in the AssetAmountPicker - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'TDN', - }); - await driver.waitForSelector({ css: 'p', text: '#1' }); - - // Switch to Account 2 - await driver.clickElement('[data-testid="send-page-account-picker"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 2', - }); - - // Ensure that the AssetPicker shows native currency and 0 value - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Go back to Account 1 - await driver.clickElement('[data-testid="send-page-account-picker"]'); - await driver.clickElement({ - css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, - text: 'Account 1', - }); - - // Ensure that the AssetPicker shows native currency and 0 value - await driver.waitForSelector({ - css: '.asset-picker__symbol', - text: 'ETH', - }); - - // Populate an amount, continue - await driver.clickElement('[data-testid="currency-input"]'); - await driver.press('[data-testid="currency-input"]', '2'); - - // Make sure hex data is cleared after switching assets - const hexDataLocator = await driver.findElement( - '[data-testid="send-hex-textarea"]', - ); - const hexDataValue = await hexDataLocator.getProperty('value'); - assert.equal( - hexDataValue, - '', - 'Hex data has not been cleared after switching assets.', - ); - - // Make sure gas is updated by resetting amount and hex data - // Note: this is needed until the race condition is fixed on the wallet level (issue #25243) - await driver.fill('[data-testid="currency-input"]', '2.000042'); - await hexDataLocator.fill('0x'); - await hexDataLocator.fill(''); - - // Go to the last confirmation screen - await driver.clickElement({ text: 'Continue', css: 'button' }); - - // Validate the send amount - await driver.waitForSelector({ - css: 'h2', - text: '2 ETH', - }); - }, - ); - }); + it('sends the correct asset when switching from ERC20 to NFT', async function () { + const smartContract = SMART_CONTRACTS.NFTS; + const tokenContract = SMART_CONTRACTS.HST; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withTokensControllerERC20() + .withNftControllerERC721() + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract: [smartContract, tokenContract], + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Click the Send button + await driver.clickElement({ + css: '[data-testid="multichain-token-list-button"] p', + text: 'TST', + }); + + // Wait for balance to load + await driver.delay(500); + + await driver.clickElement('[data-testid="eth-overview-send"]'); + + // Chose a recipient + await driver.clickElement('.multichain-account-list-item'); + + // Populate an amount, continue + await driver.clickElement('[data-testid="currency-input"]'); + await driver.press('[data-testid="currency-input"]', '0'); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Click edit + await driver.clickElement( + '[data-testid="wallet-initiated-header-back-button"]', + ); + + // Open the Amount modal + await driver.clickElement('.asset-picker__symbol'); + + // Choose an NFT instead + await driver.clickElement({ css: 'button', text: 'NFTs' }); + await driver.clickElement('[data-testid="nft-default-image"]'); + + // Validate that an NFT is chosen in the AssetAmountPicker + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'TDN', + }); + await driver.waitForSelector({ css: 'p', text: '#1' }); + + // Click continue + await driver.assertElementNotPresent('.mm-modal-content'); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Ensure NFT is showing + await driver.waitForSelector('[data-testid="nft-default-image"]'); + await driver.waitForSelector({ + css: 'h2', + text: 'Test Dapp NFTs #1', + }); + + // Send it! + await driver.clickElement({ text: 'Confirm', css: 'button' }); + + // Ensure it was sent + await driver.waitForSelector({ + css: 'p', + text: 'Send Test Dapp NFTs #1', + }); + }, + ); + }); + + it('sends the correct asset when switching from NFT to native currency', async function () { + const smartContract = SMART_CONTRACTS.NFTS; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().withNftControllerERC721().build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Choose the nft + await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); + await driver.clickElement('[data-testid="nft-default-image"]'); + await driver.clickElement('[data-testid="nft-send-button"]'); + + // Chose a recipient + await driver.clickElement('.multichain-account-list-item'); + + // Validate that an NFT is chosen in the AssetAmountPicker + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'TDN', + }); + await driver.waitForSelector({ css: 'p', text: '#1' }); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Ensure NFT is showing + await driver.waitForSelector('[data-testid="nft-default-image"]'); + await driver.waitForSelector({ + css: 'h2', + text: 'Test Dapp NFTs #1', + }); + + // Click edit + await driver.clickElement( + '[data-testid="wallet-initiated-header-back-button"]', + ); + + // Open the Amount modal + await driver.clickElement('.asset-picker__symbol'); + + // Choose tokens + await driver.clickElement({ css: 'button', text: 'Tokens' }); + await driver.clickElement( + '[data-testid="multichain-token-list-button"]', + ); + + // Ensure correct token selected + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'ETH', + }); + + // Populate an amount, continue + await driver.clickElement('[data-testid="currency-input"]'); + await driver.press('[data-testid="currency-input"]', '2'); + await driver.assertElementNotPresent('.mm-modal-content'); + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Validate the send amount + await driver.waitForSelector({ + css: 'h2', + text: '2', + }); + + // Send it! + await driver.clickElement({ text: 'Confirm', css: 'button' }); + + // Ensure it was sent + await driver.waitForSelector({ css: 'p', text: 'Send' }); + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-2 ETH', + }); + }, + ); + }); + + it('changes to native currency when switching accounts during a NFT send', async function () { + const smartContract = SMART_CONTRACTS.NFTS; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNftControllerERC721() + .withPreferencesController({ + featureFlags: { + sendHexData: true, + }, + }) + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Create second account + await driver.clickElement('[data-testid="account-menu-icon"]'); + await driver.clickElement( + '[data-testid="multichain-account-menu-popover-action-button"]', + ); + await driver.clickElement( + '[data-testid="multichain-account-menu-popover-add-account"]', + ); + await driver.fill('[placeholder="Account 2"]', 'Account 2'); + await driver.clickElement({ text: tEn('addAccount'), tag: 'button' }); + + // Go back to Account 1 + await driver.clickElement('[data-testid="account-menu-icon"]'); + await driver.clickElement({ + css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, + text: 'Account 1', + }); + + // Choose the nft + await driver.clickElement('[data-testid="account-overview__nfts-tab"]'); + await driver.clickElement('[data-testid="nft-default-image"]'); + await driver.clickElement('[data-testid="nft-send-button"]'); + + // Chose a recipient + await driver.clickElement('.multichain-account-list-item'); + + // Validate that an NFT is chosen in the AssetAmountPicker + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'TDN', + }); + await driver.waitForSelector({ css: 'p', text: '#1' }); + + // Switch to Account 2 + await driver.clickElement('[data-testid="send-page-account-picker"]'); + await driver.clickElement({ + css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, + text: 'Account 2', + }); + + // Ensure that the AssetPicker shows native currency and 0 value + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'ETH', + }); + + // Go back to Account 1 + await driver.clickElement('[data-testid="send-page-account-picker"]'); + await driver.clickElement({ + css: `.multichain-account-list-item .multichain-account-list-item__account-name__button`, + text: 'Account 1', + }); + + // Ensure that the AssetPicker shows native currency and 0 value + await driver.waitForSelector({ + css: '.asset-picker__symbol', + text: 'ETH', + }); + + // Populate an amount, continue + await driver.clickElement('[data-testid="currency-input"]'); + await driver.press('[data-testid="currency-input"]', '2'); + + // Make sure hex data is cleared after switching assets + const hexDataLocator = await driver.findElement( + '[data-testid="send-hex-textarea"]', + ); + const hexDataValue = await hexDataLocator.getProperty('value'); + assert.equal( + hexDataValue, + '', + 'Hex data has not been cleared after switching assets.', + ); + + // Make sure gas is updated by resetting amount and hex data + // Note: this is needed until the race condition is fixed on the wallet level (issue #25243) + await driver.fill('[data-testid="currency-input"]', '2.000042'); + await hexDataLocator.fill('0x'); + await hexDataLocator.fill(''); + + // Go to the last confirmation screen + await driver.clickElement({ text: 'Continue', css: 'button' }); + + // Validate the send amount + await driver.waitForSelector({ + css: 'h2', + text: '2 ETH', + }); + }, + ); }); }); diff --git a/test/e2e/tests/transaction/edit-gas-fee.spec.js b/test/e2e/tests/transaction/edit-gas-fee.spec.js index 4e30fb8c0be1..76bc1a82fd37 100644 --- a/test/e2e/tests/transaction/edit-gas-fee.spec.js +++ b/test/e2e/tests/transaction/edit-gas-fee.spec.js @@ -9,461 +9,231 @@ const { unlockWallet, generateGanacheOptions, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Editing Confirm Transaction', function () { - describe('Old confirmation screens', function () { - it('allows selecting high, medium, low gas estimates on edit gas fee popover @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1', - }); - - // update estimates to high - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.waitForSelector({ - text: 'sec', - tag: 'span', - }); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-high"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Aggressive', - }); - - // update estimates to medium - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-medium"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Market', - }); - - // update estimates to low - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-low"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Slow', - }); - await driver.waitForSelector('[data-testid="low-gas-fee-alert"]'); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('allows accessing advance gas fee popover from edit gas fee popover', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1', - }); - - // update estimates to high - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.waitForSelector({ - text: 'sec', - tag: 'span', - }); - await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); - - // enter max fee - await driver.fill('[data-testid="base-fee-input"]', '8.5'); - - // enter priority fee - await driver.fill('[data-testid="priority-fee-input"]', '8.5'); - - // save default values - await driver.clickElement('input[type="checkbox"]'); - - // edit gas limit - await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); - await driver.fill('[data-testid="gas-limit-input"]', '100000'); - - // Submit gas fee changes - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.00085', - }); - await driver.waitForSelector({ - css: '.currency-display-component__suffix', - text: 'ETH', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('should use dapp suggested estimates for transaction coming from dapp @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - // login to extension - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createDappTransaction(driver, { - maxFeePerGas: '0x2000000000', - maxPriorityFeePerGas: '0x1000000000', - }); - - // check transaction in extension popup - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - text: 'Site suggested', - }); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - // -- should render the popover with no error - // this is to test in MV3 a racing issue when request for suggestedGasFees is not fetched properly - // some data would not be defined yet - await driver.waitForSelector('.edit-gas-fee-popover'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-dappSuggested"]', - ); - - const transactionAmounts = await driver.findElements( - '.currency-display-component__text', - ); - const transactionAmount = transactionAmounts[0]; - assert.equal(await transactionAmount.getText(), '0.001'); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.00185144', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // transaction should correct values in activity tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-0.001\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); + it('allows selecting high, medium, low gas estimates on edit gas fee popover @no-mmi', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createInternalTransaction(driver); + + await driver.findElement({ + css: 'h2', + text: '1 ETH', + }); + + // update estimates to high + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.waitForSelector({ + text: 'sec', + tag: 'span', + }); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-high"] > span:first-child', + ); + + await driver.waitForSelector({ + text: 'Aggressive', + }); + + // update estimates to medium + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-medium"] > span:first-child', + ); + + await driver.waitForSelector({ + text: 'Market', + }); + + // update estimates to low + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-low"] > span:first-child', + ); + + await driver.waitForSelector({ + text: 'Slow', + }); + await driver.waitForSelector('[data-testid="inline-alert"]'); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '[data-testid="transaction-list-item-primary-currency"]', + ); + assert.equal(txValues.length, 1); + assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('allows selecting high, medium, low gas estimates on edit gas fee popover @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: 'h2', - text: '1 ETH', - }); - - // update estimates to high - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.waitForSelector({ - text: 'sec', - tag: 'span', - }); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-high"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Aggressive', - }); - - // update estimates to medium - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-medium"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Market', - }); - - // update estimates to low - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-low"] > span:first-child', - ); - - await driver.waitForSelector({ - text: 'Slow', - }); - await driver.waitForSelector('[data-testid="inline-alert"]'); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('allows accessing advance gas fee popover from edit gas fee popover', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: 'h2', - text: '1 ETH', - }); - - // update estimates to high - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.waitForSelector({ - text: 'sec', - tag: 'span', - }); - await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); - - // enter max fee - await driver.fill('[data-testid="base-fee-input"]', '8.5'); - - // enter priority fee - await driver.fill('[data-testid="priority-fee-input"]', '8.5'); - - // save default values - await driver.clickElement('input[type="checkbox"]'); - - // edit gas limit - await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); - await driver.fill('[data-testid="gas-limit-input"]', '100000'); - - // Submit gas fee changes - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '[data-testid="first-gas-field"]', - text: '0.0008 ETH', - }); - - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$1.44', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('should use dapp suggested estimates for transaction coming from dapp @no-mmi', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - // login to extension - await unlockWallet(driver); - - await createDappTransaction(driver, { - maxFeePerGas: '0x2000000000', - maxPriorityFeePerGas: '0x1000000000', - }); - - // check transaction in extension popup - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await driver.waitForSelector({ - text: 'Site suggested', - }); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - // -- should render the popover with no error - // this is to test in MV3 a racing issue when request for suggestedGasFees is not fetched properly - // some data would not be defined yet - await driver.waitForSelector('.edit-gas-fee-popover'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-dappSuggested"]', - ); - - await driver.findElements({ - css: 'h2', - text: '0.001 ETH', - }); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '[data-testid="first-gas-field"]', - text: '0.0019', - }); - - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$3.15', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); + it('allows accessing advance gas fee popover from edit gas fee popover', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createInternalTransaction(driver); + + await driver.findElement({ + css: 'h2', + text: '1 ETH', + }); + + // update estimates to high + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.waitForSelector({ + text: 'sec', + tag: 'span', + }); + await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); + + // enter max fee + await driver.fill('[data-testid="base-fee-input"]', '8.5'); + + // enter priority fee + await driver.fill('[data-testid="priority-fee-input"]', '8.5'); + + // save default values + await driver.clickElement('input[type="checkbox"]'); + + // edit gas limit + await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); + await driver.fill('[data-testid="gas-limit-input"]', '100000'); + + // Submit gas fee changes + await driver.clickElement({ text: 'Save', tag: 'button' }); + + // has correct updated value on the confirm screen the transaction + await driver.waitForSelector({ + css: '[data-testid="first-gas-field"]', + text: '0.0008 ETH', + }); + + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$1.44', + }); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '[data-testid="transaction-list-item-primary-currency"]', + ); + assert.equal(txValues.length, 1); + assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); + }, + ); + }); - // transaction should correct values in activity tab - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-0.001\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); + it('should use dapp suggested estimates for transaction coming from dapp @no-mmi', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + dapp: true, + }, + async ({ driver }) => { + // login to extension + await unlockWallet(driver); + + await createDappTransaction(driver, { + maxFeePerGas: '0x2000000000', + maxPriorityFeePerGas: '0x1000000000', + }); + + // check transaction in extension popup + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await driver.waitForSelector({ + text: 'Site suggested', + }); + + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + // -- should render the popover with no error + // this is to test in MV3 a racing issue when request for suggestedGasFees is not fetched properly + // some data would not be defined yet + await driver.waitForSelector('.edit-gas-fee-popover'); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-dappSuggested"]', + ); + + await driver.findElements({ + css: 'h2', + text: '0.001 ETH', + }); + + // has correct updated value on the confirm screen the transaction + await driver.waitForSelector({ + css: '[data-testid="first-gas-field"]', + text: '0.0019', + }); + + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$3.15', + }); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // transaction should correct values in activity tab + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '[data-testid="transaction-list-item-primary-currency"]', + ); + assert.equal(txValues.length, 1); + assert.ok(/-0.001\s*ETH/u.test(await txValues[0].getText())); + }, + ); }); }); diff --git a/test/e2e/tests/transaction/gas-estimates.spec.js b/test/e2e/tests/transaction/gas-estimates.spec.js index 77027bc67901..e65ee39dcea6 100644 --- a/test/e2e/tests/transaction/gas-estimates.spec.js +++ b/test/e2e/tests/transaction/gas-estimates.spec.js @@ -3,7 +3,6 @@ const { logInWithBalanceValidation, openActionMenuAndStartSendFlow, generateGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); const { CHAIN_IDS } = require('../../../../shared/constants/network'); @@ -17,488 +16,250 @@ describe('Gas estimates generated by MetaMask', function () { hardfork: 'london', }); - describe('Old confirmation screens', function () { - describe('Send on a network that is EIP-1559 compatible', function () { - it('show expected gas defaults', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.00043983', - }); - }, - ); - }); - - it('show expected gas defaults when API is down', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - testSpecificMock: (mockServer) => { - mockServer - .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) - .thenCallback(() => { - return { - json: { - error: 'cannot get gas prices for chain id 1337', - }, - statusCode: 503, - }; - }); - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.00043983', - }); - }, - ); - }); - - it('show expected gas defaults when the network is not supported', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - testSpecificMock: (mockServer) => { - mockServer - .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) - .thenCallback(() => { - return { - statusCode: 422, - }; - }); - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.00043983', - }); - }, - ); - }); + describe('Send on a network that is EIP-1559 compatible', function () { + it('show expected gas defaults', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: postLondonGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.0004 ETH', + }); + + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.75', + }); + }, + ); }); - describe('Send on a network that is not EIP-1559 compatible', function () { - it('show expected gas defaults on a network supported by legacy gas API', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: { - ...preLondonGanacheOptions, - chainId: parseInt(CHAIN_IDS.BSC, 16), - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.000042', - }); - }, - ); - }); - - it('show expected gas defaults on a network supported by legacy gas API when that API is down', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: { - ...preLondonGanacheOptions, - chainId: parseInt(CHAIN_IDS.BSC, 16), - }, - testSpecificMock: (mockServer) => { - mockServer - .forGet( - `${GAS_API_BASE_URL}/networks/${parseInt( - CHAIN_IDS.BSC, - 16, - )}/gasPrices`, - ) - .thenCallback(() => { - return { - statusCode: 422, - }; - }); - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.000042', - }); + it('show expected gas defaults when API is down', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: postLondonGanacheOptions, + testSpecificMock: (mockServer) => { + mockServer + .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) + .thenCallback(() => { + return { + json: { + error: 'cannot get gas prices for chain id 1337', + }, + statusCode: 503, + }; + }); }, - ); - }); - - it('show expected gas defaults on a network not supported by legacy gas API', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: preLondonGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + }, + ); + }); - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="confirm-gas-display"]', - text: '0.000042', - }); + it('show expected gas defaults when the network is not supported', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: postLondonGanacheOptions, + testSpecificMock: (mockServer) => { + mockServer + .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) + .thenCallback(() => { + return { + statusCode: 422, + }; + }); }, - ); - }); + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + }, + ); }); }); - describe('Redesigned confirmation screens', function () { - describe('Send on a network that is EIP-1559 compatible', function () { - it('show expected gas defaults', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.0004 ETH', - }); - - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.75', - }); - }, - ); - }); - - it('show expected gas defaults when API is down', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - testSpecificMock: (mockServer) => { - mockServer - .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) - .thenCallback(() => { - return { - json: { - error: 'cannot get gas prices for chain id 1337', - }, - statusCode: 503, - }; - }); - }, - title: this.test.fullTitle(), + describe('Send on a network that is not EIP-1559 compatible', function () { + it('show expected gas defaults on a network supported by legacy gas API', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: { + ...preLondonGanacheOptions, + chainId: parseInt(CHAIN_IDS.BSC, 16), }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + }, + ); + }); - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); + it('show expected gas defaults on a network supported by legacy gas API when that API is down', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: { + ...preLondonGanacheOptions, + chainId: parseInt(CHAIN_IDS.BSC, 16), }, - ); - }); - - it('show expected gas defaults when the network is not supported', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: postLondonGanacheOptions, - testSpecificMock: (mockServer) => { - mockServer - .forGet(`${GAS_API_BASE_URL}/networks/1337/suggestedGasFees`) - .thenCallback(() => { - return { - statusCode: 422, - }; - }); - }, - title: this.test.fullTitle(), + testSpecificMock: (mockServer) => { + mockServer + .forGet( + `${GAS_API_BASE_URL}/networks/${parseInt( + CHAIN_IDS.BSC, + 16, + )}/gasPrices`, + ) + .thenCallback(() => { + return { + statusCode: 422, + }; + }); }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); - }, - ); - }); + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + }, + ); }); - describe('Send on a network that is not EIP-1559 compatible', function () { - it('show expected gas defaults on a network supported by legacy gas API', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: { - ...preLondonGanacheOptions, - chainId: parseInt(CHAIN_IDS.BSC, 16), - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); - }, - ); - }); - - it('show expected gas defaults on a network supported by legacy gas API when that API is down', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: { - ...preLondonGanacheOptions, - chainId: parseInt(CHAIN_IDS.BSC, 16), - }, - testSpecificMock: (mockServer) => { - mockServer - .forGet( - `${GAS_API_BASE_URL}/networks/${parseInt( - CHAIN_IDS.BSC, - 16, - )}/gasPrices`, - ) - .thenCallback(() => { - return { - statusCode: 422, - }; - }); - }, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); - }, - ); - }); - - it('show expected gas defaults on a network not supported by legacy gas API', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: preLondonGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('input[placeholder="0"]', '1'); - - await driver.clickElement({ css: 'button', text: 'Continue' }); - - // Check that the gas estimation is what we expect - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - await driver.waitForSelector({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); - }, - ); - }); + it('show expected gas defaults on a network not supported by legacy gas API', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: preLondonGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + + await driver.fill('input[placeholder="0"]', '1'); + + await driver.clickElement({ css: 'button', text: 'Continue' }); + + // Check that the gas estimation is what we expect + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + await driver.waitForSelector({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + }, + ); }); }); }); diff --git a/test/e2e/tests/transaction/multiple-transactions.spec.js b/test/e2e/tests/transaction/multiple-transactions.spec.js index b85937f5b6bd..16c921fab65f 100644 --- a/test/e2e/tests/transaction/multiple-transactions.spec.js +++ b/test/e2e/tests/transaction/multiple-transactions.spec.js @@ -6,257 +6,122 @@ const { unlockWallet, generateGanacheOptions, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Multiple transactions', function () { - describe('Old confirmation screens', function () { - it('creates multiple queued transactions, then confirms', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - // creates first transaction - await createDappTransaction(driver); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // creates second transaction - await createDappTransaction(driver); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // confirms second transaction - await driver.waitForSelector({ - text: 'Reject 2 transactions', - tag: 'a', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for the "Reject 2 transactions" to disappear - await driver.assertElementNotPresent( - '.page-container__footer-secondary a', - ); - - // confirms first transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.delay(regularDelayMs); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(2)', - ); - - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - - assert.equal(confirmedTxes.length, 2); - }, - ); - }); - - it('creates multiple queued transactions, then rejects', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - // creates first transaction - await createDappTransaction(driver); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // creates second transaction - await createDappTransaction(driver); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // rejects second transaction - await driver.waitForSelector({ - text: 'Reject 2 transactions', - tag: 'a', - }); - await driver.clickElement({ text: 'Reject', tag: 'button' }); - await driver.assertElementNotPresent('.loading-overlay__spinner'); - // rejects first transaction - await driver.clickElement({ text: 'Reject', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.delay(regularDelayMs); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - const isTransactionListEmpty = - await driver.isElementPresentAndVisible( - '.transaction-list__empty-text', - ); - assert.equal(isTransactionListEmpty, true); - - // The previous isTransactionListEmpty wait already serves as the guard here for the assertElementNotPresent - await driver.assertElementNotPresent( - '.transaction-list__completed-transactions .activity-list-item', - ); - }, - ); - }); + it('creates multiple queued transactions, then confirms', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // initiates a transaction from the dapp + await openDapp(driver); + // creates first transaction + await createDappTransaction(driver); + await driver.waitUntilXWindowHandles(3); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + + // creates second transaction + await createDappTransaction(driver); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // confirms second transaction + await driver.waitForSelector({ + text: 'Reject all', + tag: 'button', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // wait for the "Reject 2 transactions" to disappear + await driver.assertElementNotPresent( + '.page-container__footer-secondary a', + ); + + // confirms first transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.delay(regularDelayMs); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.waitForSelector( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(2)', + ); + + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + + assert.equal(confirmedTxes.length, 2); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('creates multiple queued transactions, then confirms', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - // creates first transaction - await createDappTransaction(driver); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // creates second transaction - await createDappTransaction(driver); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // confirms second transaction - await driver.waitForSelector({ - text: 'Reject all', - tag: 'button', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // wait for the "Reject 2 transactions" to disappear - await driver.assertElementNotPresent( - '.page-container__footer-secondary a', - ); - - // confirms first transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.delay(regularDelayMs); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(2)', - ); - - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - - assert.equal(confirmedTxes.length, 2); - }, - ); - }); - - it('creates multiple queued transactions, then rejects', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - // creates first transaction - await createDappTransaction(driver); - await driver.waitUntilXWindowHandles(3); - - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - - // creates second transaction - await createDappTransaction(driver); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - // rejects second transaction - await driver.waitForSelector({ - text: 'Reject all', - tag: 'button', - }); - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.assertElementNotPresent('.loading-overlay__spinner'); - // rejects first transaction - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await driver.delay(regularDelayMs); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - - const isTransactionListEmpty = - await driver.isElementPresentAndVisible( - '.transaction-list__empty-text', - ); - assert.equal(isTransactionListEmpty, true); - - // The previous isTransactionListEmpty wait already serves as the guard here for the assertElementNotPresent - await driver.assertElementNotPresent( - '.transaction-list__completed-transactions .activity-list-item', - ); - }, - ); - }); + it('creates multiple queued transactions, then rejects', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // initiates a transaction from the dapp + await openDapp(driver); + // creates first transaction + await createDappTransaction(driver); + await driver.waitUntilXWindowHandles(3); + + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + + // creates second transaction + await createDappTransaction(driver); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + // rejects second transaction + await driver.waitForSelector({ + text: 'Reject all', + tag: 'button', + }); + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + await driver.assertElementNotPresent('.loading-overlay__spinner'); + // rejects first transaction + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await driver.delay(regularDelayMs); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + + // The previous isTransactionListEmpty wait already serves as the guard here for the assertElementNotPresent + await driver.assertElementNotPresent( + '.transaction-list__completed-transactions .activity-list-item', + ); + }, + ); }); }); diff --git a/test/e2e/tests/transaction/navigate-transactions.spec.js b/test/e2e/tests/transaction/navigate-transactions.spec.js index eb8465fb47a7..0773756c66f0 100644 --- a/test/e2e/tests/transaction/navigate-transactions.spec.js +++ b/test/e2e/tests/transaction/navigate-transactions.spec.js @@ -4,9 +4,6 @@ const { const { createDappTransaction, } = require('../../page-objects/flows/transaction'); -const { - default: ConfirmationNavigation, -} = require('../../page-objects/pages/confirmations/legacy/navigation'); const { withFixtures, @@ -15,347 +12,163 @@ const { unlockWallet, generateGanacheOptions, WINDOW_TITLES, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); const TRANSACTION_COUNT = 4; describe('Navigate transactions', function () { - describe('Old confirmation screens', function () { - it('should navigate the unapproved transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createMultipleTransactions(driver, TRANSACTION_COUNT); - - const navigation = new ConfirmationNavigation(driver); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(2, 4); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(3, 4); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(4, 4); - - await navigation.clickFirstPage(); - await navigation.check_pageNumbers(1, 4); - - await navigation.clickLastPage(); - await navigation.check_pageNumbers(4, 4); - - await navigation.clickPreviousPage(); - await navigation.check_pageNumbers(3, 4); - - await navigation.clickPreviousPage(); - await navigation.check_pageNumbers(2, 4); - }, - ); - }); - - it('should add a transaction while the confirm page is in focus', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerTxSimulationsDisabled() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createMultipleTransactions(driver, TRANSACTION_COUNT); - - const navigation = new ConfirmationNavigation(driver); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(2, 4); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // add transaction - await openDapp(driver); - await driver.clickElement({ text: 'Send', tag: 'button' }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await navigation.check_pageNumbers(2, 5); - }, - ); - }); - - it('should reject and remove an unapproved transaction', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createMultipleTransactions(driver, TRANSACTION_COUNT); - - // reject transaction - await driver.clickElement({ text: 'Reject', tag: 'button' }); - - const navigation = new ConfirmationNavigation(driver); - await navigation.check_pageNumbers(1, 3); - }, - ); - }); - - it('should confirm and remove an unapproved transaction', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createMultipleTransactions(driver, TRANSACTION_COUNT); - - // confirm transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - const navigation = new ConfirmationNavigation(driver); - await navigation.check_pageNumbers(1, 3); - }, - ); - }); - - it('should reject and remove all unapproved transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver, ganacheServer }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createMultipleTransactions(driver, TRANSACTION_COUNT); - - // reject transactions - await driver.clickElement({ text: 'Reject 4', tag: 'a' }); - await driver.clickElement({ text: 'Reject all', tag: 'button' }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await locateAccountBalanceDOM(driver, ganacheServer); - }, - ); - }); + it('should navigate the unapproved transactions', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerTxSimulationsDisabled() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + dapp: true, + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); + + const navigation = new Confirmation(driver); + + await navigation.clickNextPage(); + await navigation.check_pageNumbers(2, 4); + + await navigation.clickNextPage(); + await navigation.check_pageNumbers(3, 4); + + await navigation.clickNextPage(); + await navigation.check_pageNumbers(4, 4); + + await navigation.clickPreviousPage(); + await navigation.check_pageNumbers(3, 4); + + await navigation.clickPreviousPage(); + await navigation.check_pageNumbers(2, 4); + + await navigation.clickPreviousPage(); + await navigation.check_pageNumbers(1, 4); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('should navigate the unapproved transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); - - const navigation = new Confirmation(driver); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(2, 4); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(3, 4); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(4, 4); - - await navigation.clickPreviousPage(); - await navigation.check_pageNumbers(3, 4); - - await navigation.clickPreviousPage(); - await navigation.check_pageNumbers(2, 4); - - await navigation.clickPreviousPage(); - await navigation.check_pageNumbers(1, 4); - }, - ); - }); - - it('should add a transaction while the confirm page is in focus', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .withPreferencesControllerTxSimulationsDisabled() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); - - const navigation = new Confirmation(driver); - - await navigation.clickNextPage(); - await navigation.check_pageNumbers(2, 4); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // add transaction - await openDapp(driver); - await driver.clickElement({ text: 'Send', tag: 'button' }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - - await navigation.check_pageNumbers(2, 5); - }, - ); - }); - - it('should reject and remove an unapproved transaction', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); - - // reject transaction - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - - const navigation = new Confirmation(driver); - await navigation.check_pageNumbers(1, 3); - }, - ); - }); - - it('should confirm and remove an unapproved transaction', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); - - // confirm transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - const navigation = new Confirmation(driver); - await navigation.check_pageNumbers(1, 3); - }, - ); - }); - - it('should reject and remove all unapproved transactions', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerTxSimulationsDisabled() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - dapp: true, - }, - async ({ driver, ganacheServer }) => { - await unlockWallet(driver); - - await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); - - // reject transactions - await driver.clickElement({ text: 'Reject all', tag: 'button' }); - - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - await locateAccountBalanceDOM(driver, ganacheServer); - }, - ); - }); + it('should add a transaction while the confirm page is in focus', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .withPreferencesControllerTxSimulationsDisabled() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); + + const navigation = new Confirmation(driver); + + await navigation.clickNextPage(); + await navigation.check_pageNumbers(2, 4); + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // add transaction + await openDapp(driver); + await driver.clickElement({ text: 'Send', tag: 'button' }); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + + await navigation.check_pageNumbers(2, 5); + }, + ); }); -}); -async function createMultipleTransactions(driver, count) { - for (let i = 0; i < count; i++) { - await createDappTransaction(driver); - } + it('should reject and remove an unapproved transaction', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerTxSimulationsDisabled() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + dapp: true, + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); + + // reject transaction + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + + const navigation = new Confirmation(driver); + await navigation.check_pageNumbers(1, 3); + }, + ); + }); - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + it('should confirm and remove an unapproved transaction', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerTxSimulationsDisabled() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + dapp: true, + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); + + // confirm transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + const navigation = new Confirmation(driver); + await navigation.check_pageNumbers(1, 3); + }, + ); + }); - // Wait until total amount is loaded to mitigate flakiness on reject - await driver.findElement({ - tag: 'span', - text: '0.001', + it('should reject and remove all unapproved transactions', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerTxSimulationsDisabled() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + dapp: true, + }, + async ({ driver, ganacheServer }) => { + await unlockWallet(driver); + + await createRedesignedMultipleTransactions(driver, TRANSACTION_COUNT); + + // reject transactions + await driver.clickElement({ text: 'Reject all', tag: 'button' }); + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + await locateAccountBalanceDOM(driver, ganacheServer); + }, + ); }); -} +}); async function createRedesignedMultipleTransactions(driver, count) { for (let i = 0; i < count; i++) { diff --git a/test/e2e/tests/transaction/send-edit.spec.js b/test/e2e/tests/transaction/send-edit.spec.js index 2180d65b3ec4..bdf044bde36e 100644 --- a/test/e2e/tests/transaction/send-edit.spec.js +++ b/test/e2e/tests/transaction/send-edit.spec.js @@ -8,362 +8,183 @@ const { withFixtures, unlockWallet, generateGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Editing Confirm Transaction', function () { - describe('Old confirmation screens', function () { - it('goes back from confirm page to edit eth value, gas price and gas limit', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().withConversionRateDisabled().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); - await createInternalTransaction(driver); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1', - }); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1.000042', - }); - - await driver.clickElement( - '.confirm-page-container-header__back-button', - ); - - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press('2'); - await inputAmount.press('.'); - await inputAmount.press('2'); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - await driver.clickElement({ text: 'Edit', tag: 'button' }); - - const [gasLimitInput, gasPriceInput] = await driver.findElements( - 'input[type="number"]', - ); - await gasPriceInput.fill('8'); - await gasLimitInput.fill('100000'); - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.0008', - }); - await driver.waitForSelector({ - css: '.currency-display-component__suffix', - text: 'ETH', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('goes back from confirm page to edit eth value, baseFee, priorityFee and gas limit - 1559 V2', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().withConversionRateDisabled().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1', - }); - - await driver.findElement({ - css: '.currency-display-component__text', - text: '1.00043983', - }); - - await driver.clickElement( - '.confirm-page-container-header__back-button', - ); - - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press('2'); - await inputAmount.press('.'); - await inputAmount.press('2'); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // open gas fee popover - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - - await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); - - // enter max fee - await driver.fill('[data-testid="base-fee-input"]', '8'); - - // enter priority fee - await driver.fill('[data-testid="priority-fee-input"]', '8'); - - // edit gas limit - await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); - await driver.fill('[data-testid="gas-limit-input"]', '100000'); - - // save default values - await driver.clickElement('input[type="checkbox"]'); - - // Submit gas fee changes - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.0008', - }); - await driver.waitForSelector({ - css: '.currency-display-component__suffix', - text: 'ETH', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); + it('goes back from confirm page to edit eth value, gas price and gas limit', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().withConversionRateDisabled().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createInternalTransaction(driver); + + await driver.findElement({ + css: 'h2', + text: '1 ETH', + }); + + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0 ETH', + }); + + await driver.findElement({ + css: '[data-testid="native-currency"]', + text: '$0.07', + }); + + await driver.clickElement( + '[data-testid="wallet-initiated-header-back-button"]', + ); + + const inputAmount = await driver.findElement('input[placeholder="0"]'); + + await inputAmount.press(driver.Key.BACK_SPACE); + await inputAmount.press('2'); + await inputAmount.press('.'); + await inputAmount.press('2'); + + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + + const [gasLimitInput, gasPriceInput] = await driver.findElements( + 'input[type="number"]', + ); + await gasPriceInput.fill('8'); + await gasLimitInput.fill('100000'); + await driver.clickElement({ text: 'Save', tag: 'button' }); + + // has correct updated value on the confirm screen the transaction + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.0008 ETH', + }); + + await driver.findElement({ + css: '[data-testid="native-currency"]', + text: '$1.36', + }); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '[data-testid="transaction-list-item-primary-currency"]', + ); + assert.equal(txValues.length, 1); + assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); + }, + ); }); - describe('Redesigned confirmation screens', function () { - it('goes back from confirm page to edit eth value, gas price and gas limit', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().withConversionRateDisabled().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: 'h2', - text: '1 ETH', - }); - - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$0.07', - }); - - await driver.clickElement( - '[data-testid="wallet-initiated-header-back-button"]', - ); - - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press('2'); - await inputAmount.press('.'); - await inputAmount.press('2'); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - - const [gasLimitInput, gasPriceInput] = await driver.findElements( - 'input[type="number"]', - ); - await gasPriceInput.fill('8'); - await gasLimitInput.fill('100000'); - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.0008 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$1.36', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); - - it('goes back from confirm page to edit eth value, baseFee, priorityFee and gas limit - 1559 V2', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().withConversionRateDisabled().build(), - ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - // await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await createInternalTransaction(driver); - - await driver.findElement({ - css: 'h2', - text: '1 ETH', - }); - - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.0004 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$0.75', - }); - - await driver.clickElement( - '[data-testid="wallet-initiated-header-back-button"]', - ); - - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press('2'); - await inputAmount.press('.'); - await inputAmount.press('2'); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // open gas fee popover - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - - await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); - - // enter max fee - await driver.fill('[data-testid="base-fee-input"]', '8'); - - // enter priority fee - await driver.fill('[data-testid="priority-fee-input"]', '8'); - - // edit gas limit - await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); - await driver.fill('[data-testid="gas-limit-input"]', '100000'); - - // save default values - await driver.clickElement('input[type="checkbox"]'); - - // Submit gas fee changes - await driver.clickElement({ text: 'Save', tag: 'button' }); - - // has correct updated value on the confirm screen the transaction - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.0008 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$1.36', - }); - - // confirms the transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '[data-testid="transaction-list-item-primary-currency"]', - ); - assert.equal(txValues.length, 1); - assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); - }, - ); - }); + it('goes back from confirm page to edit eth value, baseFee, priorityFee and gas limit - 1559 V2', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().withConversionRateDisabled().build(), + ganacheOptions: generateGanacheOptions({ hardfork: 'london' }), + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await createInternalTransaction(driver); + + await driver.findElement({ + css: 'h2', + text: '1 ETH', + }); + + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.0004 ETH', + }); + + await driver.findElement({ + css: '[data-testid="native-currency"]', + text: '$0.75', + }); + + await driver.clickElement( + '[data-testid="wallet-initiated-header-back-button"]', + ); + + const inputAmount = await driver.findElement('input[placeholder="0"]'); + + await inputAmount.press(driver.Key.BACK_SPACE); + await inputAmount.press('2'); + await inputAmount.press('.'); + await inputAmount.press('2'); + + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // open gas fee popover + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + + await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); + + // enter max fee + await driver.fill('[data-testid="base-fee-input"]', '8'); + + // enter priority fee + await driver.fill('[data-testid="priority-fee-input"]', '8'); + + // edit gas limit + await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); + await driver.fill('[data-testid="gas-limit-input"]', '100000'); + + // save default values + await driver.clickElement('input[type="checkbox"]'); + + // Submit gas fee changes + await driver.clickElement({ text: 'Save', tag: 'button' }); + + // has correct updated value on the confirm screen the transaction + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.0008 ETH', + }); + + await driver.findElement({ + css: '[data-testid="native-currency"]', + text: '$1.36', + }); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '[data-testid="transaction-list-item-primary-currency"]', + ); + assert.equal(txValues.length, 1); + assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); + }, + ); }); }); diff --git a/test/e2e/tests/transaction/send-eth.spec.js b/test/e2e/tests/transaction/send-eth.spec.js index badeb2d88540..7f5d1c198049 100644 --- a/test/e2e/tests/transaction/send-eth.spec.js +++ b/test/e2e/tests/transaction/send-eth.spec.js @@ -9,403 +9,241 @@ const { editGasFeeForm, WINDOW_TITLES, defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); describe('Send ETH', function () { - describe('Old confirmation screens', function () { - describe('from inside MetaMask', function () { - /* eslint-disable-next-line mocha/max-top-level-suites */ - it('finds the transaction in the transactions list using advanced gas modal', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); + describe('from inside MetaMask', function () { + it('finds the transaction in the transactions list using default gas', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + await openActionMenuAndStartSendFlow(driver); + + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); - await tempToggleSettingRedesignedTransactionConfirmations(driver); + const inputAmount = await driver.findElement( + 'input[placeholder="0"]', + ); - await driver.delay(1000); + await inputAmount.press('1'); + await inputAmount.press('0'); + await inputAmount.press('0'); + await inputAmount.press('0'); - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); + await driver.findElement({ + css: '[data-testid="send-page-amount-error"]', + text: '. Insufficient funds.', + }); - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - await inputAmount.press('1'); + await inputAmount.press(driver.Key.BACK_SPACE); + await inputAmount.press(driver.Key.BACK_SPACE); + await inputAmount.press(driver.Key.BACK_SPACE); - const inputValue = await inputAmount.getProperty('value'); - assert.equal(inputValue, '1'); + await driver.assertElementNotPresent('.send-v2__error-amount', { + waitAtLeastGuard: 100, // A waitAtLeastGuard of 100ms is the best choice here + }); - // Continue to next screen - await driver.clickElement({ text: 'Continue', tag: 'button' }); + const amountMax = await driver.findClickableElement( + '[data-testid="max-clear-button"]', + ); + await amountMax.click(); - await driver.delay(1000); - const transactionAmounts = await driver.findElements( - '.currency-display-component__text', - ); - const transactionAmount = transactionAmounts[0]; - assert.equal(await transactionAmount.getText(), '1'); + let inputValue = await inputAmount.getProperty('value'); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); + assert(Number(inputValue) > 24); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); + await amountMax.click(); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1 ETH', - }); - }, - ); - }); + assert.equal(await inputAmount.isEnabled(), true); - describe('from dapp using advanced gas controls', function () { - it('should display the correct gas price on the legacy transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // initiates a send from the dapp - await openDapp(driver); - await driver.clickElement({ text: 'Send', tag: 'button' }); - const windowHandles = await driver.waitUntilXWindowHandles(3); - const extension = windowHandles[0]; - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.assertElementNotPresent( - { text: 'Data', tag: 'li' }, - { findElementGuard: { text: 'Estimated gas fee', tag: 'h6' } }, // make sure the Dialog has loaded - ); - - await driver.clickElement({ text: 'Edit', tag: 'button' }); - await driver.waitForSelector({ - text: '0.00021 ETH', - }); - await driver.clickElement({ - text: 'Edit suggested gas fee', - tag: 'button', - }); - await driver.waitForSelector({ - text: 'Edit priority', - tag: 'header', - }); - await editGasFeeForm(driver, '21000', '100'); - await driver.waitForSelector({ - css: '.transaction-detail-item:nth-of-type(1) h6:nth-of-type(2)', - text: '0.0021 ETH', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - - // finds the transaction in the transactions list - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-0 ETH', - }); - - // the transaction has the expected gas price - await driver.clickElement( - '[data-testid="transaction-list-item-primary-currency"]', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-breakdown__gas-price"]', - text: '100', - }); - }, - ); - }); - - it('should display correct gas values for EIP-1559 transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - hardfork: 'london', - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - await driver.clickElement({ - text: 'Create Token', - tag: 'button', - }); - const windowHandles = await driver.waitUntilXWindowHandles(3); - - const extension = windowHandles[0]; - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.assertElementNotPresent( - { text: 'Data', tag: 'li' }, - { findElementGuard: { text: 'Estimated fee' } }, // make sure the Dialog has loaded - ); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-custom"]', - ); - - const baseFeeInput = await driver.findElement( - '[data-testid="base-fee-input"]', - ); - await baseFeeInput.fill('25'); - const priorityFeeInput = await driver.findElement( - '[data-testid="priority-fee-input"]', - ); - await priorityFeeInput.fill('1'); - - await driver.clickElement({ text: 'Save', tag: 'button' }); - - await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '0.0550741', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - - // Identify the transaction in the transactions list - await driver.waitForSelector( - '[data-testid="eth-overview__primary-currency"]', - ); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-0 ETH', - }); - - // the transaction has the expected gas value - await driver.clickElement( - '[data-testid="transaction-list-item-primary-currency"]', - ); - - await driver.waitForSelector({ - xpath: "//div[contains(text(), 'Base fee')]", - }); - - const allFeeValues = await driver.findElements( - '.currency-display-component__text', - ); - - /** - * Below lines check that fee values are numeric. - * Because these values change for every e2e run, - * It's better to just check that the values are there and are numeric - */ - assert.equal(allFeeValues.length > 0, true); - - allFeeValues.forEach(async (feeValue) => { - assert.equal(/\d+\.?\d*/u.test(await feeValue.getText()), true); - }); - }, - ); - }); - }); + await inputAmount.fill('1'); - describe('to non-contract address with data that matches ERC20 transfer data signature', function () { - it('renders the correct recipient on the confirmation screen', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .withPreferencesControllerPetnamesDisabled() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await driver.assertElementNotPresent('.loading-overlay__spinner'); - const balance = await driver.findElement( - '[data-testid="eth-overview__primary-currency"]', - ); - assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - ); - - await driver.fill( - 'textarea[placeholder="Optional', - '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', - ); - - await driver.findClickableElement({ - text: 'Continue', - tag: 'button', - }); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - await driver.findClickableElement( - '[data-testid="sender-to-recipient__name"]', - ); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - const recipientAddress = await driver.findElements({ - text: '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - }); - - assert.equal(recipientAddress.length, 1); - }, - ); - }); - }); - }); - }); + inputValue = await inputAmount.getProperty('value'); + assert.equal(inputValue, '1'); - describe('Redesigned confirmation screens', function () { - describe('from inside MetaMask', function () { - it('finds the transaction in the transactions list using default gas', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); + // Continue to next screen + await driver.clickElement({ text: 'Continue', tag: 'button' }); - await openActionMenuAndStartSendFlow(driver); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); + return confirmedTxes.length === 1; + }, 10000); + + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-1 ETH', + }); + }, + ); + }); - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); + /* eslint-disable-next-line mocha/max-top-level-suites */ + it('finds the transaction in the transactions list using advanced gas modal', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await driver.delay(1000); + + await openActionMenuAndStartSendFlow(driver); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); - await inputAmount.press('1'); - await inputAmount.press('0'); - await inputAmount.press('0'); - await inputAmount.press('0'); + const inputAmount = await driver.findElement( + 'input[placeholder="0"]', + ); + await inputAmount.press('1'); - await driver.findElement({ - css: '[data-testid="send-page-amount-error"]', - text: '. Insufficient funds.', - }); + const inputValue = await inputAmount.getProperty('value'); + assert.equal(inputValue, '1'); - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press(driver.Key.BACK_SPACE); - await inputAmount.press(driver.Key.BACK_SPACE); + // Continue to next screen + await driver.clickElement({ text: 'Continue', tag: 'button' }); - await driver.assertElementNotPresent('.send-v2__error-amount', { - waitAtLeastGuard: 100, // A waitAtLeastGuard of 100ms is the best choice here - }); + await driver.delay(1000); + + // Transaction Amount + await driver.findElement({ + css: 'h2', + text: '1 ETH', + }); - const amountMax = await driver.findClickableElement( - '[data-testid="max-clear-button"]', + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', ); - await amountMax.click(); + return confirmedTxes.length === 1; + }, 10000); + + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-1 ETH', + }); + }, + ); + }); - let inputValue = await inputAmount.getProperty('value'); + it('finds the transaction in the transactions list when sending to a Multisig Address', async function () { + const smartContract = SMART_CONTRACTS.MULTISIG; + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: { + ...defaultGanacheOptions, + hardfork: 'london', + }, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); - assert(Number(inputValue) > 24); + // Wait for balance to load + await driver.delay(500); - await amountMax.click(); + await driver.clickElement('[data-testid="eth-overview-send"]'); + await driver.clickElement({ text: 'Account 1', tag: 'button' }); - assert.equal(await inputAmount.isEnabled(), true); + const inputAmount = await driver.findElement( + 'input[placeholder="0"]', + ); + await inputAmount.sendKeys('1'); - await inputAmount.fill('1'); + // Continue to next screen + await driver.clickElement({ text: 'Continue', tag: 'button' }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); - inputValue = await inputAmount.getProperty('value'); - assert.equal(inputValue, '1'); + // Go back to home screen to check txn + const balance = await driver.findElement( + '[data-testid="eth-overview__primary-currency"]', + ); - // Continue to next screen - await driver.clickElement({ text: 'Continue', tag: 'button' }); + assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); + await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item', + ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1 ETH', - }); - }, - ); - }); + // The previous findElement already serves as the guard here for the assertElementNotPresent + await driver.assertElementNotPresent( + '.transaction-status-label--failed', + ); + }, + ); + }); + + it('shows no error when cancel transaction when sending via QR code', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + await driver.assertElementNotPresent('.loading-overlay__spinner'); + const balance = await driver.findElement( + '[data-testid="eth-overview__primary-currency"]', + ); + assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); + + await openActionMenuAndStartSendFlow(driver); + // choose to scan via QR code + await driver.clickElement('[data-testid="ens-qr-scan-button"]'); + await driver.findVisibleElement('[data-testid="qr-scanner-modal"]'); + // cancel action will close the dialog and shut down camera initialization + await driver.waitForSelector({ + css: '.qr-scanner__error', + text: "We couldn't access your camera. Please give it another try.", + }); + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + await driver.assertElementNotPresent( + '[data-testid="qr-scanner-modal"]', + ); + }, + ); + }); - /* eslint-disable-next-line mocha/max-top-level-suites */ - it('finds the transaction in the transactions list using advanced gas modal', async function () { + describe('from dapp using advanced gas controls', function () { + it('should display the correct gas price on the legacy transaction', async function () { await withFixtures( { - fixtures: new FixtureBuilder().build(), + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), ganacheOptions: defaultGanacheOptions, defaultGanacheOptions, title: this.test.fullTitle(), @@ -413,107 +251,183 @@ describe('Send ETH', function () { async ({ driver }) => { await unlockWallet(driver); - await driver.delay(1000); - - await openActionMenuAndStartSendFlow(driver); - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + // initiates a send from the dapp + await openDapp(driver); + await driver.clickElement({ text: 'Send', tag: 'button' }); + const windowHandles = await driver.waitUntilXWindowHandles(3); + const extension = windowHandles[0]; + await driver.switchToWindowWithTitle( + WINDOW_TITLES.Dialog, + windowHandles, ); - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', - ); - await inputAmount.press('1'); - - const inputValue = await inputAmount.getProperty('value'); - assert.equal(inputValue, '1'); - - // Continue to next screen - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - await driver.delay(1000); + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.waitForSelector({ + text: '0.00021 ETH', + }); + await driver.clickElement({ + text: 'Edit suggested gas fee', + tag: 'button', + }); + await driver.waitForSelector({ + text: 'Edit priority', + tag: 'header', + }); + await editGasFeeForm(driver, '21000', '100'); + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.0021 ETH', + }); - // Transaction Amount await driver.findElement({ - css: 'h2', - text: '1 ETH', + css: '[data-testid="native-currency"]', + text: '$3.57', }); await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(extension); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .activity-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - + // finds the transaction in the transactions list + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.waitForSelector( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); await driver.waitForSelector({ css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-1 ETH', + text: '-0 ETH', + }); + + // the transaction has the expected gas price + await driver.clickElement( + '[data-testid="transaction-list-item-primary-currency"]', + ); + await driver.waitForSelector({ + css: '[data-testid="transaction-breakdown__gas-price"]', + text: '100', }); }, ); }); - it('finds the transaction in the transactions list when sending to a Multisig Address', async function () { - const smartContract = SMART_CONTRACTS.MULTISIG; + it('should display correct gas values for EIP-1559 transaction', async function () { await withFixtures( { - fixtures: new FixtureBuilder().build(), + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), ganacheOptions: { ...defaultGanacheOptions, hardfork: 'london', }, - smartContract, title: this.test.fullTitle(), }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); + async ({ driver }) => { + await unlockWallet(driver); - // Wait for balance to load - await driver.delay(500); + // initiates a transaction from the dapp + await openDapp(driver); + await driver.clickElement({ + text: 'Create Token', + tag: 'button', + }); + const windowHandles = await driver.waitUntilXWindowHandles(3); - await driver.clickElement('[data-testid="eth-overview-send"]'); - await driver.clickElement({ text: 'Account 1', tag: 'button' }); + const extension = windowHandles[0]; + await driver.switchToWindowWithTitle( + WINDOW_TITLES.Dialog, + windowHandles, + ); - const inputAmount = await driver.findElement( - 'input[placeholder="0"]', + await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-custom"]', ); - await inputAmount.sendKeys('1'); - // Continue to next screen - await driver.clickElement({ text: 'Continue', tag: 'button' }); + const baseFeeInput = await driver.findElement( + '[data-testid="base-fee-input"]', + ); + await baseFeeInput.fill('25'); + const priorityFeeInput = await driver.findElement( + '[data-testid="priority-fee-input"]', + ); + await priorityFeeInput.fill('1'); + + await driver.clickElement({ text: 'Save', tag: 'button' }); + + await driver.findElement({ + css: '[data-testid="first-gas-field"]', + text: '0.045 ETH', + }); + + await driver.findElement({ + css: '[data-testid="native-currency"]', + text: '$76.57', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(extension); - // Go back to home screen to check txn - const balance = await driver.findElement( + // Identify the transaction in the transactions list + await driver.waitForSelector( '[data-testid="eth-overview__primary-currency"]', ); - assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); - await driver.clickElement( '[data-testid="account-overview__activity-tab"]', ); + await driver.waitForSelector( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + await driver.waitForSelector({ + css: '[data-testid="transaction-list-item-primary-currency"]', + text: '-0 ETH', + }); - await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item', + // the transaction has the expected gas value + await driver.clickElement( + '[data-testid="transaction-list-item-primary-currency"]', ); - // The previous findElement already serves as the guard here for the assertElementNotPresent - await driver.assertElementNotPresent( - '.transaction-status-label--failed', + await driver.waitForSelector({ + xpath: "//div[contains(text(), 'Base fee')]", + }); + + const allFeeValues = await driver.findElements( + '.currency-display-component__text', ); + + /** + * Below lines check that fee values are numeric. + * Because these values change for every e2e run, + * It's better to just check that the values are there and are numeric + */ + assert.equal(allFeeValues.length > 0, true); + + allFeeValues.forEach(async (feeValue) => { + assert.equal(/\d+\.?\d*/u.test(await feeValue.getText()), true); + }); }, ); }); + }); - it('shows no error when cancel transaction when sending via QR code', async function () { + describe('to non-contract address with data that matches ERC20 transfer data signature', function () { + it('renders the correct recipient on the confirmation screen', async function () { await withFixtures( { - fixtures: new FixtureBuilder().build(), + fixtures: new FixtureBuilder() + .withPreferencesController({ + featureFlags: { + sendHexData: true, + }, + }) + .withPreferencesControllerPetnamesDisabled() + .build(), ganacheOptions: defaultGanacheOptions, title: this.test.fullTitle(), }, @@ -527,254 +441,32 @@ describe('Send ETH', function () { assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); await openActionMenuAndStartSendFlow(driver); - // choose to scan via QR code - await driver.clickElement('[data-testid="ens-qr-scan-button"]'); - await driver.findVisibleElement('[data-testid="qr-scanner-modal"]'); - // cancel action will close the dialog and shut down camera initialization - await driver.waitForSelector({ - css: '.qr-scanner__error', - text: "We couldn't access your camera. Please give it another try.", - }); - await driver.clickElement({ text: 'Cancel', tag: 'button' }); - await driver.assertElementNotPresent( - '[data-testid="qr-scanner-modal"]', - ); - }, - ); - }); - - describe('from dapp using advanced gas controls', function () { - it('should display the correct gas price on the legacy transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // initiates a send from the dapp - await openDapp(driver); - await driver.clickElement({ text: 'Send', tag: 'button' }); - const windowHandles = await driver.waitUntilXWindowHandles(3); - const extension = windowHandles[0]; - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.waitForSelector({ - text: '0.00021 ETH', - }); - await driver.clickElement({ - text: 'Edit suggested gas fee', - tag: 'button', - }); - await driver.waitForSelector({ - text: 'Edit priority', - tag: 'header', - }); - await editGasFeeForm(driver, '21000', '100'); - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.0021 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$3.57', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - - // finds the transaction in the transactions list - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-0 ETH', - }); - - // the transaction has the expected gas price - await driver.clickElement( - '[data-testid="transaction-list-item-primary-currency"]', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-breakdown__gas-price"]', - text: '100', - }); - }, - ); - }); - - it('should display correct gas values for EIP-1559 transaction', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: { - ...defaultGanacheOptions, - hardfork: 'london', - }, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - // initiates a transaction from the dapp - await openDapp(driver); - await driver.clickElement({ - text: 'Create Token', - tag: 'button', - }); - const windowHandles = await driver.waitUntilXWindowHandles(3); - - const extension = windowHandles[0]; - await driver.switchToWindowWithTitle( - WINDOW_TITLES.Dialog, - windowHandles, - ); - - await driver.clickElement('[data-testid="edit-gas-fee-icon"]'); - await driver.clickElement( - '[data-testid="edit-gas-fee-item-custom"]', - ); - - const baseFeeInput = await driver.findElement( - '[data-testid="base-fee-input"]', - ); - await baseFeeInput.fill('25'); - const priorityFeeInput = await driver.findElement( - '[data-testid="priority-fee-input"]', - ); - await priorityFeeInput.fill('1'); - - await driver.clickElement({ text: 'Save', tag: 'button' }); - - await driver.findElement({ - css: '[data-testid="first-gas-field"]', - text: '0.045 ETH', - }); - - await driver.findElement({ - css: '[data-testid="native-currency"]', - text: '$76.57', - }); - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.waitUntilXWindowHandles(2); - await driver.switchToWindow(extension); - - // Identify the transaction in the transactions list - await driver.waitForSelector( - '[data-testid="eth-overview__primary-currency"]', - ); - - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.waitForSelector( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await driver.waitForSelector({ - css: '[data-testid="transaction-list-item-primary-currency"]', - text: '-0 ETH', - }); - - // the transaction has the expected gas value - await driver.clickElement( - '[data-testid="transaction-list-item-primary-currency"]', - ); - - await driver.waitForSelector({ - xpath: "//div[contains(text(), 'Base fee')]", - }); - - const allFeeValues = await driver.findElements( - '.currency-display-component__text', - ); - - /** - * Below lines check that fee values are numeric. - * Because these values change for every e2e run, - * It's better to just check that the values are there and are numeric - */ - assert.equal(allFeeValues.length > 0, true); - - allFeeValues.forEach(async (feeValue) => { - assert.equal(/\d+\.?\d*/u.test(await feeValue.getText()), true); - }); - }, - ); - }); - }); - describe('to non-contract address with data that matches ERC20 transfer data signature', function () { - it('renders the correct recipient on the confirmation screen', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesController({ - featureFlags: { - sendHexData: true, - }, - }) - .withPreferencesControllerPetnamesDisabled() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await driver.assertElementNotPresent('.loading-overlay__spinner'); - const balance = await driver.findElement( - '[data-testid="eth-overview__primary-currency"]', - ); - assert.ok(/^[\d.]+\sETH$/u.test(await balance.getText())); - - await openActionMenuAndStartSendFlow(driver); - - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - ); + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + '0xc427D562164062a23a5cFf596A4a3208e72Acd28', + ); - await driver.fill( - 'textarea[placeholder="Optional', - '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', - ); + await driver.fill( + 'textarea[placeholder="Optional', + '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a', + ); - await driver.findClickableElement({ - text: 'Continue', - tag: 'button', - }); - await driver.clickElement({ text: 'Continue', tag: 'button' }); + await driver.findClickableElement({ + text: 'Continue', + tag: 'button', + }); + await driver.clickElement({ text: 'Continue', tag: 'button' }); - await driver.clickElement('[data-testid="recipient-address"]'); + await driver.clickElement('[data-testid="recipient-address"]'); - const recipientAddress = await driver.findElements({ - text: '0xc427D562164062a23a5cFf596A4a3208e72Acd28', - }); + const recipientAddress = await driver.findElements({ + text: '0xc427D562164062a23a5cFf596A4a3208e72Acd28', + }); - assert.equal(recipientAddress.length, 1); - }, - ); - }); + assert.equal(recipientAddress.length, 1); + }, + ); }); }); }); diff --git a/test/e2e/tests/transaction/send-hex-address.spec.js b/test/e2e/tests/transaction/send-hex-address.spec.js index 64522c706f6b..f67f840c1688 100644 --- a/test/e2e/tests/transaction/send-hex-address.spec.js +++ b/test/e2e/tests/transaction/send-hex-address.spec.js @@ -3,7 +3,6 @@ const { withFixtures, logInWithBalanceValidation, openActionMenuAndStartSendFlow, - tempToggleSettingRedesignedTransactionConfirmations, } = require('../../helpers'); const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); const FixtureBuilder = require('../../fixture-builder'); @@ -11,377 +10,226 @@ const FixtureBuilder = require('../../fixture-builder'); const hexPrefixedAddress = '0x2f318C334780961FB129D2a6c30D0763d9a5C970'; const nonHexPrefixedAddress = hexPrefixedAddress.substring(2); -describe('Old confirmation screens', function () { - describe('Send ERC20 to a 40 character hexadecimal address', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('should ensure the address is prefixed with 0x when pasted and should send TST to a valid hexadecimal address', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - // Paste address without hex prefix - await driver.pasteIntoField( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.findElement({ - css: '.confirm-page-container-summary__title', - text: '0', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - const sendTransactionListItem = await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await sendTransactionListItem.click(); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); - - it('should ensure the address is prefixed with 0x when typed and should send TST to a valid hexadecimal address', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - - // Type address without hex prefix - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.findElement({ - css: '.confirm-page-container-summary__title', - text: '0', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - const sendTransactionListItem = await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await sendTransactionListItem.click(); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); +describe('Send ETH to a 40 character hexadecimal address', function () { + it('should ensure the address is prefixed with 0x when pasted and should send ETH to a valid hexadecimal address', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerPetnamesDisabled() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Send ETH + await openActionMenuAndStartSendFlow(driver); + // Paste address without hex prefix + await driver.pasteIntoField( + 'input[placeholder="Enter public address (0x) or domain name"]', + nonHexPrefixedAddress, + ); + await driver.findElement({ + css: '.ens-input__selected-input__title', + text: '0x2f318...5C970', + }); + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // Confirm transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + const sendTransactionListItem = await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item', + ); + await sendTransactionListItem.click(); + await driver.clickElement({ text: 'Activity log', tag: 'summary' }); + await driver.clickElement('[data-testid="sender-to-recipient__name"]'); + + // Verify address in activity log + await driver.findElement({ + css: '.nickname-popover__public-address', + text: hexPrefixedAddress, + }); + }, + ); + }); - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); + it('should ensure the address is prefixed with 0x when typed and should send ETH to a valid hexadecimal address', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder() + .withPreferencesControllerPetnamesDisabled() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Send ETH + await openActionMenuAndStartSendFlow(driver); + // Type address without hex prefix + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + nonHexPrefixedAddress, + ); + await driver.findElement({ + css: '.ens-input__selected-input__title', + text: '0x2f318...5C970', + }); + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // Confirm transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.clickElement( + '.transaction-list__completed-transactions .activity-list-item', + ); + await driver.clickElement({ text: 'Activity log', tag: 'summary' }); + await driver.clickElement('[data-testid="sender-to-recipient__name"]'); + + // Verify address in activity log + await driver.findElement({ + css: '.nickname-popover__public-address', + text: hexPrefixedAddress, + }); + }, + ); }); }); -describe('Redesigned confirmation screens', function () { - describe('Send ETH to a 40 character hexadecimal address', function () { - it('should ensure the address is prefixed with 0x when pasted and should send ETH to a valid hexadecimal address', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Send ETH - await openActionMenuAndStartSendFlow(driver); - // Paste address without hex prefix - await driver.pasteIntoField( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - const sendTransactionListItem = await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item', - ); - await sendTransactionListItem.click(); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); - - it('should ensure the address is prefixed with 0x when typed and should send ETH to a valid hexadecimal address', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Send ETH - await openActionMenuAndStartSendFlow(driver); - // Type address without hex prefix - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.clickElement( - '.transaction-list__completed-transactions .activity-list-item', - ); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); +describe('Send ERC20 to a 40 character hexadecimal address', function () { + const smartContract = SMART_CONTRACTS.HST; + + it('should ensure the address is prefixed with 0x when pasted and should send TST to a valid hexadecimal address', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPreferencesControllerPetnamesDisabled() + .withTokensControllerERC20() + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Send TST + await driver.clickElement( + '[data-testid="account-overview__asset-tab"]', + ); + await driver.clickElement( + '[data-testid="multichain-token-list-button"]', + ); + await driver.clickElement('[data-testid="coin-overview-send"]'); + // Paste address without hex prefix + await driver.pasteIntoField( + 'input[placeholder="Enter public address (0x) or domain name"]', + nonHexPrefixedAddress, + ); + await driver.findElement({ + css: '.ens-input__selected-input__title', + text: '0x2f318...5C970', + }); + + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // Confirm transaction + await driver.findElement({ + css: 'h2', + text: '0 ETH', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + const sendTransactionListItem = await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + await sendTransactionListItem.click(); + await driver.clickElement({ text: 'Activity log', tag: 'summary' }); + await driver.clickElement('[data-testid="sender-to-recipient__name"]'); + + // Verify address in activity log + await driver.findElement({ + css: '.nickname-popover__public-address', + text: hexPrefixedAddress, + }); + }, + ); }); - describe('Send ERC20 to a 40 character hexadecimal address', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('should ensure the address is prefixed with 0x when pasted and should send TST to a valid hexadecimal address', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - // Paste address without hex prefix - await driver.pasteIntoField( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.findElement({ - css: 'h2', - text: '0 ETH', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - const sendTransactionListItem = await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await sendTransactionListItem.click(); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); - - it('should ensure the address is prefixed with 0x when typed and should send TST to a valid hexadecimal address', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPreferencesControllerPetnamesDisabled() - .withTokensControllerERC20() - .build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, ganacheServer }) => { - await logInWithBalanceValidation(driver, ganacheServer); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - - // Type address without hex prefix - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - nonHexPrefixedAddress, - ); - await driver.findElement({ - css: '.ens-input__selected-input__title', - text: '0x2f318...5C970', - }); - - await driver.clickElement({ text: 'Continue', tag: 'button' }); - - // Confirm transaction - await driver.findElement({ - css: 'h2', - text: '0 ETH', - }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement( - '[data-testid="account-overview__activity-tab"]', - ); - await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - const sendTransactionListItem = await driver.findElement( - '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', - ); - await sendTransactionListItem.click(); - await driver.clickElement({ text: 'Activity log', tag: 'summary' }); - await driver.clickElement( - '[data-testid="sender-to-recipient__name"]', - ); - - // Verify address in activity log - await driver.findElement({ - css: '.nickname-popover__public-address', - text: hexPrefixedAddress, - }); - }, - ); - }); + it('should ensure the address is prefixed with 0x when typed and should send TST to a valid hexadecimal address', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPreferencesControllerPetnamesDisabled() + .withTokensControllerERC20() + .build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test.fullTitle(), + }, + async ({ driver, ganacheServer }) => { + await logInWithBalanceValidation(driver, ganacheServer); + + // Send TST + await driver.clickElement( + '[data-testid="account-overview__asset-tab"]', + ); + await driver.clickElement( + '[data-testid="multichain-token-list-button"]', + ); + await driver.clickElement('[data-testid="coin-overview-send"]'); + + // Type address without hex prefix + await driver.fill( + 'input[placeholder="Enter public address (0x) or domain name"]', + nonHexPrefixedAddress, + ); + await driver.findElement({ + css: '.ens-input__selected-input__title', + text: '0x2f318...5C970', + }); + + await driver.clickElement({ text: 'Continue', tag: 'button' }); + + // Confirm transaction + await driver.findElement({ + css: 'h2', + text: '0 ETH', + }); + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + const sendTransactionListItem = await driver.findElement( + '.transaction-list__completed-transactions .activity-list-item:nth-of-type(1)', + ); + await sendTransactionListItem.click(); + await driver.clickElement({ text: 'Activity log', tag: 'summary' }); + await driver.clickElement('[data-testid="sender-to-recipient__name"]'); + + // Verify address in activity log + await driver.findElement({ + css: '.nickname-popover__public-address', + text: hexPrefixedAddress, + }); + }, + ); }); }); diff --git a/test/e2e/tests/transaction/simple-send.spec.ts b/test/e2e/tests/transaction/simple-send.spec.ts deleted file mode 100644 index 9ac091744974..000000000000 --- a/test/e2e/tests/transaction/simple-send.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Suite } from 'mocha'; -import { Driver } from '../../webdriver/driver'; -import { Ganache } from '../../seeder/ganache'; -import { - withFixtures, - defaultGanacheOptions, - tempToggleSettingRedesignedTransactionConfirmations, -} from '../../helpers'; -import FixtureBuilder from '../../fixture-builder'; -import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; -import { sendTransactionToAddress } from '../../page-objects/flows/send-transaction.flow'; -import ActivityListPage from '../../page-objects/pages/home/activity-list'; -import HomePage from '../../page-objects/pages/home/homepage'; - -describe('Simple send eth', function (this: Suite) { - it('can send a simple transaction from one account to another', async function () { - await withFixtures( - { - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test?.fullTitle(), - }, - async ({ - driver, - ganacheServer, - }: { - driver: Driver; - ganacheServer?: Ganache; - }) => { - await loginWithBalanceValidation(driver, ganacheServer); - - await tempToggleSettingRedesignedTransactionConfirmations(driver); - - await sendTransactionToAddress({ - driver, - recipientAddress: '0x985c30949c92df7a0bd42e0f3e3d539ece98db24', - amount: '1', - gasFee: '0.000042', - totalFee: '1.000042', - }); - const homePage = new HomePage(driver); - await homePage.check_pageIsLoaded(); - const activityList = new ActivityListPage(driver); - await activityList.check_confirmedTxNumberDisplayedInActivity(); - await activityList.check_txAmountInActivity(); - }, - ); - }); -}); diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index b0a335eb0d64..d4a454acb4f4 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -355,7 +355,7 @@ class Driver { // bucket that can include the state attribute to wait for elements that // match the selector to be removed from the DOM. let element; - if (!['visible', 'detached'].includes(state)) { + if (!['visible', 'detached', 'enabled'].includes(state)) { throw new Error(`Provided state selector ${state} is not supported`); } if (state === 'visible') { @@ -368,7 +368,13 @@ class Driver { until.stalenessOf(await this.findElement(rawLocator)), timeout, ); + } else if (state === 'enabled') { + element = await this.driver.wait( + until.elementIsEnabled(await this.findElement(rawLocator)), + timeout, + ); } + return wrapElementWithAPI(element, this); } @@ -499,13 +505,14 @@ class Driver { * and returns a reference to the first matching element. * * @param {string | object} rawLocator - Element locator + * @param {number} timeout - Timeout in milliseconds * @returns {Promise} A promise that resolves to the found element. */ - async findElement(rawLocator) { + async findElement(rawLocator, timeout = this.timeout) { const locator = this.buildLocator(rawLocator); const element = await this.driver.wait( until.elementLocated(locator), - this.timeout, + timeout, ); return wrapElementWithAPI(element, this); } @@ -540,13 +547,14 @@ class Driver { * Finds a clickable element on the page using the given locator. * * @param {string | object} rawLocator - Element locator + * @param {number} timeout - Timeout in milliseconds * @returns {Promise} A promise that resolves to the found clickable element. */ - async findClickableElement(rawLocator) { - const element = await this.findElement(rawLocator); + async findClickableElement(rawLocator, timeout = this.timeout) { + const element = await this.findElement(rawLocator, timeout); await Promise.all([ - this.driver.wait(until.elementIsVisible(element), this.timeout), - this.driver.wait(until.elementIsEnabled(element), this.timeout), + this.driver.wait(until.elementIsVisible(element), timeout), + this.driver.wait(until.elementIsEnabled(element), timeout), ]); return wrapElementWithAPI(element, this); } @@ -601,10 +609,18 @@ class Driver { await element.click(); return; } catch (error) { - if ( - error.name === 'StaleElementReferenceError' && - attempt < retries - 1 - ) { + const retryableErrors = [ + 'StaleElementReferenceError', + 'ElementClickInterceptedError', + 'ElementNotInteractableError', + ]; + + if (retryableErrors.includes(error.name) && attempt < retries - 1) { + console.warn( + `Retrying click (attempt ${attempt + 1}/${retries}) due to: ${ + error.name + }`, + ); await this.delay(1000); } else { throw error; @@ -828,15 +844,13 @@ class Driver { * @returns {Promise} promise that resolves to the WebElement */ async pasteIntoField(rawLocator, contentToPaste) { - // Throw if double-quote is present in content to paste - // so that we don't have to worry about escaping double-quotes - if (contentToPaste.includes('"')) { - throw new Error('Cannot paste content with double-quote'); - } // Click to focus the field await this.clickElement(rawLocator); await this.executeScript( - `navigator.clipboard.writeText("${contentToPaste}")`, + `navigator.clipboard.writeText("${contentToPaste.replace( + /"/gu, + '\\"', + )}")`, ); await this.fill(rawLocator, Key.chord(this.Key.MODIFIER, 'v')); } diff --git a/test/integration/confirmations/signatures/permit-batch.test.tsx b/test/integration/confirmations/signatures/permit-batch.test.tsx index ea311537001c..7a3050dc15c8 100644 --- a/test/integration/confirmations/signatures/permit-batch.test.tsx +++ b/test/integration/confirmations/signatures/permit-batch.test.tsx @@ -1,10 +1,11 @@ import { act, fireEvent, screen } from '@testing-library/react'; import nock from 'nock'; -import mockMetaMaskState from '../../data/integration-init-state.json'; -import { integrationTestRender } from '../../../lib/render-helpers'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; -import { createMockImplementation } from '../../helpers'; import { tEn } from '../../../lib/i18n-helpers'; +import { integrationTestRender } from '../../../lib/render-helpers'; +import mockMetaMaskState from '../../data/integration-init-state.json'; +import { createMockImplementation } from '../../helpers'; import { getMetaMaskStateWithUnapprovedPermitSign, verifyDetails, @@ -15,10 +16,20 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); const backgroundConnectionMocked = { onNotification: jest.fn(), }; +const mockedAssetDetails = jest.mocked(useAssetDetails); const renderPermitBatchSignature = async () => { const account = @@ -58,6 +69,10 @@ describe('Permit Batch Signature Tests', () => { getTokenStandardAndDetails: { decimals: '2' }, }), ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/signatures/permit-seaport.test.tsx b/test/integration/confirmations/signatures/permit-seaport.test.tsx index 7829a2714b57..dc32671da245 100644 --- a/test/integration/confirmations/signatures/permit-seaport.test.tsx +++ b/test/integration/confirmations/signatures/permit-seaport.test.tsx @@ -1,10 +1,11 @@ import { act, fireEvent, screen } from '@testing-library/react'; import nock from 'nock'; -import mockMetaMaskState from '../../data/integration-init-state.json'; -import { integrationTestRender } from '../../../lib/render-helpers'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; -import { createMockImplementation } from '../../helpers'; import { tEn } from '../../../lib/i18n-helpers'; +import { integrationTestRender } from '../../../lib/render-helpers'; +import mockMetaMaskState from '../../data/integration-init-state.json'; +import { createMockImplementation } from '../../helpers'; import { getMetaMaskStateWithUnapprovedPermitSign, verifyDetails, @@ -15,10 +16,20 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); const backgroundConnectionMocked = { onNotification: jest.fn(), }; +const mockedAssetDetails = jest.mocked(useAssetDetails); const renderSeaportSignature = async () => { const account = @@ -58,6 +69,10 @@ describe('Permit Seaport Tests', () => { getTokenStandardAndDetails: { decimals: '2' }, }), ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/signatures/permit-single.test.tsx b/test/integration/confirmations/signatures/permit-single.test.tsx index abb5d07c1587..96fe5c26491d 100644 --- a/test/integration/confirmations/signatures/permit-single.test.tsx +++ b/test/integration/confirmations/signatures/permit-single.test.tsx @@ -1,10 +1,11 @@ import { act, fireEvent, screen } from '@testing-library/react'; import nock from 'nock'; -import mockMetaMaskState from '../../data/integration-init-state.json'; -import { integrationTestRender } from '../../../lib/render-helpers'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; -import { createMockImplementation } from '../../helpers'; import { tEn } from '../../../lib/i18n-helpers'; +import { integrationTestRender } from '../../../lib/render-helpers'; +import mockMetaMaskState from '../../data/integration-init-state.json'; +import { createMockImplementation } from '../../helpers'; import { getMetaMaskStateWithUnapprovedPermitSign, verifyDetails, @@ -15,10 +16,20 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); const backgroundConnectionMocked = { onNotification: jest.fn(), }; +const mockedAssetDetails = jest.mocked(useAssetDetails); const renderSingleBatchSignature = async () => { const account = @@ -58,6 +69,10 @@ describe('Permit Single Signature Tests', () => { getTokenStandardAndDetails: { decimals: '2' }, }), ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/signatures/permit-tradeOrder.test.tsx b/test/integration/confirmations/signatures/permit-tradeOrder.test.tsx index 429e533ff8f8..3f915967dc00 100644 --- a/test/integration/confirmations/signatures/permit-tradeOrder.test.tsx +++ b/test/integration/confirmations/signatures/permit-tradeOrder.test.tsx @@ -1,10 +1,11 @@ import { act, screen } from '@testing-library/react'; import nock from 'nock'; -import mockMetaMaskState from '../../data/integration-init-state.json'; -import { integrationTestRender } from '../../../lib/render-helpers'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; -import { createMockImplementation } from '../../helpers'; import { tEn } from '../../../lib/i18n-helpers'; +import { integrationTestRender } from '../../../lib/render-helpers'; +import mockMetaMaskState from '../../data/integration-init-state.json'; +import { createMockImplementation } from '../../helpers'; import { getMetaMaskStateWithUnapprovedPermitSign, verifyDetails, @@ -15,10 +16,20 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); const backgroundConnectionMocked = { onNotification: jest.fn(), }; +const mockedAssetDetails = jest.mocked(useAssetDetails); const renderTradeOrderSignature = async () => { const account = @@ -58,6 +69,10 @@ describe('Permit Trade Order Tests', () => { getTokenStandardAndDetails: { decimals: '2' }, }), ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/signatures/permit.test.tsx b/test/integration/confirmations/signatures/permit.test.tsx index 6b736e4add90..332cebc3a6b2 100644 --- a/test/integration/confirmations/signatures/permit.test.tsx +++ b/test/integration/confirmations/signatures/permit.test.tsx @@ -7,6 +7,7 @@ import { MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { shortenAddress } from '../../../../ui/helpers/utils/util'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { integrationTestRender } from '../../../lib/render-helpers'; import mockMetaMaskState from '../../data/integration-init-state.json'; @@ -18,10 +19,20 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); const backgroundConnectionMocked = { onNotification: jest.fn(), }; +const mockedAssetDetails = jest.mocked(useAssetDetails); describe('Permit Confirmation', () => { beforeEach(() => { @@ -31,6 +42,10 @@ describe('Permit Confirmation', () => { getTokenStandardAndDetails: { decimals: '2', standard: 'ERC20' }, }), ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/signatures/personalSign.test.tsx b/test/integration/confirmations/signatures/personalSign.test.tsx index 03685f46ab7b..d58e0d441e03 100644 --- a/test/integration/confirmations/signatures/personalSign.test.tsx +++ b/test/integration/confirmations/signatures/personalSign.test.tsx @@ -1,6 +1,6 @@ import { ApprovalType } from '@metamask/controller-utils'; -import { act, fireEvent, screen, waitFor } from '@testing-library/react'; import { CHAIN_IDS } from '@metamask/transaction-controller'; +import { act, fireEvent, screen, waitFor } from '@testing-library/react'; import { MESSAGE_TYPE } from '../../../../shared/constants/app'; import { MetaMetricsEventCategory, @@ -8,6 +8,7 @@ import { MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { shortenAddress } from '../../../../ui/helpers/utils/util'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { integrationTestRender } from '../../../lib/render-helpers'; import mockMetaMaskState from '../../data/integration-init-state.json'; @@ -17,7 +18,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ submitRequestToBackground: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -68,6 +79,10 @@ const getMetaMaskStateWithUnapprovedPersonalSign = (accountAddress: string) => { describe('PersonalSign Confirmation', () => { beforeEach(() => { jest.resetAllMocks(); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); it('displays the header account modal with correct data', async () => { diff --git a/test/integration/confirmations/transactions/alerts.test.tsx b/test/integration/confirmations/transactions/alerts.test.tsx index b21a7dbb679c..ee7e95762ac3 100644 --- a/test/integration/confirmations/transactions/alerts.test.tsx +++ b/test/integration/confirmations/transactions/alerts.test.tsx @@ -1,12 +1,13 @@ import { randomUUID } from 'crypto'; -import { act, fireEvent, screen } from '@testing-library/react'; import { ApprovalType } from '@metamask/controller-utils'; +import { act, fireEvent, screen } from '@testing-library/react'; import nock from 'nock'; -import mockMetaMaskState from '../../data/integration-init-state.json'; -import { integrationTestRender } from '../../../lib/render-helpers'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; -import { createMockImplementation, mock4byte } from '../../helpers'; +import { integrationTestRender } from '../../../lib/render-helpers'; import { createTestProviderTools } from '../../../stub/provider'; +import mockMetaMaskState from '../../data/integration-init-state.json'; +import { createMockImplementation, mock4byte } from '../../helpers'; import { getUnapprovedApproveTransaction } from './transactionDataHelpers'; jest.mock('../../../../ui/store/background-connection', () => ({ @@ -15,7 +16,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -92,6 +103,10 @@ describe('Contract Interaction Confirmation Alerts', () => { setupSubmitRequestToBackgroundMocks(); const APPROVE_NFT_HEX_SIG = '0x095ea7b3'; mock4byte(APPROVE_NFT_HEX_SIG); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/transactions/contract-deployment.test.tsx b/test/integration/confirmations/transactions/contract-deployment.test.tsx index 7698ce3ef8b2..45410c0a76d9 100644 --- a/test/integration/confirmations/transactions/contract-deployment.test.tsx +++ b/test/integration/confirmations/transactions/contract-deployment.test.tsx @@ -13,6 +13,7 @@ import { MetaMetricsEventLocation, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -26,7 +27,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -136,6 +147,10 @@ describe('Contract Deployment Confirmation', () => { setupSubmitRequestToBackgroundMocks(); const DEPOSIT_HEX_SIG = '0xd0e30db0'; mock4byte(DEPOSIT_HEX_SIG); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/transactions/contract-interaction.test.tsx b/test/integration/confirmations/transactions/contract-interaction.test.tsx index 5db121bc9fda..e3da57aeceb3 100644 --- a/test/integration/confirmations/transactions/contract-interaction.test.tsx +++ b/test/integration/confirmations/transactions/contract-interaction.test.tsx @@ -13,6 +13,7 @@ import { MetaMetricsEventLocation, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -31,7 +32,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -156,6 +167,10 @@ describe('Contract Interaction Confirmation', () => { setupSubmitRequestToBackgroundMocks(); const MINT_NFT_HEX_SIG = '0x3b4b1381'; mock4byte(MINT_NFT_HEX_SIG); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/transactions/erc20-approve.test.tsx b/test/integration/confirmations/transactions/erc20-approve.test.tsx index c25b2ee3627d..f77c8162b79d 100644 --- a/test/integration/confirmations/transactions/erc20-approve.test.tsx +++ b/test/integration/confirmations/transactions/erc20-approve.test.tsx @@ -3,6 +3,7 @@ import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import nock from 'nock'; import { TokenStandard } from '../../../../shared/constants/transaction'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -17,7 +18,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockImplementation(() => ({ + decimals: '4', + })), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -140,6 +151,10 @@ describe('ERC20 Approve Confirmation', () => { const APPROVE_ERC20_HEX_SIG = '0x095ea7b3'; const APPROVE_ERC20_TEXT_SIG = 'approve(address,uint256)'; mock4byte(APPROVE_ERC20_HEX_SIG, APPROVE_ERC20_TEXT_SIG); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/transactions/erc721-approve.test.tsx b/test/integration/confirmations/transactions/erc721-approve.test.tsx index 4f211576e6cd..cce5456ae0a2 100644 --- a/test/integration/confirmations/transactions/erc721-approve.test.tsx +++ b/test/integration/confirmations/transactions/erc721-approve.test.tsx @@ -3,6 +3,7 @@ import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import nock from 'nock'; import { TokenStandard } from '../../../../shared/constants/transaction'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -17,7 +18,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -140,6 +151,10 @@ describe('ERC721 Approve Confirmation', () => { const APPROVE_NFT_HEX_SIG = '0x095ea7b3'; const APPROVE_NFT_TEXT_SIG = 'approve(address,uint256)'; mock4byte(APPROVE_NFT_HEX_SIG, APPROVE_NFT_TEXT_SIG); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { @@ -220,6 +235,7 @@ describe('ERC721 Approve Confirmation', () => { const approveDetails = await screen.findByTestId( 'confirmation__approve-details', ); + expect(approveDetails).toBeInTheDocument(); const approveDetailsSpender = await screen.findByTestId( 'confirmation__approve-spender', diff --git a/test/integration/confirmations/transactions/increase-allowance.test.tsx b/test/integration/confirmations/transactions/increase-allowance.test.tsx index fb2ef9cf2629..083c8b3a72dd 100644 --- a/test/integration/confirmations/transactions/increase-allowance.test.tsx +++ b/test/integration/confirmations/transactions/increase-allowance.test.tsx @@ -3,6 +3,7 @@ import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import nock from 'nock'; import { TokenStandard } from '../../../../shared/constants/transaction'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -17,7 +18,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -144,6 +155,10 @@ describe('ERC20 increaseAllowance Confirmation', () => { INCREASE_ALLOWANCE_ERC20_HEX_SIG, INCREASE_ALLOWANCE_ERC20_TEXT_SIG, ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/confirmations/transactions/set-approval-for-all.test.tsx b/test/integration/confirmations/transactions/set-approval-for-all.test.tsx index 51cb991ac3b2..c017f8acc9ca 100644 --- a/test/integration/confirmations/transactions/set-approval-for-all.test.tsx +++ b/test/integration/confirmations/transactions/set-approval-for-all.test.tsx @@ -3,6 +3,7 @@ import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import nock from 'nock'; import { TokenStandard } from '../../../../shared/constants/transaction'; +import { useAssetDetails } from '../../../../ui/pages/confirmations/hooks/useAssetDetails'; import * as backgroundConnection from '../../../../ui/store/background-connection'; import { tEn } from '../../../lib/i18n-helpers'; import { integrationTestRender } from '../../../lib/render-helpers'; @@ -17,7 +18,17 @@ jest.mock('../../../../ui/store/background-connection', () => ({ callBackgroundMethod: jest.fn(), })); +jest.mock('../../../../ui/pages/confirmations/hooks/useAssetDetails', () => ({ + ...jest.requireActual( + '../../../../ui/pages/confirmations/hooks/useAssetDetails', + ), + useAssetDetails: jest.fn().mockResolvedValue({ + decimals: '4', + }), +})); + const mockedBackgroundConnection = jest.mocked(backgroundConnection); +const mockedAssetDetails = jest.mocked(useAssetDetails); const backgroundConnectionMocked = { onNotification: jest.fn(), @@ -144,6 +155,10 @@ describe('ERC721 setApprovalForAll Confirmation', () => { INCREASE_SET_APPROVAL_FOR_ALL_HEX_SIG, INCREASE_SET_APPROVAL_FOR_ALL_TEXT_SIG, ); + mockedAssetDetails.mockImplementation(() => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + decimals: '4' as any, + })); }); afterEach(() => { diff --git a/test/integration/data/integration-init-state.json b/test/integration/data/integration-init-state.json index 3d3580dc12ca..cbf065ea2aba 100644 --- a/test/integration/data/integration-init-state.json +++ b/test/integration/data/integration-init-state.json @@ -2049,7 +2049,6 @@ "useNftDetection": false, "useNonceField": false, "usePhishDetect": true, - "useRequestQueue": false, "useSafeChainsListValidation": true, "useTokenDetection": false, "useTransactionSimulations": true, diff --git a/test/integration/data/onboarding-completion-route.json b/test/integration/data/onboarding-completion-route.json index 9d3df88dbeae..479c9041b3a2 100644 --- a/test/integration/data/onboarding-completion-route.json +++ b/test/integration/data/onboarding-completion-route.json @@ -462,7 +462,6 @@ "useNftDetection": false, "useNonceField": false, "usePhishDetect": true, - "useRequestQueue": true, "useSafeChainsListValidation": true, "useTokenDetection": true, "useTransactionSimulations": true, diff --git a/test/integration/notifications&auth/data/notification-state.ts b/test/integration/notifications&auth/data/notification-state.ts index 61d74d161671..d91c1e7f0d2e 100644 --- a/test/integration/notifications&auth/data/notification-state.ts +++ b/test/integration/notifications&auth/data/notification-state.ts @@ -40,6 +40,7 @@ export const getMockedNotificationsState = () => { isProfileSyncingUpdateLoading: false, hasAccountSyncingSyncedAtLeastOnce: false, isAccountSyncingReadyToBeDispatched: false, + isAccountSyncingInProgress: false, isMetamaskNotificationsFeatureSeen: true, isNotificationServicesEnabled: true, isFeatureAnnouncementsEnabled: true, diff --git a/test/jest/mocks.ts b/test/jest/mocks.ts index 8822b96315b6..b165385d8f4b 100644 --- a/test/jest/mocks.ts +++ b/test/jest/mocks.ts @@ -3,9 +3,9 @@ import { EthMethod, BtcMethod, BtcAccountType, - InternalAccount, isEvmAccountType, } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import { v4 as uuidv4 } from 'uuid'; import { keyringTypeToName } from '@metamask/accounts-controller'; @@ -186,7 +186,11 @@ export function createMockInternalAccount({ type = EthAccountType.Eoa, keyringType = KeyringTypes.hd, lastSelected = 0, - snapOptions = undefined, + snapOptions = { + enabled: true, + id: 'npm:snap-id', + name: 'snap-name', + }, options = undefined, }: { name?: string; @@ -236,7 +240,7 @@ export function createMockInternalAccount({ keyring: { type: keyringType, }, - snap: snapOptions, + snap: keyringType === KeyringTypes.snap ? snapOptions : undefined, lastSelected, }, options: options ?? {}, diff --git a/test/lib/render-helpers.js b/test/lib/render-helpers.js index 574415f2f3c6..d2161fe1cf2e 100644 --- a/test/lib/render-helpers.js +++ b/test/lib/render-helpers.js @@ -69,10 +69,15 @@ const createProviderWrapper = (store, pathname = '/') => { }; }; -export function renderWithProvider(component, store, pathname = '/') { +export function renderWithProvider( + component, + store, + pathname = '/', + renderer = render, +) { const { history, Wrapper } = createProviderWrapper(store, pathname); return { - ...render(component, { wrapper: Wrapper }), + ...renderer(component, { wrapper: Wrapper }), history, }; } diff --git a/types/eth-query.d.ts b/types/eth-query.d.ts deleted file mode 100644 index 726300f68176..000000000000 --- a/types/eth-query.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -declare module 'eth-query' { - // What it says on the tin. We omit `null` because confusingly, this is used - // for a successful response to indicate a lack of an error. - type EverythingButNull = - | string - | number - | boolean - | object - | symbol - | undefined; - - type ProviderSendAsyncResponse = { - error?: { message: string }; - result?: Result; - }; - - type ProviderSendAsyncCallback = ( - error: unknown, - response: ProviderSendAsyncResponse, - ) => void; - - type Provider = { - sendAsync( - payload: SendAsyncPayload, - callback: ProviderSendAsyncCallback, - ): void; - }; - - type SendAsyncPayload = { - id: number; - jsonrpc: '2.0'; - method: string; - params: Params; - }; - - type SendAsyncCallback = ( - ...args: - | [error: EverythingButNull, result: undefined] - | [error: null, result: Result] - ) => void; - - export default class EthQuery { - constructor(provider: Provider); - - sendAsync( - opts: Partial>, - callback: SendAsyncCallback, - ): void; - } -} diff --git a/types/global.d.ts b/types/global.d.ts index 8078a3998bde..8dbd3a02e314 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -21,6 +21,7 @@ import { OffscreenCommunicationTarget, TrezorAction, } from 'shared/constants/offscreen-communication'; +import type { Provider } from '@metamask/network-controller'; import type { Preferences } from '../app/scripts/controllers/preferences-controller'; declare class Platform { @@ -233,11 +234,6 @@ type SentryObject = Sentry & { getMetaMetricsEnabled: () => Promise; }; -type HttpProvider = { - host: string; - timeout: number; -}; - type StateHooks = { getCustomTraces?: () => { [name: string]: number }; getCleanAppState?: () => Promise; @@ -263,7 +259,7 @@ export declare global { var chrome: Chrome; - var ethereumProvider: HttpProvider; + var ethereumProvider: Provider; var stateHooks: StateHooks; diff --git a/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.tsx b/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.tsx index f84c8113ae1e..c0089b6d31ed 100644 --- a/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.tsx +++ b/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.tsx @@ -87,7 +87,7 @@ function ConfirmDetails({ <> - {t('confirmationAlertModalDetails')} + {t('confirmationAlertDetails')} { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should fire metrics event when refresh button is clicked', async () => { + const store = configureMockStore([thunk])({ + metamask: { + selectedNetworkClientId: 'selectedNetworkClientId', + networkConfigurationsByChainId: { + '0x1': { + chainId: '0x1', + defaultRpcEndpointIndex: 0, + rpcEndpoints: [ + { + networkClientId: 'selectedNetworkClientId', + }, + ], + }, + }, + internalAccounts: { + selectedAccount: 'selectedAccount', + accounts: { + selectedAccount: {}, + }, + }, + }, + }); + + const mockTrackEvent = jest.fn(); + + const { findByTestId } = renderWithProvider( + + + , + store, + ); + + const importButton = await findByTestId('import-token-button'); + importButton.click(); + + const refreshListItem = await findByTestId('refreshList__button'); + refreshListItem.click(); + + expect(mockTrackEvent).toHaveBeenCalledTimes(1); + expect(mockTrackEvent).toHaveBeenCalledWith({ + category: MetaMetricsEventCategory.Tokens, + event: MetaMetricsEventName.TokenListRefreshed, + }); + }); +}); diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx index 348fd82fbdaa..d335f6f41820 100644 --- a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx +++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { getCurrentNetwork, getIsTokenNetworkFilterEqualCurrentNetwork, + getSelectedInternalAccount, getTokenNetworkFilter, } from '../../../../../selectors'; import { getNetworkConfigurationsByChainId } from '../../../../../../shared/modules/selectors/networks'; @@ -49,6 +50,8 @@ import { showImportTokensModal, } from '../../../../../store/actions'; import Tooltip from '../../../../ui/tooltip'; +import { useMultichainSelector } from '../../../../../hooks/useMultichainSelector'; +import { getMultichainNetwork } from '../../../../../selectors/multichain'; type AssetListControlBarProps = { showTokensLinks?: boolean; @@ -72,6 +75,9 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { const [isNetworkFilterPopoverOpen, setIsNetworkFilterPopoverOpen] = useState(false); + const account = useSelector(getSelectedInternalAccount); + const { isEvmNetwork } = useMultichainSelector(getMultichainNetwork, account); + const isTestNetwork = useMemo(() => { return (TEST_CHAINS as string[]).includes(currentNetwork.chainId); }, [currentNetwork.chainId, TEST_CHAINS]); @@ -154,6 +160,10 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { const handleRefresh = () => { dispatch(detectTokens()); closePopover(); + trackEvent({ + category: MetaMetricsEventCategory.Tokens, + event: MetaMetricsEventName.TokenListRefreshed, + }); }; return ( @@ -166,12 +176,13 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { - {process.env.PORTFOLIO_VIEW && ( + {/* TODO: Remove isEvmNetwork check when we are ready to show the network filter in all networks including non-EVM */} + {process.env.PORTFOLIO_VIEW && isEvmNetwork ? ( { ? currentNetwork?.nickname ?? t('currentNetwork') : t('popularNetworks')} - )} + ) : null} { })), tokenBalancesStartPolling: jest.fn().mockResolvedValue('pollingToken'), tokenBalancesStopPollingByPollingToken: jest.fn(), + addImportedTokens: jest.fn(), + }; +}); + +// Mock the dispatch function +const mockDispatch = jest.fn(); + +jest.mock('react-redux', () => { + const actual = jest.requireActual('react-redux'); + return { + ...actual, + useDispatch: () => mockDispatch, }; }); diff --git a/ui/components/app/assets/asset-list/asset-list.tsx b/ui/components/app/assets/asset-list/asset-list.tsx index 3cd06ec4686b..5ac7a84e0b29 100644 --- a/ui/components/app/assets/asset-list/asset-list.tsx +++ b/ui/components/app/assets/asset-list/asset-list.tsx @@ -1,14 +1,17 @@ -import React, { useContext, useState } from 'react'; -import { useSelector } from 'react-redux'; +import React, { useContext, useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { Token } from '@metamask/assets-controllers'; +import { NetworkConfiguration } from '@metamask/network-controller'; import TokenList from '../token-list'; import { PRIMARY } from '../../../../helpers/constants/common'; import { useUserPreferencedCurrency } from '../../../../hooks/useUserPreferencedCurrency'; import { getAllDetectedTokensForSelectedAddress, getDetectedTokensInCurrentNetwork, - getIstokenDetectionInactiveOnNonMainnetSupportedNetwork, getIsTokenNetworkFilterEqualCurrentNetwork, getSelectedAccount, + getSelectedAddress, + getUseTokenDetection, } from '../../../../selectors'; import { getMultichainIsEvm, @@ -23,9 +26,10 @@ import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { MetaMetricsEventCategory, MetaMetricsEventName, + MetaMetricsTokenEventSource, } from '../../../../../shared/constants/metametrics'; import DetectedToken from '../../detected-token/detected-token'; -import { DetectedTokensBanner, ReceiveModal } from '../../../multichain'; +import { ReceiveModal } from '../../../multichain'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { FundingMethodModal } from '../../../multichain/funding-method-modal/funding-method-modal'; ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) @@ -35,6 +39,16 @@ import { } from '../../../multichain/ramps-card/ramps-card'; import { getIsNativeTokenBuyable } from '../../../../ducks/ramps'; ///: END:ONLY_INCLUDE_IF +import { + getCurrentChainId, + getNetworkConfigurationsByChainId, + getSelectedNetworkClientId, +} from '../../../../../shared/modules/selectors/networks'; +import { addImportedTokens } from '../../../../store/actions'; +import { + AssetType, + TokenStandard, +} from '../../../../../shared/constants/transaction'; import AssetListControlBar from './asset-list-control-bar'; import NativeToken from './native-token'; @@ -54,6 +68,7 @@ export type AssetListProps = { }; const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => { + const dispatch = useDispatch(); const [showDetectedTokens, setShowDetectedTokens] = useState(false); const selectedAccount = useSelector(getSelectedAccount); const t = useI18nContext(); @@ -74,14 +89,19 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => { }); const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork) || []; - const isTokenDetectionInactiveOnNonMainnetSupportedNetwork = useSelector( - getIstokenDetectionInactiveOnNonMainnetSupportedNetwork, - ); const isTokenNetworkFilterEqualCurrentNetwork = useSelector( getIsTokenNetworkFilterEqualCurrentNetwork, ); + const allNetworks: Record<`0x${string}`, NetworkConfiguration> = useSelector( + getNetworkConfigurationsByChainId, + ); + const networkClientId = useSelector(getSelectedNetworkClientId); + const selectedAddress = useSelector(getSelectedAddress); + const useTokenDetection = useSelector(getUseTokenDetection); + const currentChainId = useSelector(getCurrentChainId); + const [showFundingMethodModal, setShowFundingMethodModal] = useState(false); const [showReceiveModal, setShowReceiveModal] = useState(false); @@ -104,31 +124,88 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => { // for EVM assets const shouldShowTokensLinks = showTokensLinks ?? isEvm; - const detectedTokensMultichain = useSelector( - getAllDetectedTokensForSelectedAddress, - ); + const detectedTokensMultichain: { + [key: `0x${string}`]: Token[]; + } = useSelector(getAllDetectedTokensForSelectedAddress); + + const multichainDetectedTokensLength = Object.values( + detectedTokensMultichain || {}, + ).reduce((acc, tokens) => acc + tokens.length, 0); + + // Add detected tokens to sate + useEffect(() => { + const importAllDetectedTokens = async () => { + // If autodetect tokens toggle is OFF, return + if (!useTokenDetection) { + return; + } + // TODO add event for MetaMetricsEventName.TokenAdded + + if ( + process.env.PORTFOLIO_VIEW && + !isTokenNetworkFilterEqualCurrentNetwork + ) { + const importPromises = Object.entries(detectedTokensMultichain).map( + async ([networkId, tokens]) => { + const chainConfig = allNetworks[networkId as `0x${string}`]; + const { defaultRpcEndpointIndex } = chainConfig; + const { networkClientId: networkInstanceId } = + chainConfig.rpcEndpoints[defaultRpcEndpointIndex]; + + await dispatch( + addImportedTokens(tokens as Token[], networkInstanceId), + ); + tokens.forEach((importedToken) => { + trackEvent({ + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, + sensitiveProperties: { + token_symbol: importedToken.symbol, + token_contract_address: importedToken.address, + token_decimal_precision: importedToken.decimals, + source: MetaMetricsTokenEventSource.Detected, + token_standard: TokenStandard.ERC20, + asset_type: AssetType.token, + token_added_type: 'detected', + chain_id: chainConfig.chainId, + }, + }); + }); + }, + ); + + await Promise.all(importPromises); + } else if (detectedTokens.length > 0) { + await dispatch(addImportedTokens(detectedTokens, networkClientId)); + detectedTokens.forEach((importedToken: Token) => { + trackEvent({ + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, + sensitiveProperties: { + token_symbol: importedToken.symbol, + token_contract_address: importedToken.address, + token_decimal_precision: importedToken.decimals, + source: MetaMetricsTokenEventSource.Detected, + token_standard: TokenStandard.ERC20, + asset_type: AssetType.token, + token_added_type: 'detected', + chain_id: currentChainId, + }, + }); + }); + } + }; + importAllDetectedTokens(); + }, [ + isTokenNetworkFilterEqualCurrentNetwork, + selectedAddress, + networkClientId, + detectedTokens.length, + multichainDetectedTokensLength, + ]); - const totalTokens = - process.env.PORTFOLIO_VIEW && - !isTokenNetworkFilterEqualCurrentNetwork && - detectedTokensMultichain - ? (Object.values(detectedTokensMultichain).reduce( - // @ts-expect-error TS18046: 'tokenArray' is of type 'unknown' - (count, tokenArray) => count + tokenArray.length, - 0, - ) as number) - : detectedTokens.length; return ( <> - {totalTokens && - totalTokens > 0 && - !isTokenDetectionInactiveOnNonMainnetSupportedNetwork ? ( - setShowDetectedTokens(true)} - margin={4} - /> - ) : null}
    @@ -13,7 +13,7 @@ exports[`NFT Default Image should match snapshot with all provided props 1`] = ` exports[`NFT Default Image should match snapshot with missing clickable prop 1`] = `
    @@ -23,7 +23,7 @@ exports[`NFT Default Image should match snapshot with missing clickable prop 1`] exports[`NFT Default Image should render with no props 1`] = `
    diff --git a/ui/components/app/assets/nfts/nft-default-image/nft-default-image.js b/ui/components/app/assets/nfts/nft-default-image/nft-default-image.tsx similarity index 63% rename from ui/components/app/assets/nfts/nft-default-image/nft-default-image.js rename to ui/components/app/assets/nfts/nft-default-image/nft-default-image.tsx index 37c31e1bf35e..4fd6676507ec 100644 --- a/ui/components/app/assets/nfts/nft-default-image/nft-default-image.js +++ b/ui/components/app/assets/nfts/nft-default-image/nft-default-image.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import { useDispatch } from 'react-redux'; import { @@ -12,7 +11,15 @@ import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { ButtonLink, Box } from '../../../../component-library'; import { showIpfsModal } from '../../../../../store/actions'; -export default function NftDefaultImage({ className, clickable }) { +type NftDefaultImageProps = { + className: string; + clickable?: boolean; +}; + +export default function NftDefaultImage({ + className, + clickable, +}: NftDefaultImageProps) { const t = useI18nContext(); const dispatch = useDispatch(); @@ -21,18 +28,18 @@ export default function NftDefaultImage({ className, clickable }) { tabIndex={0} data-testid="nft-default-image" className={classnames(className, 'nft-default', { - 'nft-default--clickable': clickable, + 'nft-default--clickable': Boolean(clickable), })} display={Display.Flex} - alignItems={AlignItems.Center} - justifyContent={JustifyContent.Center} + alignItems={AlignItems.center} + justifyContent={JustifyContent.center} borderRadius={BorderRadius.LG} > {clickable && ( { + onClick={(e: { stopPropagation: () => void }) => { e.stopPropagation(); dispatch(showIpfsModal()); }} @@ -43,15 +50,3 @@ export default function NftDefaultImage({ className, clickable }) { ); } - -NftDefaultImage.propTypes = { - /** - * Controls the css class for the cursor hover - * It determines if we need to show the button on default image or not - */ - clickable: PropTypes.bool, - /** - * An additional className to apply to the NFT default image - */ - className: PropTypes.string, -}; diff --git a/ui/components/app/assets/nfts/nft-details/__snapshots__/nft-details.test.js.snap b/ui/components/app/assets/nfts/nft-details/__snapshots__/nft-details.test.js.snap index dd91a6bb0188..380e39f95f44 100644 --- a/ui/components/app/assets/nfts/nft-details/__snapshots__/nft-details.test.js.snap +++ b/ui/components/app/assets/nfts/nft-details/__snapshots__/nft-details.test.js.snap @@ -24,10 +24,12 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` style="mask-image: url('./images/icons/arrow-left.svg');" /> -
    +
    -
    -
    + +
    - G +
    + G +
    -
    - + +

    +

    +

    - + +

    +

    +

    diff --git a/ui/components/app/assets/nfts/nft-details/index.scss b/ui/components/app/assets/nfts/nft-details/index.scss index 5d8cda879a57..a10fec90d753 100644 --- a/ui/components/app/assets/nfts/nft-details/index.scss +++ b/ui/components/app/assets/nfts/nft-details/index.scss @@ -108,7 +108,7 @@ $spacer-break-small: 16px; padding-left: 16px; padding-right: 16px; border-radius: var(--Spacing-sm, 8px); - border: 1px solid var(--border-muted, #d6d9dc); + border: 1px solid var(--color-border-muted); } &__nft-attribute-frame { diff --git a/ui/components/app/assets/nfts/nft-details/nft-details.test.js b/ui/components/app/assets/nfts/nft-details/nft-details.test.js index 350dc4813c6a..e378fb4bb2bf 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-details.test.js +++ b/ui/components/app/assets/nfts/nft-details/nft-details.test.js @@ -109,7 +109,8 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const removeNftButton = queryByTestId('nft-item-remove'); + const removeNftButton = queryByTestId('nft-item-remove')?.firstChild; + expect(removeNftButton).toBeInTheDocument(); fireEvent.click(removeNftButton); await expect(removeAndIgnoreNft).toHaveBeenCalledWith( @@ -132,7 +133,7 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const removeNftButton = queryByTestId('nft-item-remove'); + const removeNftButton = queryByTestId('nft-item-remove')?.firstChild; fireEvent.click(removeNftButton); await expect(removeAndIgnoreNft).toHaveBeenCalledWith( @@ -217,14 +218,16 @@ describe('NFT Details', () => { mockStore, ); + const openTabSpy = jest.spyOn(global.platform, 'openTab'); + const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); fireEvent.click(openOpenSea); await waitFor(() => { - expect(global.platform.openTab).toHaveBeenCalledWith({ + expect(openTabSpy).toHaveBeenCalledWith({ url: `https://testnets.opensea.io/assets/goerli/${nfts[5].address}/${nfts[5].tokenId}`, }); }); @@ -242,6 +245,8 @@ describe('NFT Details', () => { }; const mainnetMockStore = configureMockStore([thunk])(mainnetState); + const openTabSpy = jest.spyOn(global.platform, 'openTab'); + const { queryByTestId } = renderWithProvider( , mainnetMockStore, @@ -250,11 +255,11 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); fireEvent.click(openOpenSea); await waitFor(() => { - expect(global.platform.openTab).toHaveBeenCalledWith({ + expect(openTabSpy).toHaveBeenCalledWith({ url: `https://opensea.io/assets/ethereum/${nfts[5].address}/${nfts[5].tokenId}`, }); }); @@ -270,6 +275,8 @@ describe('NFT Details', () => { }; const polygonMockStore = configureMockStore([thunk])(polygonState); + const openTabSpy = jest.spyOn(global.platform, 'openTab'); + const { queryByTestId } = renderWithProvider( , polygonMockStore, @@ -278,11 +285,11 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); fireEvent.click(openOpenSea); await waitFor(() => { - expect(global.platform.openTab).toHaveBeenCalledWith({ + expect(openTabSpy).toHaveBeenCalledWith({ url: `https://opensea.io/assets/matic/${nfts[5].address}/${nfts[5].tokenId}`, }); }); @@ -298,6 +305,8 @@ describe('NFT Details', () => { }; const sepoliaMockStore = configureMockStore([thunk])(sepoliaState); + const openTabSpy = jest.spyOn(global.platform, 'openTab'); + const { queryByTestId } = renderWithProvider( , sepoliaMockStore, @@ -306,11 +315,11 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); fireEvent.click(openOpenSea); await waitFor(() => { - expect(global.platform.openTab).toHaveBeenCalledWith({ + expect(openTabSpy).toHaveBeenCalledWith({ url: `https://testnets.opensea.io/assets/sepolia/${nfts[5].address}/${nfts[5].tokenId}`, }); }); @@ -336,7 +345,7 @@ describe('NFT Details', () => { const openOptionMenuButton = queryByTestId('nft-options__button'); fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); await waitFor(() => { expect(openOpenSea).not.toBeInTheDocument(); }); diff --git a/ui/components/app/assets/nfts/nft-details/nft-details.tsx b/ui/components/app/assets/nfts/nft-details/nft-details.tsx index 49408dfd5fa4..8a857e5f0ce1 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-details.tsx +++ b/ui/components/app/assets/nfts/nft-details/nft-details.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useContext } from 'react'; -import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { isEqual } from 'lodash'; @@ -21,11 +20,7 @@ import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { shortenAddress } from '../../../../../helpers/utils/util'; import { getNftImageAlt } from '../../../../../helpers/utils/nfts'; import { getCurrentChainId } from '../../../../../../shared/modules/selectors/networks'; -import { - getCurrentCurrency, - getCurrentNetwork, - getIpfsGateway, -} from '../../../../../selectors'; +import { getCurrentNetwork, getIpfsGateway } from '../../../../../selectors'; import { ASSET_ROUTE, DEFAULT_ROUTE, @@ -67,7 +62,10 @@ import { Content, Footer, Page } from '../../../../multichain/pages/page'; import { formatCurrency } from '../../../../../helpers/utils/confirm-tx.util'; import { getShortDateFormatterV2 } from '../../../../../pages/asset/util'; import { CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../../../shared/constants/common'; -import { getConversionRate } from '../../../../../ducks/metamask/metamask'; +import { + getConversionRate, + getCurrentCurrency, +} from '../../../../../ducks/metamask/metamask'; import { Numeric } from '../../../../../../shared/modules/Numeric'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths @@ -113,7 +111,10 @@ export default function NftDetails({ nft }: { nft: Nft }) { const isIpfsURL = nftSrcUrl?.startsWith('ipfs:'); const isImageHosted = image?.startsWith('https:') || image?.startsWith('http:'); - const nftImageURL = useGetAssetImageUrl(imageOriginal ?? image, ipfsGateway); + const nftImageURL = useGetAssetImageUrl( + imageOriginal ?? image ?? undefined, + ipfsGateway, + ); const hasFloorAskPrice = Boolean( collection?.floorAsk?.price?.amount?.usd && @@ -311,6 +312,8 @@ export default function NftDetails({ nft }: { nft: Nft }) { return `${text.slice(0, chars)}...${text.slice(-chars)}`; }; + const nftItemSrc = isImageHosted ? image : nftImageURL; + return ( @@ -327,11 +330,13 @@ export default function NftDetails({ nft }: { nft: Nft }) { data-testid="nft__back" /> global.platform.openTab({ url: openSeaLink }) - : null - } + showOpenSeaLink={Boolean(openSeaLink)} + onViewOnOpensea={() => { + if (!openSeaLink) { + return null; + } + return global.platform.openTab({ url: openSeaLink }); + }} onRemove={onRemove} />
    @@ -343,14 +348,13 @@ export default function NftDetails({ nft }: { nft: Nft }) { > @@ -847,106 +851,3 @@ export default function NftDetails({ nft }: { nft: Nft }) { ); } - -NftDetails.propTypes = { - nft: PropTypes.shape({ - address: PropTypes.string.isRequired, - tokenId: PropTypes.string.isRequired, - isCurrentlyOwned: PropTypes.bool, - name: PropTypes.string, - description: PropTypes.string, - image: PropTypes.string, - standard: PropTypes.string, - imageThumbnail: PropTypes.string, - imagePreview: PropTypes.string, - imageOriginal: PropTypes.string, - rarityRank: PropTypes.string, - - creator: PropTypes.shape({ - address: PropTypes.string, - config: PropTypes.string, - profile_img_url: PropTypes.string, - }), - attributes: PropTypes.arrayOf( - PropTypes.shape({ - key: PropTypes.string, - value: PropTypes.string, - }), - ), - lastSale: PropTypes.shape({ - timestamp: PropTypes.string, - orderSource: PropTypes.string, - price: PropTypes.shape({ - amount: PropTypes.shape({ - native: PropTypes.string, - decimal: PropTypes.string, - usd: PropTypes.string, - }), - currency: PropTypes.shape({ - symbol: PropTypes.string, - }), - }), - }), - topBid: PropTypes.shape({ - source: PropTypes.shape({ - id: PropTypes.string, - domain: PropTypes.string, - name: PropTypes.string, - icon: PropTypes.string, - url: PropTypes.string, - }), - price: PropTypes.shape({ - amount: PropTypes.shape({ - native: PropTypes.string, - decimal: PropTypes.string, - usd: PropTypes.string, - }), - currency: PropTypes.shape({ - symbol: PropTypes.string, - }), - }), - }), - collection: PropTypes.shape({ - openseaVerificationStatus: PropTypes.string, - tokenCount: PropTypes.string, - name: PropTypes.string, - ownerCount: PropTypes.string, - creator: PropTypes.string, - symbol: PropTypes.string, - contractDeployedAt: PropTypes.string, - floorAsk: PropTypes.shape({ - sourceDomain: PropTypes.string, - source: PropTypes.shape({ - id: PropTypes.string, - domain: PropTypes.string, - name: PropTypes.string, - icon: PropTypes.string, - url: PropTypes.string, - }), - price: PropTypes.shape({ - amount: PropTypes.shape({ - native: PropTypes.string, - decimal: PropTypes.string, - usd: PropTypes.string, - }), - currency: PropTypes.shape({ - symbol: PropTypes.string, - }), - }), - }), - topBid: PropTypes.shape({ - sourceDomain: PropTypes.string, - price: PropTypes.shape({ - amount: PropTypes.shape({ - native: PropTypes.string, - decimal: PropTypes.string, - usd: PropTypes.string, - }), - currency: PropTypes.shape({ - symbol: PropTypes.string, - }), - }), - }), - }), - }), -}; diff --git a/ui/components/app/assets/nfts/nft-grid/index.scss b/ui/components/app/assets/nfts/nft-grid/index.scss new file mode 100644 index 000000000000..22303aba159c --- /dev/null +++ b/ui/components/app/assets/nfts/nft-grid/index.scss @@ -0,0 +1,24 @@ +@use "design-system"; + +.nft-items { + &__wrapper { + grid-template-columns: repeat(4, minmax(120px, 1fr)); + + /* When used in the send NFT modal */ + .mm-modal-content & { + grid-template-columns: repeat(2, minmax(120px, 1fr)); + } + } + + @include design-system.screen-md-max { + &__wrapper { + grid-template-columns: repeat(3, minmax(100px, 1fr)); + } + } + + @include design-system.screen-sm-max { + &__wrapper { + grid-template-columns: repeat(3, minmax(85px, 1fr)); + } + } +} diff --git a/ui/components/app/assets/nfts/nft-grid/nft-grid.tsx b/ui/components/app/assets/nfts/nft-grid/nft-grid.tsx new file mode 100644 index 000000000000..626010dbea18 --- /dev/null +++ b/ui/components/app/assets/nfts/nft-grid/nft-grid.tsx @@ -0,0 +1,113 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { Hex } from '@metamask/utils'; +import { Display } from '../../../../../helpers/constants/design-system'; +import { Box } from '../../../../component-library'; +import Spinner from '../../../../ui/spinner'; +import { getNftImageAlt } from '../../../../../helpers/utils/nfts'; +import { NftItem } from '../../../../multichain/nft-item'; +import { NFT } from '../../../../multichain/asset-picker-amount/asset-picker-modal/types'; +import { + getCurrentNetwork, + getIpfsGateway, + getNftIsStillFetchingIndication, +} from '../../../../../selectors'; +import useGetAssetImageUrl from '../../../../../hooks/useGetAssetImageUrl'; + +const NFTGridItem = (props: { + nft: NFT; + onClick: () => void; + privacyMode?: boolean; + currentChain: { + chainId: Hex; + nickname: string; + rpcPrefs?: { + imageUrl: string; + }; + }; +}) => { + const { nft, onClick, privacyMode, currentChain } = props; + + const { image, imageOriginal } = nft; + + const ipfsGateway = useSelector(getIpfsGateway); + const nftImageURL = useGetAssetImageUrl( + imageOriginal ?? image ?? undefined, + ipfsGateway, + ); + + const isImageHosted = + image?.startsWith('https:') || image?.startsWith('http:'); + const nftItemSrc = isImageHosted ? image : nftImageURL; + + const nftImageAlt = getNftImageAlt(nft); + + const nftSrcUrl = imageOriginal ?? image; + const isIpfsURL = nftSrcUrl?.startsWith('ipfs:'); + + return ( + + ); +}; + +export default function NftGrid({ + nfts, + handleNftClick, + privacyMode, +}: { + nfts: NFT[]; + handleNftClick: (nft: NFT) => void; + privacyMode?: boolean; +}) { + const currentChain = useSelector(getCurrentNetwork) as { + chainId: Hex; + nickname: string; + rpcPrefs?: { imageUrl: string }; + }; + const nftsStillFetchingIndication = useSelector( + getNftIsStillFetchingIndication, + ); + + return ( + + + {nfts.map((nft: NFT) => { + const { tokenURI } = nft; + + return ( + + handleNftClick(nft)} + privacyMode={privacyMode} + /> + + ); + })} + {nftsStillFetchingIndication ? ( + + + + ) : null} + + + ); +} diff --git a/ui/components/app/assets/nfts/nft-options/nft-options.js b/ui/components/app/assets/nfts/nft-options/nft-options.js deleted file mode 100644 index 520d3a32c116..000000000000 --- a/ui/components/app/assets/nfts/nft-options/nft-options.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useContext, useRef, useState } from 'react'; -import PropTypes from 'prop-types'; - -import { I18nContext } from '../../../../../contexts/i18n'; -import { Menu, MenuItem } from '../../../../ui/menu'; -import { - ButtonIcon, - ButtonIconSize, - IconName, -} from '../../../../component-library'; -import { Color } from '../../../../../helpers/constants/design-system'; - -const NftOptions = ({ onRemove, onViewOnOpensea }) => { - const t = useContext(I18nContext); - const [nftOptionsOpen, setNftOptionsOpen] = useState(false); - const ref = useRef(false); - - return ( -
    - setNftOptionsOpen(true)} - color={Color.textDefault} - size={ButtonIconSize.Sm} - ariaLabel={t('nftOptions')} - /> - - {nftOptionsOpen ? ( - setNftOptionsOpen(false)} - > - {onViewOnOpensea ? ( - { - setNftOptionsOpen(false); - onViewOnOpensea(); - }} - > - {t('viewOnOpensea')} - - ) : null} - { - setNftOptionsOpen(false); - onRemove(); - }} - > - {t('removeNFT')} - - - ) : null} -
    - ); -}; - -NftOptions.propTypes = { - onRemove: PropTypes.func.isRequired, - onViewOnOpensea: PropTypes.func, -}; - -export default NftOptions; diff --git a/ui/components/app/assets/nfts/nft-options/nft-options.test.js b/ui/components/app/assets/nfts/nft-options/nft-options.test.js index 450206df7714..7d6652f3b9c7 100644 --- a/ui/components/app/assets/nfts/nft-options/nft-options.test.js +++ b/ui/components/app/assets/nfts/nft-options/nft-options.test.js @@ -7,6 +7,7 @@ describe('NFT Options Component', () => { const props = { onRemove: jest.fn(), onViewOnOpensea: jest.fn(), + showOpenSeaLink: true, }; it('should expand NFT options menu`', async () => { @@ -26,15 +27,14 @@ describe('NFT Options Component', () => { it('should expand and close menu options when clicked`', async () => { const { queryByTestId } = renderWithProvider(); - const openOptionMenuButton = queryByTestId('nft-options__button'); - - fireEvent.click(openOptionMenuButton); + const optionMenuToggle = queryByTestId('nft-options__button'); - const closeOptionMenuButton = queryByTestId('close-nft-options-menu'); + fireEvent.click(optionMenuToggle); + fireEvent.click(optionMenuToggle); - fireEvent.click(closeOptionMenuButton); + const nftItemRemove = queryByTestId('nft-item-remove'); - expect(closeOptionMenuButton).not.toBeInTheDocument(); + expect(nftItemRemove).not.toBeInTheDocument(); }); it('should click onRemove handler and close option menu', () => { @@ -44,8 +44,7 @@ describe('NFT Options Component', () => { fireEvent.click(openOptionMenuButton); - const removeNftButton = queryByTestId('nft-item-remove'); - + const removeNftButton = queryByTestId('nft-item-remove__button'); fireEvent.click(removeNftButton); expect(props.onRemove).toHaveBeenCalled(); @@ -60,10 +59,9 @@ describe('NFT Options Component', () => { fireEvent.click(openOptionMenuButton); - const openOpenSea = queryByTestId('nft-options__view-on-opensea'); + const openOpenSea = queryByTestId('nft-options__view-on-opensea__button'); fireEvent.click(openOpenSea); - expect(props.onViewOnOpensea).toHaveBeenCalled(); expect(removeNftButton).not.toBeInTheDocument(); }); diff --git a/ui/components/app/assets/nfts/nft-options/nft-options.tsx b/ui/components/app/assets/nfts/nft-options/nft-options.tsx new file mode 100644 index 000000000000..998ba90a7e42 --- /dev/null +++ b/ui/components/app/assets/nfts/nft-options/nft-options.tsx @@ -0,0 +1,89 @@ +import React, { useContext, useRef, useState } from 'react'; +import { I18nContext } from '../../../../../contexts/i18n'; +import { + Box, + ButtonIcon, + ButtonIconSize, + Icon, + IconName, + IconSize, + Popover, + PopoverPosition, +} from '../../../../component-library'; +import { IconColor } from '../../../../../helpers/constants/design-system'; +import { SelectableListItem } from '../../asset-list/sort-control/sort-control'; + +type NftOptionsProps = { + onRemove: () => void; + onViewOnOpensea?: () => void; + showOpenSeaLink: boolean; +}; + +const NftOptions = ({ + onRemove, + onViewOnOpensea, + showOpenSeaLink, +}: NftOptionsProps) => { + const t = useContext(I18nContext); + const [nftOptionsOpen, setNftOptionsOpen] = useState(false); + const ref = useRef(null); + + const closePopover = () => { + setNftOptionsOpen(false); + }; + + return ( + + setNftOptionsOpen(true)} + color={IconColor.iconDefault} + size={ButtonIconSize.Sm} + ariaLabel={t('nftOptions')} + /> + + {showOpenSeaLink ? ( + { + closePopover(); + onViewOnOpensea?.(); + }} + > + + {t('viewOnOpensea')} + + ) : null} + { + closePopover(); + onRemove?.(); + }} + > + + {t('removeNFT')} + + + + ); +}; + +export default NftOptions; diff --git a/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/index.js b/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/index.ts similarity index 100% rename from ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/index.js rename to ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/index.ts diff --git a/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.js b/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx similarity index 83% rename from ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.js rename to ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx index 90697c1535b9..1653e67b06e5 100644 --- a/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.js +++ b/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx @@ -5,7 +5,13 @@ import { BannerAlert } from '../../../../component-library'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { SECURITY_ROUTE } from '../../../../../helpers/constants/routes'; -export default function NftsDetectionNoticeImportNFTs({ onActionButtonClick }) { +type NftsDetectionNoticeImportNFTsProps = { + onActionButtonClick: () => void; +}; + +export default function NftsDetectionNoticeImportNFTs({ + onActionButtonClick, +}: NftsDetectionNoticeImportNFTsProps) { const t = useI18nContext(); const history = useHistory(); diff --git a/ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/index.js b/ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/index.ts similarity index 100% rename from ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/index.js rename to ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/index.ts diff --git a/ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/nfts-detection-notice-nfts-tab.js b/ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/nfts-detection-notice-nfts-tab.tsx similarity index 100% rename from ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/nfts-detection-notice-nfts-tab.js rename to ui/components/app/assets/nfts/nfts-detection-notice-nfts-tab/nfts-detection-notice-nfts-tab.tsx diff --git a/ui/components/app/assets/nfts/nfts-items/collection-image.component.test.tsx b/ui/components/app/assets/nfts/nfts-items/collection-image.component.test.tsx deleted file mode 100644 index 726ca26508b9..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/collection-image.component.test.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import { screen } from '@testing-library/react'; -import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; -import { getIpfsGateway, getOpenSeaEnabled } from '../../../../../selectors'; -import { CollectionImageComponent } from './collection-image.component'; - -jest.mock('react-redux', () => ({ - ...jest.requireActual('react-redux'), - useSelector: jest.fn(), -})); - -jest.mock('../../../../../selectors', () => ({ - ...jest.requireActual('../../../../../selectors'), - getIpfsGateway: jest.fn(), - getOpenSeaEnabled: jest.fn(), -})); -const mockStore = configureMockStore([thunk])(mockState); -describe('CollectionImageComponent', () => { - const useSelectorMock = useSelector as jest.Mock; - beforeEach(() => { - jest.resetAllMocks(); - }); - it('should show collection first letter when ipfs is not enabled', async () => { - useSelectorMock.mockImplementation((selector) => { - if (selector === getIpfsGateway) { - return undefined; - } - return undefined; - }); - - const props = { - collectionName: 'NFT Collection', - collectionImage: 'ipfs://', - }; - - const { getByText } = renderWithProvider( - , - mockStore, - ); - - expect(getByText('N')).toBeInTheDocument(); - }); - - it('should show collection first letter when opensea is not enabled', async () => { - useSelectorMock.mockImplementation((selector) => { - if (selector === getOpenSeaEnabled) { - return false; - } - return undefined; - }); - - const props = { - collectionName: 'Test NFT Collection', - collectionImage: 'https://image.png', - }; - - const { getByText } = renderWithProvider( - , - mockStore, - ); - - expect(getByText('T')).toBeInTheDocument(); - }); - - it('should show collection image', async () => { - useSelectorMock.mockImplementation((selector) => { - if (selector === getOpenSeaEnabled) { - return true; - } - return undefined; - }); - - const props = { - collectionName: 'Test NFT Collection', - collectionImage: 'https://image.png', - }; - - renderWithProvider(, mockStore); - - expect(screen.getAllByRole('img')).toHaveLength(1); - }); -}); diff --git a/ui/components/app/assets/nfts/nfts-items/collection-image.component.tsx b/ui/components/app/assets/nfts/nfts-items/collection-image.component.tsx deleted file mode 100644 index 24f34714dd95..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/collection-image.component.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; - -import { useSelector } from 'react-redux'; - -import { getIpfsGateway, getOpenSeaEnabled } from '../../../../../selectors'; -import useGetAssetImageUrl from '../../../../../hooks/useGetAssetImageUrl'; -import { Box } from '../../../../component-library'; - -export const CollectionImageComponent = ({ - collectionImage, - collectionName, -}: { - collectionImage: string; - collectionName: string; -}) => { - const ipfsGateway = useSelector(getIpfsGateway); - const openSeaEnabled = useSelector(getOpenSeaEnabled); - const nftImageURL = useGetAssetImageUrl(collectionImage, ipfsGateway); - - const renderCollectionImage = () => { - if (collectionImage?.startsWith('ipfs') && !ipfsGateway) { - return ( -
    - {collectionName?.[0]?.toUpperCase() ?? null} -
    - ); - } - if (!openSeaEnabled && !collectionImage?.startsWith('ipfs')) { - return ( -
    - {collectionName?.[0]?.toUpperCase() ?? null} -
    - ); - } - - if (collectionImage) { - return ( - {collectionName} - ); - } - return ( -
    - {collectionName?.[0]?.toUpperCase() ?? null} -
    - ); - }; - - return {renderCollectionImage()}; -}; diff --git a/ui/components/app/assets/nfts/nfts-items/index.js b/ui/components/app/assets/nfts/nfts-items/index.js deleted file mode 100644 index e0428c09b332..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './nfts-items'; diff --git a/ui/components/app/assets/nfts/nfts-items/index.scss b/ui/components/app/assets/nfts/nfts-items/index.scss deleted file mode 100644 index f8d7839fb200..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/index.scss +++ /dev/null @@ -1,58 +0,0 @@ -.nfts-items { - &__collection { - margin-bottom: 24px; - - &:last-child { - margin-bottom: 0; - } - - &-accordion-title { - cursor: pointer; - } - - &-wrapper { - background-color: transparent; - border: 0; - width: 100%; - } - - &-image { - width: 32px; - height: 32px; - border-radius: 50%; - } - - &-image-alt { - border-radius: 50%; - width: 32px; - height: 32px; - padding: 8px; - background: var(--color-overlay-alternative); - color: var(--color-overlay-inverse); - text-align: center; - } - } - - &__item-wrapper { - align-self: center; - - &__card { - overflow: hidden; - } - } - - &__item { - width: 100%; - display: flex; - justify-content: center; - cursor: pointer; - align-self: center; - padding: 0; - - &-image { - width: 100%; - height: 100%; - cursor: pointer; - } - } -} diff --git a/ui/components/app/assets/nfts/nfts-items/nfts-items.js b/ui/components/app/assets/nfts/nfts-items/nfts-items.js deleted file mode 100644 index 990477e6fc89..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/nfts-items.js +++ /dev/null @@ -1,397 +0,0 @@ -import React, { useContext, useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; -import { useDispatch, useSelector } from 'react-redux'; -import { useHistory } from 'react-router-dom'; -import { isEqual } from 'lodash'; -import Box from '../../../../ui/box'; -import Typography from '../../../../ui/typography/typography'; -import { - Color, - TypographyVariant, - JustifyContent, - FLEX_DIRECTION, - AlignItems, - DISPLAY, - BLOCK_SIZES, - FLEX_WRAP, -} from '../../../../../helpers/constants/design-system'; -import { ENVIRONMENT_TYPE_POPUP } from '../../../../../../shared/constants/app'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'; -import { getCurrentChainId } from '../../../../../../shared/modules/selectors/networks'; -import { - getIpfsGateway, - getSelectedInternalAccount, - getCurrentNetwork, -} from '../../../../../selectors'; -import { - ASSET_ROUTE, - SEND_ROUTE, -} from '../../../../../helpers/constants/routes'; -import { getAssetImageURL } from '../../../../../helpers/utils/util'; -import { getNftImageAlt } from '../../../../../helpers/utils/nfts'; -import { updateNftDropDownState } from '../../../../../store/actions'; -import { usePrevious } from '../../../../../hooks/usePrevious'; -import { getNftsDropdownState } from '../../../../../ducks/metamask/metamask'; -import { useI18nContext } from '../../../../../hooks/useI18nContext'; -import { Icon, IconName, Text } from '../../../../component-library'; -import { NftItem } from '../../../../multichain/nft-item'; -import { - getSendAnalyticProperties, - updateSendAsset, -} from '../../../../../ducks/send'; -import { AssetType } from '../../../../../../shared/constants/transaction'; -import { MetaMetricsContext } from '../../../../../contexts/metametrics'; -import { - MetaMetricsEventCategory, - MetaMetricsEventName, -} from '../../../../../../shared/constants/metametrics'; -import { isEqualCaseInsensitive } from '../../../../../../shared/modules/string-utils'; -import { CollectionImageComponent } from './collection-image.component'; - -const width = (isModal) => { - const env = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP; - - if (isModal) { - return BLOCK_SIZES.ONE_THIRD; - } - if (env === ENVIRONMENT_TYPE_POPUP) { - return BLOCK_SIZES.ONE_THIRD; - } - return BLOCK_SIZES.ONE_SIXTH; -}; - -const PREVIOUSLY_OWNED_KEY = 'previouslyOwned'; - -export default function NftsItems({ - collections = {}, - previouslyOwnedCollection = {}, - isModal = false, - onCloseModal = {}, - showTokenId = false, - displayPreviouslyOwnedCollection = true, -}) { - const dispatch = useDispatch(); - const collectionsKeys = Object.keys(collections); - const nftsDropdownState = useSelector(getNftsDropdownState); - const previousCollectionKeys = usePrevious(collectionsKeys); - const { address: selectedAddress } = useSelector(getSelectedInternalAccount); - const chainId = useSelector(getCurrentChainId); - const currentChain = useSelector(getCurrentNetwork); - const t = useI18nContext(); - const ipfsGateway = useSelector(getIpfsGateway); - - const [updatedNfts, setUpdatedNfts] = useState([]); - - const trackEvent = useContext(MetaMetricsContext); - const sendAnalytics = useSelector(getSendAnalyticProperties); - - useEffect(() => { - if ( - chainId !== undefined && - selectedAddress !== undefined && - !isEqual(previousCollectionKeys, collectionsKeys) && - (nftsDropdownState?.[selectedAddress]?.[chainId] === undefined || - Object.keys(nftsDropdownState?.[selectedAddress]?.[chainId]).length === - 0) - ) { - const initState = {}; - collectionsKeys.forEach((key) => { - initState[key] = true; - }); - - const newNftDropdownState = { - ...nftsDropdownState, - [selectedAddress]: { - ...nftsDropdownState?.[selectedAddress], - [chainId]: initState, - }, - }; - - dispatch(updateNftDropDownState(newNftDropdownState)); - } - }, [ - collectionsKeys, - previousCollectionKeys, - nftsDropdownState, - selectedAddress, - chainId, - dispatch, - ]); - - const getAssetImageUrlAndUpdate = async (image, nft) => { - const nftImage = await getAssetImageURL(image, ipfsGateway); - const updatedNFt = { - ...nft, - ipfsImageUpdated: nftImage, - }; - return updatedNFt; - }; - - useEffect(() => { - const promisesArr = []; - const modifyItems = async () => { - for (const key of collectionsKeys) { - const { nfts } = collections[key]; - for (const singleNft of nfts) { - const { image, imageOriginal } = singleNft; - - const isImageHosted = - image?.startsWith('https:') || image?.startsWith('http:'); - if (!isImageHosted) { - promisesArr.push( - getAssetImageUrlAndUpdate(imageOriginal ?? image, singleNft), - ); - } - } - } - const settled = await Promise.all(promisesArr); - setUpdatedNfts(settled); - }; - - modifyItems(); - }, []); - - const history = useHistory(); - - const updateNftDropDownStateKey = (key, isExpanded) => { - const newCurrentAccountState = { - ...nftsDropdownState?.[selectedAddress]?.[chainId], - [key]: !isExpanded, - }; - - const newState = { - ...nftsDropdownState, - [selectedAddress]: { - [chainId]: newCurrentAccountState, - }, - }; - - dispatch(updateNftDropDownState(newState)); - }; - - const onSendNft = async (nft) => { - trackEvent( - { - event: MetaMetricsEventName.sendAssetSelected, - category: MetaMetricsEventCategory.Send, - properties: { - is_destination_asset_picker_modal: false, - is_nft: true, - }, - sensitiveProperties: { - ...sendAnalytics, - new_asset_symbol: nft.name, - new_asset_address: nft.address, - }, - }, - { excludeMetaMetricsId: false }, - ); - await dispatch( - updateSendAsset({ - type: AssetType.NFT, - details: nft, - skipComputeEstimatedGasLimit: false, - }), - ); - history.push(SEND_ROUTE); - onCloseModal(); - }; - - const renderCollection = ({ nfts, collectionName, collectionImage, key }) => { - if (!nfts.length) { - return null; - } - const getSource = (isImageHosted, nft) => { - if (!isImageHosted) { - const found = updatedNfts.find( - (elm) => - elm.tokenId === nft.tokenId && - isEqualCaseInsensitive(elm.address, nft.address), - ); - if (found) { - return found.ipfsImageUpdated; - } - } - return nft.image; - }; - - const isExpanded = nftsDropdownState[selectedAddress]?.[chainId]?.[key]; - return ( -
    - - - {isExpanded ? ( - - {nfts.map((nft, i) => { - const { image, address, tokenId, name, imageOriginal, tokenURI } = - nft; - const nftImageAlt = getNftImageAlt(nft); - const isImageHosted = - image?.startsWith('https:') || image?.startsWith('http:'); - - const source = getSource(isImageHosted, nft); - - const isIpfsURL = ( - imageOriginal ?? - image ?? - tokenURI - )?.startsWith('ipfs:'); - const handleImageClick = () => { - if (isModal) { - return onSendNft(nft); - } - return history.push( - `${ASSET_ROUTE}/${currentChain.chainId}/${address}/${tokenId}`, - ); - }; - return ( - - - {showTokenId ? {`${t('id')}: ${tokenId}`} : null} - - ); - })} - - ) : null} -
    - ); - }; - - return ( -
    - - <> - {collectionsKeys.map((key) => { - const { nfts, collectionName, collectionImage } = collections[key]; - - return renderCollection({ - nfts, - collectionName, - collectionImage, - key, - isPreviouslyOwnedCollection: false, - }); - })} - {displayPreviouslyOwnedCollection - ? renderCollection({ - nfts: previouslyOwnedCollection.nfts, - collectionName: previouslyOwnedCollection.collectionName, - collectionImage: previouslyOwnedCollection.nfts[0]?.image, - isPreviouslyOwnedCollection: true, - key: PREVIOUSLY_OWNED_KEY, - }) - : null} - - -
    - ); -} - -NftsItems.propTypes = { - previouslyOwnedCollection: PropTypes.shape({ - nfts: PropTypes.arrayOf( - PropTypes.shape({ - address: PropTypes.string.isRequired, - tokenId: PropTypes.string.isRequired, - name: PropTypes.string, - description: PropTypes.string, - image: PropTypes.string, - standard: PropTypes.string, - imageThumbnail: PropTypes.string, - imagePreview: PropTypes.string, - creator: PropTypes.shape({ - address: PropTypes.string, - config: PropTypes.string, - profile_img_url: PropTypes.string, - }), - }), - ), - collectionName: PropTypes.string, - collectionImage: PropTypes.string, - }), - collections: PropTypes.shape({ - nfts: PropTypes.arrayOf( - PropTypes.shape({ - address: PropTypes.string.isRequired, - tokenId: PropTypes.string.isRequired, - name: PropTypes.string, - description: PropTypes.string, - image: PropTypes.string, - standard: PropTypes.string, - imageThumbnail: PropTypes.string, - imagePreview: PropTypes.string, - creator: PropTypes.shape({ - address: PropTypes.string, - config: PropTypes.string, - profile_img_url: PropTypes.string, - }), - }), - ), - collectionImage: PropTypes.string, - collectionName: PropTypes.string, - }), - isModal: PropTypes.bool, - onCloseModal: PropTypes.func, - showTokenId: PropTypes.bool, - displayPreviouslyOwnedCollection: PropTypes.bool, -}; diff --git a/ui/components/app/assets/nfts/nfts-items/nfts-items.stories.tsx b/ui/components/app/assets/nfts/nfts-items/nfts-items.stories.tsx deleted file mode 100644 index f13af8c13ea4..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/nfts-items.stories.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react'; -import { Provider } from 'react-redux'; -import configureStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import type { Meta, StoryObj } from '@storybook/react'; -import NftsItems from './nfts-items'; -import { mockNetworkState } from '../../../../../../test/stub/networks'; -import { CHAIN_IDS } from '../../../../../../shared/constants/network'; - - -// Custom middleware to ensure actions are plain objects -const ensurePlainObjectMiddleware = () => (next) => (action) => { - if (typeof action === 'function') { - return next(action()); - } - return next(action); -}; - -const mockStore = configureStore([thunk, ensurePlainObjectMiddleware]); - -const createMockState = () => ({ - metamask: { - nftsDropdownState: { - '0x123': { - '0x1': { - '0x123': true, // This sets isExpanded to true for the specific collection - previouslyOwned: true, // Expanded previously owned collection - }, - }, - }, - selectedAddress: '0x123', - selectedAccount: { - address: '0x123', - id: 'selected-account-id', - balance: '0x0', - name: 'Account 1', - }, - internalAccounts: { - selectedAccount: 'selected-account-id', - accounts: { - 'selected-account-id': { - address: '0x123', - id: 'selected-account-id', - balance: '0x0', - name: 'Account 1', - metadata: { - keyring: { - type: 'HD Key Tree', - }, - }, - }, - }, - }, - accounts: { - '0x123': { - address: '0x123', - balance: '0x0', - }, - }, - identities: { - '0x123': { - address: '0x123', - name: 'Account 1', - }, - }, - chainId: '0x1', - ipfsGateway: 'https://ipfs.io/ipfs/', - openSeaEnabled: true, - nativeCurrency: 'ETH', - currentCurrency: 'usd', - provider: { - type: 'mainnet', - chainId: '0x1', - nickname: 'Ethereum Mainnet', - }, - network: '1', - nftContracts: [], - nfts: [], - ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }), - useRequestQueue: true, - }, - appState: { - isLoading: false, - }, - send: { - currentTransactionUUID: '0x123', - draftTransactions: { - '0x123': { - id: '0x123', - status: 'unapproved', - time: Date.now(), - txParams: { - from: '0x123', - to: '0x456', - value: '0x0', - gas: '0x5208', - gasPrice: '0x3b9aca00', - }, - type: 'standard', - }, - }, - }, -}); - -const mockCollections = { - '0x123': { - nfts: [ - { - address: '0x123', - tokenId: '1', - name: 'NFT 1', - description: 'This is NFT 1', - image: './catnip-spicywright.png', - standard: 'ERC721', - }, - { - address: '0x123', - tokenId: '2', - name: 'NFT 2', - description: 'This is NFT 2', - image: './catnip-spicywright.png', - standard: 'ERC721', - }, - ], - collectionName: 'Test Collection', - collectionImage: './catnip-spicywright.png', - }, -}; - -const meta: Meta = { - title: 'Components/App/Assets/NFTs/NftsItems', - component: NftsItems, - decorators: [ - (Story) => { - const store = mockStore(createMockState()); - const originalDispatch = store.dispatch; - store.dispatch = ((action: any) => { - if (typeof action === 'function') { - return action(originalDispatch, store.getState); - } - return originalDispatch(action); - }) as typeof store.dispatch; - return ( - - - - ); - }, - ], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - collections: mockCollections, - previouslyOwnedCollection: { nfts: [] }, - }, -}; - -export const Modal: Story = { - args: { - ...Default.args, - isModal: true, - }, -}; - -export const WithPreviouslyOwnedCollection: Story = { - args: { - ...Default.args, - previouslyOwnedCollection: { - nfts: [ - { - address: '0x456', - tokenId: '3', - name: 'Previously Owned NFT', - description: 'This is a previously owned NFT', - image: './catnip-spicywright.png', - standard: 'ERC721', - }, - ], - collectionName: 'Previously Owned', - }, - }, -}; diff --git a/ui/components/app/assets/nfts/nfts-items/nfts-items.test.js b/ui/components/app/assets/nfts/nfts-items/nfts-items.test.js deleted file mode 100644 index 0eebd960c100..000000000000 --- a/ui/components/app/assets/nfts/nfts-items/nfts-items.test.js +++ /dev/null @@ -1,101 +0,0 @@ -import React from 'react'; -import { fireEvent } from '@testing-library/react'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import { toHex } from '@metamask/controller-utils'; -import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; -import { updateNftDropDownState } from '../../../../../store/actions'; -import { getSelectedInternalAccountFromMockState } from '../../../../../../test/jest/mocks'; -import NftsItems from '.'; - -const mockHistoryPush = jest.fn(); - -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useLocation: jest.fn(() => ({ search: '' })), - useHistory: () => ({ - push: mockHistoryPush, - }), -})); - -jest.mock('../../../../../store/actions.ts', () => ({ - ...jest.requireActual('../../../../../store/actions.ts'), - updateNftDropDownState: jest.fn().mockReturnValue(jest.fn()), -})); - -const mockSelectedInternalAccount = - getSelectedInternalAccountFromMockState(mockState); - -describe('NFTs Item Component', () => { - const nfts = - mockState.metamask.allNfts[mockSelectedInternalAccount.address][toHex(5)]; - const props = { - collections: { - '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { - nfts, - collectionImage: '', - collectionName: 'NFT Collection', - }, - }, - previouslyOwnedCollection: { - nfts: [], - }, - }; - - const mockStore = configureMockStore([thunk])(mockState); - - it('should expand NFT collection showing individual NFTs', async () => { - const { queryByTestId, queryAllByTestId } = renderWithProvider( - , - mockStore, - ); - - const collectionExpanderButton = queryByTestId( - 'collection-expander-button', - ); - - expect(queryAllByTestId('nft-wrapper')).toHaveLength(0); - - fireEvent.click(collectionExpanderButton); - - const expectedParams = { - '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': { - '0x5': { - '0x495f947276749Ce646f68AC8c248420045cb7b5e': false, - '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': true, - }, - }, - }; - - expect(updateNftDropDownState).toHaveBeenCalledWith(expectedParams); - - // Force rerender component with state/store update - mockState.metamask.nftsDropdownState = expectedParams; - renderWithProvider(, mockStore); - - expect(queryAllByTestId('nft-wrapper')).toHaveLength(8); - }); - - it('should NFT click image', () => { - const { queryAllByTestId } = renderWithProvider( - , - mockStore, - ); - - const nftImages = queryAllByTestId('nft-image'); - const nftDefaultImages = queryAllByTestId('nft-default-image'); - if (nftImages.length) { - fireEvent.click(nftImages[0]); - } else { - fireEvent.click(nftDefaultImages[0]); - } - - const firstNft = nfts[0]; - const nftRoute = `/asset/${toHex(5)}/${firstNft.address}/${ - firstNft.tokenId - }`; - - expect(mockHistoryPush).toHaveBeenCalledWith(nftRoute); - }); -}); diff --git a/ui/components/app/assets/nfts/nfts-tab/index.scss b/ui/components/app/assets/nfts/nfts-tab/index.scss deleted file mode 100644 index 44c20656d417..000000000000 --- a/ui/components/app/assets/nfts/nfts-tab/index.scss +++ /dev/null @@ -1,17 +0,0 @@ -.nfts-tab { - &__fetching { - display: flex; - height: 100px; - align-items: center; - justify-content: center; - padding: 30px; - } - - &__loading { - display: flex; - height: 200px; - align-items: center; - justify-content: center; - padding: 30px; - } -} diff --git a/ui/components/app/assets/nfts/nfts-tab/index.js b/ui/components/app/assets/nfts/nfts-tab/index.ts similarity index 100% rename from ui/components/app/assets/nfts/nfts-tab/index.js rename to ui/components/app/assets/nfts/nfts-tab/index.ts diff --git a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.test.js b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.test.js index 52acdbcd84f4..ee694da48fca 100644 --- a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.test.js +++ b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.test.js @@ -133,20 +133,6 @@ const NFTS = [ }, ]; -const NFTS_CONTRACTS = [ - { - address: '0x495f947276749Ce646f68AC8c248420045cb7b5e', - name: 'PUNKS', - symbol: 'PNKS', - schemaName: 'ERC1155', - }, - { - address: '0xDc7382Eb0Bc9C352A4CbA23c909bDA01e0206414', - name: 'Munks', - symbol: 'MNKS', - }, -]; - const nftsDropdownState = { '0x495f947276749ce646f68ac8c248420045cb7b5e': true, '0xdc7382eb0bc9c352a4cba23c909bda01e0206414': true, @@ -312,27 +298,6 @@ describe('NFT Items', () => { }); }); - describe('Collections', () => { - it('should render the name of the collections and number of NFTs in each collection if current account/chainId combination has NFTs', () => { - render({ - selectedAddress: ACCOUNT_1, - nfts: NFTS, - nftContracts: NFTS_CONTRACTS, - }); - expect(screen.queryByText('PUNKS (5)')).toBeInTheDocument(); - expect(screen.queryByText('Munks (3)')).toBeInTheDocument(); - }); - it('should not render collections if current account/chainId combination has NFTs', () => { - render({ - selectedAddress: ACCOUNT_2, - nfts: NFTS, - nftContracts: NFTS_CONTRACTS, - }); - expect(screen.queryByText('PUNKS (5)')).not.toBeInTheDocument(); - expect(screen.queryByText('Munks (3)')).not.toBeInTheDocument(); - }); - }); - describe('NFTs options', () => { it('should render a link "Refresh list" when some NFTs are present on mainnet and NFT auto-detection preference is set to true, which, when clicked calls methods DetectNFTs and checkAndUpdateNftsOwnershipStatus', () => { render({ diff --git a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.js b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx similarity index 50% rename from ui/components/app/assets/nfts/nfts-tab/nfts-tab.js rename to ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx index 2a9f3287346e..3faae7c68e16 100644 --- a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.js +++ b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx @@ -1,17 +1,16 @@ import React, { useContext, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import { Hex } from '@metamask/utils'; import { AlignItems, Display, FlexDirection, JustifyContent, - Size, TextAlign, TextColor, TextVariant, } from '../../../../../helpers/constants/design-system'; -import { SECURITY_ROUTE } from '../../../../../helpers/constants/routes'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useNftsCollections } from '../../../../../hooks/useNftsCollections'; import { @@ -19,18 +18,16 @@ import { getIsMainnet, getUseNftDetection, getNftIsStillFetchingIndication, + getPreferences, } from '../../../../../selectors'; import { - checkAndUpdateAllNftsOwnershipStatus, - detectNfts, - showImportNftsModal, -} from '../../../../../store/actions'; -import { Box, ButtonLink, IconName, Text } from '../../../../component-library'; + Box, + ButtonLink, + ButtonLinkSize, + IconName, + Text, +} from '../../../../component-library'; import NFTsDetectionNoticeNFTsTab from '../nfts-detection-notice-nfts-tab/nfts-detection-notice-nfts-tab'; -import NftsItems from '../nfts-items'; -///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) -import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url'; -///: END:ONLY_INCLUDE_IF import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { ORIGIN_METAMASK } from '../../../../../../shared/constants/app'; import { @@ -40,31 +37,43 @@ import { import { getCurrentLocale } from '../../../../../ducks/locale/locale'; import Spinner from '../../../../ui/spinner'; import { endTrace, TraceName } from '../../../../../../shared/lib/trace'; +import { useNfts } from '../../../../../hooks/useNfts'; +import { NFT } from '../../../../multichain/asset-picker-amount/asset-picker-modal/types'; +import { + checkAndUpdateAllNftsOwnershipStatus, + detectNfts, + showImportNftsModal, +} from '../../../../../store/actions'; +import { + ASSET_ROUTE, + SECURITY_ROUTE, +} from '../../../../../helpers/constants/routes'; +import NftGrid from '../nft-grid/nft-grid'; +///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) +import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url'; +///: END:ONLY_INCLUDE_IF +import { sortAssets } from '../../util/sort'; export default function NftsTab() { + const history = useHistory(); + const dispatch = useDispatch(); const useNftDetection = useSelector(getUseNftDetection); const isMainnet = useSelector(getIsMainnet); - const history = useHistory(); + const { privacyMode } = useSelector(getPreferences); const t = useI18nContext(); - const dispatch = useDispatch(); const trackEvent = useContext(MetaMetricsContext); const nftsStillFetchingIndication = useSelector( getNftIsStillFetchingIndication, ); - - const { nftsLoading, collections, previouslyOwnedCollection } = - useNftsCollections(); - - const onEnableAutoDetect = () => { - history.push(SECURITY_ROUTE); + const currentChain = useSelector(getCurrentNetwork) as { + chainId: Hex; + nickname: string; + rpcPrefs?: { imageUrl: string }; }; - const onRefresh = () => { - if (isMainnet) { - dispatch(detectNfts()); - } - checkAndUpdateAllNftsOwnershipStatus(); - }; + const { nftsLoading, collections } = useNftsCollections(); + + const { currentlyOwnedNfts, previouslyOwnedNfts } = useNfts(); const hasAnyNfts = Object.keys(collections).length > 0; const showNftBanner = hasAnyNfts === false; @@ -100,6 +109,29 @@ export default function NftsTab() { } }, [nftsLoading, nftsStillFetchingIndication]); + const handleNftClick = (nft: NFT) => { + history.push( + `${ASSET_ROUTE}/${currentChain.chainId}/${nft.address}/${nft.tokenId}`, + ); + }; + + const onEnableAutoDetect = () => { + history.push(SECURITY_ROUTE); + }; + + const onRefresh = () => { + if (isMainnet) { + dispatch(detectNfts()); + } + checkAndUpdateAllNftsOwnershipStatus(); + }; + + const sortedNfts = sortAssets(currentlyOwnedNfts, { + key: 'collection.name', + order: 'asc', + sortCallback: 'alphaNumeric', + }); + if (!hasAnyNfts && nftsStillFetchingIndication) { return ( @@ -119,21 +151,62 @@ export default function NftsTab() { ) : null} - {hasAnyNfts > 0 || previouslyOwnedCollection.nfts.length > 0 ? ( + {hasAnyNfts || previouslyOwnedNfts.length > 0 ? ( - + + { + dispatch(showImportNftsModal({})); + }} + > + {t('importNFT')} + - {nftsStillFetchingIndication ? ( - - - - ) : null} + {!isMainnet && Object.keys(collections).length < 1 ? null : ( + <> + + {isMainnet && !useNftDetection ? ( + + {t('enableAutoDetect')} + + ) : ( + + {t('refreshList')} + + )} + + + )} + ) : ( <> @@ -159,7 +232,7 @@ export default function NftsTab() { {t('noNFTs')} @@ -167,7 +240,7 @@ export default function NftsTab() { { ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) @@ -177,56 +250,57 @@ export default function NftsTab() { }
    - - )} - - { - dispatch(showImportNftsModal()); - }} - > - {t('importNFT')} - - {!isMainnet && Object.keys(collections).length < 1 ? null : ( - <> - + { + dispatch(showImportNftsModal({})); + }} > - {isMainnet && !useNftDetection ? ( - - {t('enableAutoDetect')} - - ) : ( - + + {!isMainnet && Object.keys(collections).length < 1 ? null : ( + <> + - {t('refreshList')} - - )} - - - )} - + {isMainnet && !useNftDetection ? ( + + {t('enableAutoDetect')} + + ) : ( + + {t('refreshList')} + + )} + + + )} + + + )} ); diff --git a/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap b/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap index 7fb51f212ebd..3ec0face8295 100644 --- a/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap +++ b/ui/components/app/assets/token-cell/__snapshots__/token-cell.test.tsx.snap @@ -28,7 +28,7 @@ exports[`Token Cell should match snapshot 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    network logo = ({ {copyEnabled && ( )} @@ -130,7 +130,6 @@ export const ConfirmInfoRow: React.FC = ({ cursor: 'pointer', position: 'absolute', right: 8, - top: 4, }} onClick={() => setExpanded(!expanded)} data-testid="sectionCollapseButton" diff --git a/ui/components/app/confirm/info/row/url.tsx b/ui/components/app/confirm/info/row/url.tsx index 807fc7298042..cc517880bb42 100644 --- a/ui/components/app/confirm/info/row/url.tsx +++ b/ui/components/app/confirm/info/row/url.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useState } from 'react'; +import { isSnapId } from '@metamask/snaps-utils'; import { Box, Icon, @@ -18,7 +19,6 @@ import { } from '../../../../../helpers/constants/design-system'; import SnapAuthorshipPill from '../../../snaps/snap-authorship-pill'; import { SnapMetadataModal } from '../../../snaps/snap-metadata-modal'; -import { isSnapId } from '../../../../../helpers/utils/snaps'; export type ConfirmInfoRowUrlProps = { url: string; diff --git a/ui/components/app/confirm/info/row/value-double.tsx b/ui/components/app/confirm/info/row/value-double.tsx index b58016541c07..092ffe5ef7dd 100644 --- a/ui/components/app/confirm/info/row/value-double.tsx +++ b/ui/components/app/confirm/info/row/value-double.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { ReactNode } from 'react'; import { Box, Text } from '../../../../component-library'; import { AlignItems, @@ -12,8 +12,8 @@ import { useRowContext } from './hook'; import { ConfirmInfoRowVariant } from './row'; export type ConfirmInfoRowValueDoubleProps = { - left: string; - right: string; + left: ReactNode; + right: ReactNode; }; const LEFT_TEXT_COLORS = { @@ -35,8 +35,16 @@ export const ConfirmInfoRowValueDouble = ({ flexWrap={FlexWrap.Wrap} gap={1} > - {left} - {right} + {typeof left === 'string' ? ( + {left} + ) : ( + left + )} + {typeof right === 'string' ? ( + {right} + ) : ( + right + )} ); }; diff --git a/ui/components/app/connected-sites-list/connected-sites-list.component.js b/ui/components/app/connected-sites-list/connected-sites-list.component.js index d3b6cffa03fb..edb9ef4aaf50 100644 --- a/ui/components/app/connected-sites-list/connected-sites-list.component.js +++ b/ui/components/app/connected-sites-list/connected-sites-list.component.js @@ -1,11 +1,11 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { isSnapId } from '@metamask/snaps-utils'; import Button from '../../ui/button'; import { AvatarFavicon, IconSize } from '../../component-library'; import { stripHttpsSchemeWithoutPort } from '../../../helpers/utils/util'; import SiteOrigin from '../../ui/site-origin'; import { Size } from '../../../helpers/constants/design-system'; -import { isSnapId } from '../../../helpers/utils/snaps'; import { SnapIcon } from '../snaps/snap-icon'; export default class ConnectedSitesList extends Component { diff --git a/ui/components/app/contact-list/utils.ts b/ui/components/app/contact-list/utils.ts index 4254988e4af6..fe40d3fd6437 100644 --- a/ui/components/app/contact-list/utils.ts +++ b/ui/components/app/contact-list/utils.ts @@ -1,5 +1,5 @@ import { AddressBookEntry } from '@metamask/address-book-controller'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; export const buildDuplicateContactMap = ( addressBook: AddressBookEntry[], diff --git a/ui/components/app/currency-input/currency-input.js b/ui/components/app/currency-input/currency-input.js index 83bd3c2edce8..e16d95b8bfb7 100644 --- a/ui/components/app/currency-input/currency-input.js +++ b/ui/components/app/currency-input/currency-input.js @@ -5,12 +5,15 @@ import { Box } from '../../component-library'; import { BlockSize } from '../../../helpers/constants/design-system'; import UnitInput from '../../ui/unit-input'; import CurrencyDisplay from '../../ui/currency-display'; -import { getNativeCurrency } from '../../../ducks/metamask/metamask'; +import { + getNativeCurrency, + getCurrentCurrency, +} from '../../../ducks/metamask/metamask'; import { getProviderConfig, getCurrentChainId, } from '../../../../shared/modules/selectors/networks'; -import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors'; +import { getShouldShowFiat } from '../../../selectors'; import { EtherDenomination } from '../../../../shared/constants/common'; import { Numeric } from '../../../../shared/modules/Numeric'; import { useIsOriginalNativeTokenSymbol } from '../../../hooks/useIsOriginalNativeTokenSymbol'; diff --git a/ui/components/app/detected-token/detected-token-details/detected-token-details.js b/ui/components/app/detected-token/detected-token-details/detected-token-details.js index 9882fbce4819..c23aa98f9cd8 100644 --- a/ui/components/app/detected-token/detected-token-details/detected-token-details.js +++ b/ui/components/app/detected-token/detected-token-details/detected-token-details.js @@ -43,6 +43,7 @@ const DetectedTokenDetails = ({ src={CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP[chainId]} name={currentNetwork?.nickname || ''} backgroundColor={testNetworkBackgroundColor} + borderWidth={2} /> } marginRight={2} diff --git a/ui/components/app/home-notification/index.scss b/ui/components/app/home-notification/index.scss index ec997e00e3aa..647dc7314d0d 100644 --- a/ui/components/app/home-notification/index.scss +++ b/ui/components/app/home-notification/index.scss @@ -10,10 +10,9 @@ border-radius: 8px; min-height: 116px; padding: 16px; + width: calc(100% - 16px); + max-width: 472px; - @include design-system.screen-sm-min { - min-width: 472px; - } &__content-container { display: flex; diff --git a/ui/components/app/metamask-template-renderer/safe-component-list.js b/ui/components/app/metamask-template-renderer/safe-component-list.js index 03f8625733b9..b15bff11247c 100644 --- a/ui/components/app/metamask-template-renderer/safe-component-list.js +++ b/ui/components/app/metamask-template-renderer/safe-component-list.js @@ -1,83 +1,113 @@ -import Button from '../../ui/button'; -import Chip from '../../ui/chip'; -import DefinitionList from '../../ui/definition-list'; -import TruncatedDefinitionList from '../../ui/truncated-definition-list'; -import Popover from '../../ui/popover'; -import Typography from '../../ui/typography'; -import Box from '../../ui/box'; -import MetaMaskTranslation from '../metamask-translation'; -import NetworkDisplay from '../network-display'; -import TextArea from '../../ui/textarea/textarea'; -import TextField from '../../ui/text-field'; import ConfirmationNetworkSwitch from '../../../pages/confirmations/confirmation/components/confirmation-network-switch'; -import UrlIcon from '../../ui/url-icon'; -import Tooltip from '../../ui/tooltip/tooltip'; +import { SmartTransactionStatusPage } from '../../../pages/smart-transactions/smart-transaction-status-page'; import { AvatarIcon, + BannerAlert, FormTextField, Text, - BannerAlert, } from '../../component-library'; -import ActionableMessage from '../../ui/actionable-message/actionable-message'; import { AccountListItem } from '../../multichain'; +import ActionableMessage from '../../ui/actionable-message/actionable-message'; +import Box from '../../ui/box'; +import Button from '../../ui/button'; +import Chip from '../../ui/chip'; +import DefinitionList from '../../ui/definition-list'; +import Preloader from '../../ui/icon/preloader'; +import OriginPill from '../../ui/origin-pill/origin-pill'; +import Popover from '../../ui/popover'; +import Spinner from '../../ui/spinner'; +import TextField from '../../ui/text-field'; +import TextArea from '../../ui/textarea/textarea'; +import Tooltip from '../../ui/tooltip/tooltip'; +import TruncatedDefinitionList from '../../ui/truncated-definition-list'; +import Typography from '../../ui/typography'; +import UrlIcon from '../../ui/url-icon'; import { ConfirmInfoRow, ConfirmInfoRowAddress, ConfirmInfoRowValueDouble, } from '../confirm/info/row'; -import { SnapDelineator } from '../snaps/snap-delineator'; +import MetaMaskTranslation from '../metamask-translation'; +import NetworkDisplay from '../network-display'; import { Copyable } from '../snaps/copyable'; -import Spinner from '../../ui/spinner'; -import Preloader from '../../ui/icon/preloader'; -import { SnapUIMarkdown } from '../snaps/snap-ui-markdown'; -import { SnapUILink } from '../snaps/snap-ui-link'; -import { SmartTransactionStatusPage } from '../../../pages/smart-transactions/smart-transaction-status-page'; +import { SnapDelineator } from '../snaps/snap-delineator'; +import { SnapUIAddress } from '../snaps/snap-ui-address'; +import { SnapUIAvatar } from '../snaps/snap-ui-avatar'; +import { SnapUIBanner } from '../snaps/snap-ui-banner'; +import { SnapUIButton } from '../snaps/snap-ui-button'; +import { SnapUICard } from '../snaps/snap-ui-card'; +import { SnapUICheckbox } from '../snaps/snap-ui-checkbox'; +import { SnapUIDropdown } from '../snaps/snap-ui-dropdown'; +import { SnapUIFileInput } from '../snaps/snap-ui-file-input'; +import { SnapUIFooterButton } from '../snaps/snap-ui-footer-button'; +import { SnapUIForm } from '../snaps/snap-ui-form'; import { SnapUIIcon } from '../snaps/snap-ui-icon'; import { SnapUIImage } from '../snaps/snap-ui-image'; -import { SnapUIFileInput } from '../snaps/snap-ui-file-input'; import { SnapUIInput } from '../snaps/snap-ui-input'; -import { SnapUIForm } from '../snaps/snap-ui-form'; -import { SnapUIButton } from '../snaps/snap-ui-button'; -import { SnapUIDropdown } from '../snaps/snap-ui-dropdown'; +import { SnapUILink } from '../snaps/snap-ui-link'; +import { SnapUIMarkdown } from '../snaps/snap-ui-markdown'; import { SnapUIRadioGroup } from '../snaps/snap-ui-radio-group'; -import { SnapUICheckbox } from '../snaps/snap-ui-checkbox'; -import { SnapUITooltip } from '../snaps/snap-ui-tooltip'; -import { SnapUICard } from '../snaps/snap-ui-card'; -import { SnapUIAddress } from '../snaps/snap-ui-address'; -import { SnapUIAvatar } from '../snaps/snap-ui-avatar'; import { SnapUISelector } from '../snaps/snap-ui-selector'; -import { SnapUIFooterButton } from '../snaps/snap-ui-footer-button'; +import { SnapUITooltip } from '../snaps/snap-ui-tooltip'; ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) -import { SnapAccountSuccessMessage } from '../../../pages/confirmations/components/snap-account-success-message'; import { SnapAccountErrorMessage } from '../../../pages/confirmations/components/snap-account-error-message'; +import { SnapAccountSuccessMessage } from '../../../pages/confirmations/components/snap-account-success-message'; import { CreateSnapAccount } from '../../../pages/create-snap-account'; -import { CreateNamedSnapAccount } from '../../multichain/create-named-snap-account'; import { RemoveSnapAccount, SnapAccountCard, } from '../../../pages/remove-snap-account'; import { SnapAccountRedirect } from '../../../pages/snap-account-redirect'; +import { CreateNamedSnapAccount } from '../../multichain/create-named-snap-account'; import SnapAuthorshipHeader from '../snaps/snap-authorship-header'; ///: END:ONLY_INCLUDE_IF export const safeComponentList = { a: 'a', - ActionableMessage, AccountListItem, + ActionableMessage, AvatarIcon, b: 'b', + BannerAlert, Box, Button, Chip, ConfirmationNetworkSwitch, + ConfirmInfoRow, + ConfirmInfoRowAddress, + ConfirmInfoRowValueDouble, + Copyable, DefinitionList, div: 'div', + FormTextField, i: 'i', MetaMaskTranslation, NetworkDisplay, + OriginPill, p: 'p', Popover, + Preloader, + SnapDelineator, + SnapUIAddress, + SnapUIAvatar, + SnapUIBanner, + SnapUIButton, + SnapUICard, + SnapUICheckbox, + SnapUIDropdown, + SnapUIFileInput, + SnapUIForm, + SnapUIFooterButton, + SnapUIIcon, + SnapUIImage, + SnapUIInput, + SnapUILink, + SnapUIMarkdown, + SnapUIRadioGroup, + SnapUISelector, + SnapUITooltip, span: 'span', + Spinner, Text, TextArea, TextField, @@ -86,40 +116,14 @@ export const safeComponentList = { Typography, SmartTransactionStatusPage, UrlIcon, - Copyable, - SnapDelineator, - SnapUIMarkdown, - SnapUILink, - SnapUIIcon, - SnapUIImage, - BannerAlert, - Spinner, - Preloader, - ConfirmInfoRow, - ConfirmInfoRowAddress, - ConfirmInfoRowValueDouble, - SnapUIFileInput, - SnapUIInput, - SnapUIButton, - SnapUIForm, - SnapUIDropdown, - SnapUIRadioGroup, - SnapUICheckbox, - SnapUITooltip, - SnapUICard, - SnapUISelector, - SnapUIAddress, - SnapUIAvatar, - SnapUIFooterButton, - FormTextField, ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) + CreateNamedSnapAccount, CreateSnapAccount, RemoveSnapAccount, - CreateNamedSnapAccount, - SnapAccountSuccessMessage, + SnapAccountCard, SnapAccountErrorMessage, - SnapAuthorshipHeader, SnapAccountRedirect, - SnapAccountCard, + SnapAccountSuccessMessage, + SnapAuthorshipHeader, ///: END:ONLY_INCLUDE_IF }; diff --git a/ui/components/app/name/__snapshots__/name.test.tsx.snap b/ui/components/app/name/__snapshots__/name.test.tsx.snap index 286429760c1e..883717fca1f4 100644 --- a/ui/components/app/name/__snapshots__/name.test.tsx.snap +++ b/ui/components/app/name/__snapshots__/name.test.tsx.snap @@ -79,7 +79,7 @@ exports[`Name renders address with long saved name 1`] = `

    - Very long an... + Very long...

    diff --git a/ui/components/app/name/index.scss b/ui/components/app/name/index.scss index f82638373ecd..8037a25390e4 100644 --- a/ui/components/app/name/index.scss +++ b/ui/components/app/name/index.scss @@ -6,6 +6,7 @@ gap: 5px; font-size: 12px; max-width: 100%; + cursor: pointer; &__missing { background-color: var(--color-background-alternative); diff --git a/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap b/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap index 3520a1b64a13..8ddce02439c9 100644 --- a/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap +++ b/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap @@ -753,7 +753,7 @@ exports[`NameDetails renders with recognized name 1`] = `

    - iZUMi Bond U... + iZUMi Bon...

    diff --git a/ui/components/app/name/name.tsx b/ui/components/app/name/name.tsx index 4871cc481f0c..1b5305c2b61f 100644 --- a/ui/components/app/name/name.tsx +++ b/ui/components/app/name/name.tsx @@ -106,7 +106,7 @@ const Name = memo( const MAX_PET_NAME_LENGTH = 12; const formattedName = shortenString(name || undefined, { truncatedCharLimit: MAX_PET_NAME_LENGTH, - truncatedStartChars: MAX_PET_NAME_LENGTH, + truncatedStartChars: MAX_PET_NAME_LENGTH - 3, truncatedEndChars: 0, skipCharacterInEnd: true, }); diff --git a/ui/components/app/permission-cell/permission-cell-options.js b/ui/components/app/permission-cell/permission-cell-options.js index 5cefdf7f7d8f..f94a2b7599d3 100644 --- a/ui/components/app/permission-cell/permission-cell-options.js +++ b/ui/components/app/permission-cell/permission-cell-options.js @@ -49,6 +49,10 @@ export const PermissionCellOptions = ({ dispatch(revokeDynamicSnapPermissions(snapId, [permissionName])); }; + if (!description && !isRevokable) { + return null; + } + return ( {showOptions && ( - - - {t('details')} - - + {description && ( + + + {t('details')} + + + )} {isRevokable && ( ); })} diff --git a/ui/components/app/snaps/snap-home-page/snap-home-renderer.js b/ui/components/app/snaps/snap-home-page/snap-home-renderer.js index d0acd2060f9b..c8e54775117a 100644 --- a/ui/components/app/snaps/snap-home-page/snap-home-renderer.js +++ b/ui/components/app/snaps/snap-home-page/snap-home-renderer.js @@ -64,16 +64,16 @@ export const SnapHomeRenderer = ({ snapId }) => { } }, [unapprovedTemplatedConfirmations, unapprovedConfirmations, history]); - return ( - - {error && ( + if (error) { + return ( + @@ -82,18 +82,18 @@ export const SnapHomeRenderer = ({ snapId }) => { - )} - {(interfaceId || loading) && ( - - )} - + + ); + } + + return ( + ); }; diff --git a/ui/components/app/snaps/snap-insight/snap-insight.js b/ui/components/app/snaps/snap-insight/snap-insight.js index 4f243e265183..07630c3b0706 100644 --- a/ui/components/app/snaps/snap-insight/snap-insight.js +++ b/ui/components/app/snaps/snap-insight/snap-insight.js @@ -6,6 +6,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { Text } from '../../../component-library'; import { AlignItems, + BackgroundColor, FLEX_DIRECTION, JustifyContent, TextAlign, @@ -69,6 +70,7 @@ export const SnapInsight = ({ snapId, data }) => { interfaceId={interfaceId} delineatorType={DelineatorType.Insights} isLoading={isLoading} + contentBackgroundColor={BackgroundColor.backgroundDefault} /> ) : ( { diff --git a/ui/components/app/snaps/snap-settings-page/index.ts b/ui/components/app/snaps/snap-settings-page/index.ts new file mode 100644 index 000000000000..91a594fcdeb0 --- /dev/null +++ b/ui/components/app/snaps/snap-settings-page/index.ts @@ -0,0 +1 @@ +export * from './snap-settings-renderer'; diff --git a/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx b/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx new file mode 100644 index 000000000000..fa5636ebb77f --- /dev/null +++ b/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx @@ -0,0 +1,81 @@ +import React, { FunctionComponent, useEffect, useMemo } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useLocation } from 'react-router-dom'; +import { useI18nContext } from '../../../../hooks/useI18nContext'; + +import { deleteInterface } from '../../../../store/actions'; +import { Box, Text } from '../../../component-library'; +import { + BackgroundColor, + BlockSize, + TextVariant, +} from '../../../../helpers/constants/design-system'; +import { SnapDelineator } from '../snap-delineator'; +import { getSnapMetadata } from '../../../../selectors'; +import { DelineatorType } from '../../../../helpers/constants/snaps'; +import { Copyable } from '../copyable'; +import { SnapUIRenderer } from '../snap-ui-renderer'; +import { useSnapSettings } from '../../../../hooks/snaps/useSnapSettings'; +import { decodeSnapIdFromPathname } from '../../../../helpers/utils/snaps'; + +type SnapSettingsRendererProps = { + snapId: string; +}; + +export const SnapSettingsRenderer: FunctionComponent< + SnapSettingsRendererProps +> = () => { + const { pathname } = useLocation(); + const dispatch = useDispatch(); + const t = useI18nContext(); + + const snapId = useMemo(() => decodeSnapIdFromPathname(pathname), [pathname]); + + const { name: snapName } = useSelector((state) => + getSnapMetadata(state, snapId), + ); + + const { data, error, loading } = useSnapSettings({ + snapId, + }); + + const interfaceId = !loading && !error ? data?.id : undefined; + + useEffect(() => { + return () => { + interfaceId && dispatch(deleteInterface(interfaceId)); + }; + }, [interfaceId]); + + if (!snapId) { + return null; + } + + return ( + + {error && ( + + + + {t('snapsUIError', [{snapName}])} + + + + + )} + {(interfaceId || loading) && ( + + )} + + ); +}; diff --git a/ui/components/app/snaps/snap-ui-banner/index.ts b/ui/components/app/snaps/snap-ui-banner/index.ts new file mode 100644 index 000000000000..f7e12ce782b0 --- /dev/null +++ b/ui/components/app/snaps/snap-ui-banner/index.ts @@ -0,0 +1 @@ +export * from './snap-ui-banner'; diff --git a/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.stories.tsx b/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.stories.tsx new file mode 100644 index 000000000000..4d1581e9d3e8 --- /dev/null +++ b/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.stories.tsx @@ -0,0 +1,33 @@ +import React, { ReactNode } from 'react'; +import { SnapUIBanner } from './snap-ui-banner'; +import { BannerAlertSeverity } from '../../../component-library'; + +export default { + title: 'Components/App/Snaps/SnapUIBanner', + component: SnapUIBanner, + argTypes: { + title: { + control: 'text', + }, + severity: { + control: 'text', + }, + children: { + control: 'text', + }, + }, +}; + +export const DefaultStory = (args: { + title: string; + severity: BannerAlertSeverity; + children: ReactNode; +}) => ; + +DefaultStory.storyName = 'Default'; + +DefaultStory.args = { + title: 'Banner title', + severity: 'info', + children: 'Banner content.', +}; diff --git a/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.tsx b/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.tsx new file mode 100644 index 000000000000..872eb3032993 --- /dev/null +++ b/ui/components/app/snaps/snap-ui-banner/snap-ui-banner.tsx @@ -0,0 +1,19 @@ +import React, { FunctionComponent } from 'react'; +import { BannerAlert, BannerAlertSeverity } from '../../../component-library'; + +export type SnapUIBannerProps = { + severity: BannerAlertSeverity | undefined; + title: string; +}; + +export const SnapUIBanner: FunctionComponent = ({ + children, + severity, + title, +}) => { + return ( + + {children} + + ); +}; diff --git a/ui/components/app/snaps/snap-ui-button/snap-ui-button.tsx b/ui/components/app/snaps/snap-ui-button/snap-ui-button.tsx index 08fef2f9a6b7..49f1de8fbee1 100644 --- a/ui/components/app/snaps/snap-ui-button/snap-ui-button.tsx +++ b/ui/components/app/snaps/snap-ui-button/snap-ui-button.tsx @@ -1,7 +1,12 @@ import React, { FunctionComponent, MouseEvent as ReactMouseEvent } from 'react'; import classnames from 'classnames'; import { ButtonType, UserInputEventType } from '@metamask/snaps-sdk'; -import { ButtonLinkProps, Text } from '../../../component-library'; +import { + ButtonLinkProps, + Icon, + IconName, + Text, +} from '../../../component-library'; import { FontWeight, TextColor, @@ -10,6 +15,8 @@ import { useSnapInterfaceContext } from '../../../../contexts/snaps'; export type SnapUIButtonProps = { name?: string; + textVariant: ButtonLinkProps<'button'>['variant']; + loading?: boolean; }; const COLORS = { @@ -26,7 +33,9 @@ export const SnapUIButton: FunctionComponent< type = ButtonType.Button, variant = 'primary', disabled = false, + loading = false, className = '', + textVariant, ...props }) => { const { handleEvent } = useSnapInterfaceContext(); @@ -58,9 +67,17 @@ export const SnapUIButton: FunctionComponent< onClick={handleClick} color={color} disabled={disabled} + variant={textVariant} {...props} > - {children} + {loading ? ( + + ) : ( + children + )} ); }; diff --git a/ui/components/app/snaps/snap-ui-checkbox/snap-ui-checkbox.tsx b/ui/components/app/snaps/snap-ui-checkbox/snap-ui-checkbox.tsx index 0d85f8ef60dc..9c2606a2c77f 100644 --- a/ui/components/app/snaps/snap-ui-checkbox/snap-ui-checkbox.tsx +++ b/ui/components/app/snaps/snap-ui-checkbox/snap-ui-checkbox.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; +import classnames from 'classnames'; import { useSnapInterfaceContext } from '../../../../contexts/snaps'; import { BorderColor, @@ -51,7 +52,9 @@ export const SnapUICheckbox: FunctionComponent = ({ return ( diff --git a/ui/components/app/snaps/snap-ui-dropdown/snap-ui-dropdown.tsx b/ui/components/app/snaps/snap-ui-dropdown/snap-ui-dropdown.tsx index f2cb85cc4ef0..835734b2bf87 100644 --- a/ui/components/app/snaps/snap-ui-dropdown/snap-ui-dropdown.tsx +++ b/ui/components/app/snaps/snap-ui-dropdown/snap-ui-dropdown.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; +import classnames from 'classnames'; import { useSnapInterfaceContext } from '../../../../contexts/snaps'; import { Display, @@ -46,7 +47,9 @@ export const SnapUIDropdown: FunctionComponent = ({ return ( diff --git a/ui/components/app/snaps/snap-ui-file-input/snap-ui-file-input.tsx b/ui/components/app/snaps/snap-ui-file-input/snap-ui-file-input.tsx index 1d254ccaa2e3..cfab068ab6db 100644 --- a/ui/components/app/snaps/snap-ui-file-input/snap-ui-file-input.tsx +++ b/ui/components/app/snaps/snap-ui-file-input/snap-ui-file-input.tsx @@ -146,7 +146,13 @@ export const SnapUIFileInput: FunctionComponent = ({ if (compact) { return ( - + {header} = ({ } return ( - + {header} - {isSnapAction && !hideSnapBranding && ( + {isSnapAction && !hideSnapBranding && !loading && ( )} - {children} + {loading ? ( + + ) : ( + children + )} ); }; diff --git a/ui/components/app/snaps/snap-ui-input/snap-ui-input.tsx b/ui/components/app/snaps/snap-ui-input/snap-ui-input.tsx index 469a8313f4a1..a5dd9ae224b9 100644 --- a/ui/components/app/snaps/snap-ui-input/snap-ui-input.tsx +++ b/ui/components/app/snaps/snap-ui-input/snap-ui-input.tsx @@ -5,17 +5,19 @@ import React, { useRef, useState, } from 'react'; +import classnames from 'classnames'; import { useSnapInterfaceContext } from '../../../../contexts/snaps'; import { FormTextField, FormTextFieldProps } from '../../../component-library'; export type SnapUIInputProps = { name: string; form?: string; + label?: string | React.ReactNode; }; export const SnapUIInput: FunctionComponent< SnapUIInputProps & FormTextFieldProps<'div'> -> = ({ name, form, ...props }) => { +> = ({ name, form, label, ...props }) => { const { handleInputChange, getValue, focusedInput, setCurrentFocusedInput } = useSnapInterfaceContext(); @@ -54,10 +56,13 @@ export const SnapUIInput: FunctionComponent< ref={inputRef} onFocus={handleFocus} onBlur={handleBlur} - className="snap-ui-renderer__input" + className={classnames('snap-ui-renderer__input', { + 'snap-ui-renderer__field': label !== undefined, + })} id={name} value={value} onChange={handleChange} + label={label} {...props} /> ); diff --git a/ui/components/app/snaps/snap-ui-radio-group/snap-ui-radio-group.tsx b/ui/components/app/snaps/snap-ui-radio-group/snap-ui-radio-group.tsx index 4563fbc02fe3..185eed8bddc9 100644 --- a/ui/components/app/snaps/snap-ui-radio-group/snap-ui-radio-group.tsx +++ b/ui/components/app/snaps/snap-ui-radio-group/snap-ui-radio-group.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; +import classnames from 'classnames'; import { useSnapInterfaceContext } from '../../../../contexts/snaps'; import { AlignItems, @@ -75,7 +76,9 @@ export const SnapUIRadioGroup: FunctionComponent = ({ return ( diff --git a/ui/components/app/snaps/snap-ui-renderer/components/avatar.ts b/ui/components/app/snaps/snap-ui-renderer/components/avatar.ts index 9572516383b6..fd7953e54936 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/avatar.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/avatar.ts @@ -5,5 +5,6 @@ export const avatar: UIComponentFactory = ({ element }) => ({ element: 'SnapUIAvatar', props: { address: element.props.address, + size: element.props.size, }, }); diff --git a/ui/components/app/snaps/snap-ui-renderer/components/banner.ts b/ui/components/app/snaps/snap-ui-renderer/components/banner.ts new file mode 100644 index 000000000000..fceb03d4be5d --- /dev/null +++ b/ui/components/app/snaps/snap-ui-renderer/components/banner.ts @@ -0,0 +1,20 @@ +import { BannerElement, JSXElement } from '@metamask/snaps-sdk/jsx'; +import { getJsxChildren } from '@metamask/snaps-utils'; +import { mapToTemplate } from '../utils'; +import { UIComponentFactory } from './types'; + +export const banner: UIComponentFactory = ({ + element, + ...params +}) => { + return { + element: 'SnapUIBanner', + children: getJsxChildren(element).map((children) => + mapToTemplate({ element: children as JSXElement, ...params }), + ), + props: { + title: element.props.title, + severity: element.props.severity, + }, + }; +}; diff --git a/ui/components/app/snaps/snap-ui-renderer/components/button.ts b/ui/components/app/snaps/snap-ui-renderer/components/button.ts index f624ffb23195..4b0cdb808e79 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/button.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/button.ts @@ -2,6 +2,7 @@ import { ButtonElement, JSXElement } from '@metamask/snaps-sdk/jsx'; import { getJsxChildren } from '@metamask/snaps-utils'; import { NonEmptyArray } from '@metamask/utils'; import { mapTextToTemplate } from '../utils'; +import { TextVariant } from '../../../../../helpers/constants/design-system'; import { UIComponentFactory } from './types'; export const button: UIComponentFactory = ({ @@ -15,6 +16,9 @@ export const button: UIComponentFactory = ({ variant: element.props.variant, name: element.props.name, disabled: element.props.disabled, + loading: element.props.loading, + textVariant: + element.props.size === 'sm' ? TextVariant.bodySm : TextVariant.bodyMd, }, children: mapTextToTemplate( getJsxChildren(element) as NonEmptyArray, diff --git a/ui/components/app/snaps/snap-ui-renderer/components/container.ts b/ui/components/app/snaps/snap-ui-renderer/components/container.ts index cac6788f8c48..709483c84492 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/container.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/container.ts @@ -1,15 +1,14 @@ -import { BoxElement, JSXElement } from '@metamask/snaps-sdk/jsx'; +import { ContainerElement, JSXElement } from '@metamask/snaps-sdk/jsx'; import { getJsxChildren } from '@metamask/snaps-utils'; import { mapToTemplate } from '../utils'; import { - BlockSize, Display, FlexDirection, } from '../../../../../helpers/constants/design-system'; import { UIComponentFactory } from './types'; import { DEFAULT_FOOTER } from './footer'; -export const container: UIComponentFactory = ({ +export const container: UIComponentFactory = ({ element, useFooter, onCancel, @@ -78,12 +77,7 @@ export const container: UIComponentFactory = ({ props: { display: Display.Flex, flexDirection: FlexDirection.Column, - height: BlockSize.Full, className: 'snap-ui-renderer__container', - style: { - overflowY: 'auto', - paddingBottom: useFooter ? '80px' : 'initial', - }, }, }; }; diff --git a/ui/components/app/snaps/snap-ui-renderer/components/index.ts b/ui/components/app/snaps/snap-ui-renderer/components/index.ts index 17a9b6aa37c1..f6173b7199b0 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/index.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/index.ts @@ -27,6 +27,7 @@ import { selector } from './selector'; import { icon } from './icon'; import { section } from './section'; import { avatar } from './avatar'; +import { banner } from './banner'; export const COMPONENT_MAPPING = { Box: box, @@ -58,4 +59,5 @@ export const COMPONENT_MAPPING = { Container: container, Selector: selector, Section: section, + Banner: banner, }; diff --git a/ui/components/app/snaps/snap-ui-renderer/components/section.ts b/ui/components/app/snaps/snap-ui-renderer/components/section.ts index 5e582936804c..e5c26ccbc51a 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/section.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/section.ts @@ -8,12 +8,20 @@ import { box } from './box'; export const section: UIComponentFactory = ({ element, + contentBackgroundColor, ...params }) => { const { children, props } = box({ element, ...params, } as unknown as UIComponentParams); + + // Reverse colors to improve visibility on certain backgrounds + const backgroundColor = + contentBackgroundColor === BackgroundColor.backgroundDefault + ? BackgroundColor.backgroundAlternative + : BackgroundColor.backgroundDefault; + return { element: 'Box', children, @@ -22,7 +30,7 @@ export const section: UIComponentFactory = ({ className: 'snap-ui-renderer__section', padding: 4, gap: 2, - backgroundColor: BackgroundColor.backgroundDefault, + backgroundColor, borderRadius: BorderRadius.LG, }, }; diff --git a/ui/components/app/snaps/snap-ui-renderer/components/text.ts b/ui/components/app/snaps/snap-ui-renderer/components/text.ts index fe9194817ca3..6b68227f6bd5 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/text.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/text.ts @@ -6,32 +6,45 @@ import { TextVariant, OverflowWrap, TextColor, + FontWeight, } from '../../../../../helpers/constants/design-system'; import { UIComponentFactory } from './types'; +function getTextColor(color: TextElement['props']['color']) { + switch (color) { + case 'default': + return TextColor.textDefault; + case 'alternative': + return TextColor.textAlternative; + case 'muted': + return TextColor.textMuted; + case 'error': + return TextColor.errorDefault; + case 'success': + return TextColor.successDefault; + case 'warning': + return TextColor.warningDefault; + default: + return TextColor.inherit; + } +} + +function getFontWeight(color: TextElement['props']['fontWeight']) { + switch (color) { + case 'bold': + return FontWeight.Bold; + case 'medium': + return FontWeight.Medium; + case 'regular': + default: + return FontWeight.Normal; + } +} + export const text: UIComponentFactory = ({ element, ...params }) => { - const getTextColor = () => { - switch (element.props.color) { - case 'default': - return TextColor.textDefault; - case 'alternative': - return TextColor.textAlternative; - case 'muted': - return TextColor.textMuted; - case 'error': - return TextColor.errorDefault; - case 'success': - return TextColor.successDefault; - case 'warning': - return TextColor.warningDefault; - default: - return TextColor.inherit; - } - }; - return { element: 'Text', children: mapTextToTemplate( @@ -41,8 +54,9 @@ export const text: UIComponentFactory = ({ props: { variant: element.props.size === 'sm' ? TextVariant.bodySm : TextVariant.bodyMd, - overflowWrap: OverflowWrap.Anywhere, - color: getTextColor(), + fontWeight: getFontWeight(element.props.fontWeight), + overflowWrap: OverflowWrap.BreakWord, + color: getTextColor(element.props.color), className: 'snap-ui-renderer__text', textAlign: element.props.alignment, }, diff --git a/ui/components/app/snaps/snap-ui-renderer/components/types.ts b/ui/components/app/snaps/snap-ui-renderer/components/types.ts index 78d354f805a0..bba5296aa899 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/types.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/types.ts @@ -13,6 +13,7 @@ export type UIComponentParams = { placeholder?: string; }; t: (key: string) => string; + contentBackgroundColor: string | undefined; }; export type UIComponent = { diff --git a/ui/components/app/snaps/snap-ui-renderer/components/value.ts b/ui/components/app/snaps/snap-ui-renderer/components/value.ts index f365e30b1f39..70bb100daf62 100644 --- a/ui/components/app/snaps/snap-ui-renderer/components/value.ts +++ b/ui/components/app/snaps/snap-ui-renderer/components/value.ts @@ -1,10 +1,32 @@ import { ValueElement } from '@metamask/snaps-sdk/jsx'; +import { mapToTemplate } from '../utils'; import { UIComponentFactory } from './types'; -export const value: UIComponentFactory = ({ element }) => ({ - element: 'ConfirmInfoRowValueDouble', - props: { - left: element.props.extra, - right: element.props.value, - }, -}); +export const value: UIComponentFactory = ({ + element, + ...params +}) => { + return { + element: 'ConfirmInfoRowValueDouble', + props: { + left: + typeof element.props.extra === 'string' + ? element.props.extra + : undefined, + right: + typeof element.props.value === 'string' + ? element.props.value + : undefined, + }, + propComponents: { + left: + typeof element.props.extra === 'string' + ? undefined + : mapToTemplate({ element: element.props.extra, ...params }), + right: + typeof element.props.value === 'string' + ? undefined + : mapToTemplate({ element: element.props.value, ...params }), + }, + }; +}; diff --git a/ui/components/app/snaps/snap-ui-renderer/index.scss b/ui/components/app/snaps/snap-ui-renderer/index.scss index d32edf726479..c840a76b670c 100644 --- a/ui/components/app/snaps/snap-ui-renderer/index.scss +++ b/ui/components/app/snaps/snap-ui-renderer/index.scss @@ -5,21 +5,13 @@ $width-screen-md-min: 80vw; $width-screen-lg-min: 62vw; - &__content { - margin-bottom: 0 !important; - } - &__container { & > *:first-child { gap: 16px; - padding: 16px; + margin: 16px; } } - &__error { - margin-top: 0 !important; - } - &__spinner { width: 30px; } @@ -88,4 +80,12 @@ max-width: $width-screen-lg-min; } } + + &__form { + .snap-ui-renderer__panel { + .snap-ui-renderer__field { + flex: 1 1 50%; // Ensure that adjacent form elements take up to 50% width + } + } + } } diff --git a/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js b/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js index 332fab99308d..a11a77c9810b 100644 --- a/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js +++ b/ui/components/app/snaps/snap-ui-renderer/snap-ui-renderer.js @@ -14,12 +14,13 @@ import { SnapInterfaceContextProvider } from '../../../../contexts/snaps'; import PulseLoader from '../../../ui/pulse-loader'; import { AlignItems, + BackgroundColor, BlockSize, Display, JustifyContent, } from '../../../../helpers/constants/design-system'; import { useI18nContext } from '../../../../hooks/useI18nContext'; -import { mapToTemplate } from './utils'; +import { mapToExtensionCompatibleColor, mapToTemplate } from './utils'; // Component that maps Snaps UI JSON format to MetaMask Template Renderer format const SnapUIRendererComponent = ({ @@ -69,6 +70,11 @@ const SnapUIRendererComponent = ({ [inputValue, onInputChange, placeholder, isPrompt], ); + const backgroundColor = + contentBackgroundColor ?? + mapToExtensionCompatibleColor(content?.props?.backgroundColor) ?? + BackgroundColor.backgroundAlternative; + const sections = useMemo( () => content && @@ -79,8 +85,9 @@ const SnapUIRendererComponent = ({ useFooter, promptLegacyProps, t, + contentBackgroundColor: backgroundColor, }), - [content, onCancel, useFooter, promptLegacyProps, t], + [content, onCancel, useFooter, promptLegacyProps, t, backgroundColor], ); if (isLoading || !content) { @@ -99,6 +106,10 @@ const SnapUIRendererComponent = ({ const { state: initialState, context } = interfaceState; + // The renderer should only have a footer if there is a default cancel action + // or if the footer component has been used. + const hasFooter = onCancel || content?.props?.children?.[1] !== undefined; + return useDelineator ? ( diff --git a/ui/components/app/snaps/snap-ui-renderer/utils.ts b/ui/components/app/snaps/snap-ui-renderer/utils.ts index a22bffa46fe2..c71772618995 100644 --- a/ui/components/app/snaps/snap-ui-renderer/utils.ts +++ b/ui/components/app/snaps/snap-ui-renderer/utils.ts @@ -5,6 +5,7 @@ import { sha256 } from '@noble/hashes/sha256'; import { NonEmptyArray, bytesToHex, remove0x } from '@metamask/utils'; import { unescape as unescapeEntities } from 'he'; import { ChangeEvent as ReactChangeEvent } from 'react'; +import { BackgroundColor } from '../../../../helpers/constants/design-system'; import { COMPONENT_MAPPING } from './components'; import { UIComponent } from './components/types'; @@ -20,6 +21,7 @@ export type MapToTemplateParams = { placeholder?: string; }; t?: (key: string) => string; + contentBackgroundColor?: string | undefined; }; /** @@ -140,3 +142,17 @@ export const FIELD_ELEMENT_TYPES = [ export const getPrimaryChildElementIndex = (children: JSXElement[]) => { return children.findIndex((c) => FIELD_ELEMENT_TYPES.includes(c.type)); }; + +/** + * Map Snap custom color to extension compatible color. + * + * @param color - Snap custom color. + * @returns String, representing color from design system. + */ +export const mapToExtensionCompatibleColor = (color: string) => { + const backgroundColorMapping: { [key: string]: string | undefined } = { + default: BackgroundColor.backgroundAlternative, // For Snaps, the default background color is the Alternative + alternative: BackgroundColor.backgroundDefault, + }; + return color ? backgroundColorMapping[color] : undefined; +}; diff --git a/ui/components/app/snaps/snap-ui-selector/index.scss b/ui/components/app/snaps/snap-ui-selector/index.scss index 96830bf6c9d5..8f7cec5702b1 100644 --- a/ui/components/app/snaps/snap-ui-selector/index.scss +++ b/ui/components/app/snaps/snap-ui-selector/index.scss @@ -1,6 +1,7 @@ .snap-ui-renderer { &__selector { width: 100%; + border: 1px solid var(--color-border-muted); & > span:first-child { width: 100%; @@ -12,6 +13,7 @@ &:hover { background-color: var(--color-background-alternative-hover); + border-color: var(--color-border-default); } } diff --git a/ui/components/app/snaps/snap-ui-selector/snap-ui-selector.tsx b/ui/components/app/snaps/snap-ui-selector/snap-ui-selector.tsx index a0869ff0b46b..6f844dc29425 100644 --- a/ui/components/app/snaps/snap-ui-selector/snap-ui-selector.tsx +++ b/ui/components/app/snaps/snap-ui-selector/snap-ui-selector.tsx @@ -3,6 +3,7 @@ import React, { useEffect, MouseEvent as ReactMouseEvent, } from 'react'; +import classnames from 'classnames'; import { Box, ButtonBase, @@ -75,7 +76,7 @@ const SelectorItem: React.FunctionComponent = ({ justifyContent: 'inherit', textAlign: 'inherit', height: 'inherit', - minHeight: '32px', + minHeight: '48px', maxHeight: '64px', }} > @@ -128,7 +129,13 @@ export const SnapUISelector: React.FunctionComponent = ({ return ( <> - + {label && } = ({ justifyContent: 'inherit', textAlign: 'inherit', height: 'inherit', - minHeight: '32px', + minHeight: '48px', maxHeight: '64px', }} > diff --git a/ui/components/app/tab-bar/index.scss b/ui/components/app/tab-bar/index.scss index ce149f922879..6efdbab6c51e 100644 --- a/ui/components/app/tab-bar/index.scss +++ b/ui/components/app/tab-bar/index.scss @@ -38,11 +38,16 @@ display: flex; align-items: center; position: relative; + overflow: hidden; width: 100%; &__title { @include design-system.H4; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + @include design-system.screen-sm-min { @include design-system.H6; } diff --git a/ui/components/app/toast-master/selectors.ts b/ui/components/app/toast-master/selectors.ts index b88762c3bc19..80b574c05d90 100644 --- a/ui/components/app/toast-master/selectors.ts +++ b/ui/components/app/toast-master/selectors.ts @@ -1,4 +1,5 @@ -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { getAlertEnabledness } from '../../../ducks/metamask/metamask'; import { PRIVACY_POLICY_DATE } from '../../../helpers/constants/privacy-policy'; import { diff --git a/ui/components/app/transaction-list-item-details/index.scss b/ui/components/app/transaction-list-item-details/index.scss index 13adb780fa4d..34d4af1ea82e 100644 --- a/ui/components/app/transaction-list-item-details/index.scss +++ b/ui/components/app/transaction-list-item-details/index.scss @@ -49,6 +49,8 @@ display: flex; flex-direction: column; align-items: flex-end; + height: 42px; + justify-content: space-between; .btn-link { font-size: 12px; @@ -62,9 +64,10 @@ } &__operations { - margin: 0 0 16px 16px; + margin: 0 16px 16px 16px; display: flex; - justify-content: flex-end; + justify-content: space-between; + align-items: center; } &__header { diff --git a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js index 226a2a9113c0..f614a4dbc250 100644 --- a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.js @@ -13,9 +13,19 @@ import Tooltip from '../../ui/tooltip'; import CancelButton from '../cancel-button'; import Popover from '../../ui/popover'; import { Box } from '../../component-library/box'; +import { Text } from '../../component-library/text'; +import { + BannerAlert, + BannerAlertSeverity, +} from '../../component-library/banner-alert'; +import { + TextVariant, + ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) + IconColor, + ///: END:ONLY_INCLUDE_IF +} from '../../../helpers/constants/design-system'; ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) -import { Icon, IconName, Text } from '../../component-library'; -import { IconColor } from '../../../helpers/constants/design-system'; +import { Icon, IconName } from '../../component-library'; ///: END:ONLY_INCLUDE_IF import { SECOND } from '../../../../shared/constants/time'; import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; @@ -55,6 +65,7 @@ export default class TransactionListItemDetails extends PureComponent { recipientNickname: PropTypes.string, transactionStatus: PropTypes.func, isCustomNetwork: PropTypes.bool, + showErrorBanner: PropTypes.bool, history: PropTypes.object, blockExplorerLinkText: PropTypes.object, ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) @@ -204,6 +215,7 @@ export default class TransactionListItemDetails extends PureComponent { onClose, recipientNickname, showCancel, + showErrorBanner, transactionStatus: TransactionStatus, blockExplorerLinkText, ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) @@ -220,6 +232,17 @@ export default class TransactionListItemDetails extends PureComponent {
    + {showErrorBanner && ( + + + {t('transactionFailedBannerMessage')} + + + )}
    {showSpeedUp && ( )} @@ -258,22 +281,18 @@ export default class TransactionListItemDetails extends PureComponent { data-testid="transaction-list-item-details-tx-status" >
    {t('status')}
    -
    - -
    +
    -
    - -
    +
    { +const render = (overrideProps) => { const rpcPrefs = { blockExplorerUrl: 'https://customblockexplorer.com/', }; @@ -71,7 +71,7 @@ const render = async (overrideProps) => { senderAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tryReverseResolveAddress: jest.fn(), transactionGroup, - transactionStatus: () =>
    , + transactionStatus: () =>
    , blockExplorerLinkText, rpcPrefs, ...overrideProps, @@ -79,59 +79,57 @@ const render = async (overrideProps) => { const mockStore = configureMockStore([thunk])(mockState); - let result; - - await act( - async () => - (result = renderWithProvider( - , - mockStore, - )), + const result = renderWithProvider( + , + mockStore, ); return result; }; describe('TransactionListItemDetails Component', () => { - it('should render title with title prop', async () => { - const { queryByText } = await render(); + describe('matches snapshot', () => { + it('for non-error details', async () => { + const { queryByText, queryByTestId } = render(); + expect(queryByText('Test Transaction Details')).toBeInTheDocument(); + expect( + queryByTestId('transaction-list-item-details-banner-error-message'), + ).not.toBeInTheDocument(); + }); - await waitFor(() => { + it('for error details', async () => { + const { queryByText, queryByTestId } = render({ showErrorBanner: true }); expect(queryByText('Test Transaction Details')).toBeInTheDocument(); + expect( + queryByTestId('transaction-list-item-details-banner-error-message'), + ).toBeInTheDocument(); }); }); - describe('Retry button', () => { - it('should render retry button with showRetry prop', async () => { - const { queryByTestId } = await render({ showRetry: true }); - + describe('Action buttons', () => { + it('renders retry button with showRetry prop', async () => { + const { queryByTestId } = render({ showRetry: true }); expect(queryByTestId('rety-button')).toBeInTheDocument(); }); - }); - - describe('Cancel button', () => { - it('should render cancel button with showCancel prop', async () => { - const { queryByTestId } = await render({ showCancel: true }); + it('renders cancel button with showCancel prop', async () => { + const { queryByTestId } = render({ showCancel: true }); expect(queryByTestId('cancel-button')).toBeInTheDocument(); }); - }); - - describe('Speedup button', () => { - it('should render speedup button with showSpeedUp prop', async () => { - const { queryByTestId } = await render({ showSpeedUp: true }); + it('renders speedup button with showSpeedUp prop', async () => { + const { queryByTestId } = render({ showSpeedUp: true }); expect(queryByTestId('speedup-button')).toBeInTheDocument(); }); }); describe('Institutional', () => { - it('should render correctly if custodyTransactionDeepLink has a url', async () => { + it('renders correctly if custodyTransactionDeepLink has a url', async () => { mockGetCustodianTransactionDeepLink = jest .fn() .mockReturnValue({ url: 'https://url.com' }); - await render({ showCancel: true }); + render({ showCancel: true }); await waitFor(() => { const custodianViewButton = document.querySelector( @@ -143,7 +141,7 @@ describe('TransactionListItemDetails Component', () => { }); }); - it('should render correctly if transactionNote is provided', async () => { + it('renders correctly if transactionNote is provided', async () => { const newTransaction = { ...transaction, metadata: { @@ -159,13 +157,11 @@ describe('TransactionListItemDetails Component', () => { initialTransaction: newTransaction, }; - const { queryByText } = await render({ + const { queryByText } = render({ transactionGroup: newTransactionGroup, }); - await waitFor(() => { - expect(queryByText('some note')).toBeInTheDocument(); - }); + expect(queryByText('some note')).toBeInTheDocument(); }); }); }); diff --git a/ui/components/app/transaction-list-item/smart-transaction-list-item.component.js b/ui/components/app/transaction-list-item/smart-transaction-list-item.component.js index 5c1658918dbe..547f2e460497 100644 --- a/ui/components/app/transaction-list-item/smart-transaction-list-item.component.js +++ b/ui/components/app/transaction-list-item/smart-transaction-list-item.component.js @@ -125,6 +125,7 @@ export default function SmartTransactionListItem({ date={date} status={displayedStatusKey} statusOnly + shouldShowTooltip={false} /> )} /> diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.js b/ui/components/app/transaction-list-item/transaction-list-item.component.js index 09e8983b9196..5dc8cf48ef35 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.js @@ -459,6 +459,7 @@ function TransactionListItemInner({ !hasCancelled && !isBridgeTx } + showErrorBanner={Boolean(error)} transactionStatus={() => ( )} - {completedTransactions.length > 0 ? ( - completedTransactions - .map(removeIncomingTxsButToAnotherAddress) - .map(removeTxGroupsWithNoTx) - .filter(dateGroupsWithTransactionGroups) - .slice(0, limit) - .map((dateGroup) => { - return dateGroup.transactionGroups.map( - (transactionGroup, index) => { - return ( - - {renderDateStamp(index, dateGroup)} - {transactionGroup.initialTransaction - ?.isSmartTransaction ? ( - - ) : ( - - )} - - ); - }, - ); - }) - ) : ( - - - {isChainIdMismatch - ? noTransactionsMessage - : t('noTransactions')} - - - )} + {completedTransactions.length > 0 + ? completedTransactions + .map(removeIncomingTxsButToAnotherAddress) + .map(removeTxGroupsWithNoTx) + .filter(dateGroupsWithTransactionGroups) + .slice(0, limit) + .map((dateGroup) => { + return dateGroup.transactionGroups.map( + (transactionGroup, index) => { + return ( + + {renderDateStamp(index, dateGroup)} + {transactionGroup.initialTransaction + ?.isSmartTransaction ? ( + + ) : ( + + )} + + ); + }, + ); + }) + : null} {completedTransactions.length > limit && (
    +
    + ), +})); + +jest.mock('react-redux', () => ({ + useSelector: jest.fn(), + useDispatch: () => jest.fn(), +})); + +jest.mock('reselect', () => ({ + createSelector: jest.fn(), + createDeepEqualSelector: jest.fn(), + createSelectorCreator: jest.fn(() => jest.fn()), + lruMemoize: jest.fn(), +})); + +jest.mock('../../../selectors/approvals', () => ({ + selectPendingApproval: jest.fn(), +})); + jest.mock('../../../hooks/useI18nContext', () => ({ useI18nContext: () => (key: string) => key, })); @@ -46,13 +80,24 @@ describe('Carousel', () => { expect(closeButtons).toHaveLength(2); fireEvent.click(closeButtons[0]); - expect(mockOnClose).toHaveBeenCalledWith('1'); + expect(mockOnClose).toHaveBeenCalledWith(false, '1'); const remainingSlides = mockSlides.filter((slide) => slide.id !== '1'); rerender(); - const updatedSlides = container.querySelectorAll('.mm-carousel-slide'); - expect(updatedSlides).toHaveLength(1); + const updatedCloseButtons = container.querySelectorAll( + '.mm-carousel-slide__close-button', + ); + expect(updatedCloseButtons).toHaveLength(1); + + fireEvent.click(updatedCloseButtons[0]); + expect(mockOnClose).toHaveBeenCalledWith(true, '2'); + + const finalSlides = remainingSlides.filter((slide) => slide.id !== '2'); + rerender(); + + const finalSlideElements = container.querySelectorAll('.mm-carousel-slide'); + expect(finalSlideElements).toHaveLength(0); }); it('should handle slide navigation', () => { @@ -65,7 +110,7 @@ describe('Carousel', () => { fireEvent.click(dots[1]); const slides = container.querySelectorAll('.mm-carousel-slide'); - expect(slides[1].parentElement).toHaveClass('selected'); + expect(slides[1].parentElement).toHaveClass('mock-carousel'); }); it('should return null when no slides are present', () => { diff --git a/ui/components/multichain/carousel/carousel.tsx b/ui/components/multichain/carousel/carousel.tsx index 3fbbe955a8eb..83423948c530 100644 --- a/ui/components/multichain/carousel/carousel.tsx +++ b/ui/components/multichain/carousel/carousel.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Carousel as ResponsiveCarousel } from 'react-responsive-carousel'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { Box, BoxProps, BannerBase } from '../../component-library'; @@ -24,6 +24,7 @@ export const Carousel = React.forwardRef( isLoading = false, onClose, onClick, + onRenderSlides, ...props }: CarouselProps, ref: React.Ref, @@ -44,6 +45,17 @@ export const Carousel = React.forwardRef( }) .slice(0, MAX_SLIDES); + useEffect(() => { + if ( + visibleSlides && + visibleSlides.length > 0 && + onRenderSlides && + !isLoading + ) { + onRenderSlides(visibleSlides); + } + }, [visibleSlides, onRenderSlides, isLoading]); + const handleClose = (e: React.MouseEvent, slideId: string) => { e.preventDefault(); e.stopPropagation(); @@ -65,7 +77,7 @@ export const Carousel = React.forwardRef( setSelectedIndex(newSelectedIndex); if (onClose) { - onClose(slideId); + onClose(visibleSlides.length === 1, slideId); } }; diff --git a/ui/components/multichain/carousel/carousel.types.ts b/ui/components/multichain/carousel/carousel.types.ts index a8aef8df4839..3a6289e76a4b 100644 --- a/ui/components/multichain/carousel/carousel.types.ts +++ b/ui/components/multichain/carousel/carousel.types.ts @@ -3,6 +3,7 @@ import { CarouselSlide } from '../../../../shared/constants/app-state'; export type CarouselProps = { slides: CarouselSlide[]; isLoading?: boolean; - onClose?: (id: string) => void; + onClose?: (isLastSlide: boolean, id: string) => void; onClick?: (id: string) => void; + onRenderSlides?: (slides: CarouselSlide[]) => void; }; diff --git a/ui/components/multichain/connect-accounts-modal/__snapshots__/connect-accounts-modal.test.tsx.snap b/ui/components/multichain/connect-accounts-modal/__snapshots__/connect-accounts-modal.test.tsx.snap index b4a4836db2d6..8bcb788bb745 100644 --- a/ui/components/multichain/connect-accounts-modal/__snapshots__/connect-accounts-modal.test.tsx.snap +++ b/ui/components/multichain/connect-accounts-modal/__snapshots__/connect-accounts-modal.test.tsx.snap @@ -232,7 +232,7 @@ exports[`Connect More Accounts Modal should render correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    diff --git a/ui/components/multichain/connect-accounts-modal/connect-account-modal.types.ts b/ui/components/multichain/connect-accounts-modal/connect-account-modal.types.ts index 392d5b210dd4..4f9b4e56b4a2 100644 --- a/ui/components/multichain/connect-accounts-modal/connect-account-modal.types.ts +++ b/ui/components/multichain/connect-accounts-modal/connect-account-modal.types.ts @@ -1,4 +1,4 @@ -import { type InternalAccount } from '@metamask/keyring-api'; +import { type InternalAccount } from '@metamask/keyring-internal-api'; export enum ConnectAccountsType { Account = 'disconnectAllAccountsText', diff --git a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.tsx b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.tsx index 457e15b0141d..ff48f416e29d 100644 --- a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.tsx +++ b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { useSelector } from 'react-redux'; -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { getUnconnectedAccounts } from '../../../selectors/selectors'; import { ConnectAccountsModalList } from './connect-accounts-modal-list'; diff --git a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.types.ts b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.types.ts index c5c28678e689..4c510166d48f 100644 --- a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.types.ts +++ b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.types.ts @@ -1,4 +1,4 @@ -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; export type KeyringMetadata = { type: string; diff --git a/ui/components/multichain/connected-site-menu/__snapshots__/connected-site-menu.test.js.snap b/ui/components/multichain/connected-site-menu/__snapshots__/connected-site-menu.test.js.snap index fa6f6a0b202a..18b794d1e971 100644 --- a/ui/components/multichain/connected-site-menu/__snapshots__/connected-site-menu.test.js.snap +++ b/ui/components/multichain/connected-site-menu/__snapshots__/connected-site-menu.test.js.snap @@ -32,7 +32,7 @@ exports[`Connected Site Menu should render the site menu in connected state 1`] style="bottom: -1px; right: -4px; z-index: 1;" >
    @@ -74,7 +74,7 @@ exports[`Connected Site Menu should render the site menu in not connected state style="bottom: -1px; right: -4px; z-index: 1;" >
    diff --git a/ui/components/multichain/connected-site-menu/connected-site-menu.js b/ui/components/multichain/connected-site-menu/connected-site-menu.js index 4f532710288e..cbceafa7d99f 100644 --- a/ui/components/multichain/connected-site-menu/connected-site-menu.js +++ b/ui/components/multichain/connected-site-menu/connected-site-menu.js @@ -88,9 +88,9 @@ export const ConnectedSiteMenu = ({ borderColor={ isConnectedtoOtherAccountOrSnap ? BorderColor.successDefault - : BackgroundColor.backgroundDefault + : BorderColor.backgroundDefault } - borderWidth={isConnectedtoOtherAccountOrSnap ? 2 : 3} + borderWidth={2} /> } > diff --git a/ui/components/multichain/connected-status/connected-status.tsx b/ui/components/multichain/connected-status/connected-status.tsx index 83dc0c77ec45..8de3d7c4b38b 100644 --- a/ui/components/multichain/connected-status/connected-status.tsx +++ b/ui/components/multichain/connected-status/connected-status.tsx @@ -3,7 +3,6 @@ import { useSelector } from 'react-redux'; import { BackgroundColor, BorderColor, - Color, } from '../../../helpers/constants/design-system'; import { isAccountConnectedToCurrentTab } from '../../../selectors'; import { @@ -43,11 +42,11 @@ export const ConnectedStatus: React.FC = ({ status = STATUS_CONNECTED_TO_ANOTHER_ACCOUNT; } - let badgeBorderColor = BackgroundColor.backgroundDefault; // TODO: Replace it once border-color has this value. - let badgeBackgroundColor = Color.borderMuted; // //TODO: Replace it once Background color has this value. + let badgeBorderColor = BorderColor.backgroundDefault; // TODO: Replace it once border-color has this value. + let badgeBackgroundColor = BackgroundColor.iconAlternative; let tooltipText = t('statusNotConnected'); if (status === STATUS_CONNECTED) { - badgeBorderColor = BackgroundColor.backgroundDefault; + badgeBorderColor = BorderColor.backgroundDefault; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: type 'string' can't be used to index type '{}' badgeBackgroundColor = BackgroundColor.successDefault; diff --git a/ui/components/multichain/create-account/create-account.tsx b/ui/components/multichain/create-account/create-account.tsx index 446d487482e5..81e63ff60b39 100644 --- a/ui/components/multichain/create-account/create-account.tsx +++ b/ui/components/multichain/create-account/create-account.tsx @@ -8,7 +8,7 @@ import React, { } from 'react'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { Box, ButtonPrimary, diff --git a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx index 194a8c6399df..d04763902247 100644 --- a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx +++ b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import { CreateAccount } from '..'; import { Box, ModalHeader } from '../../component-library'; diff --git a/ui/components/multichain/import-tokens-modal/import-tokens-modal-confirm.js b/ui/components/multichain/import-tokens-modal/import-tokens-modal-confirm.js index c8817e59612d..e9c2c05a1c8a 100644 --- a/ui/components/multichain/import-tokens-modal/import-tokens-modal-confirm.js +++ b/ui/components/multichain/import-tokens-modal/import-tokens-modal-confirm.js @@ -2,6 +2,7 @@ import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; import { getCurrentNetwork, + getPendingTokens, getTestNetworkBackgroundColor, getTokenList, } from '../../../selectors'; @@ -22,7 +23,6 @@ import { AlignItems, FlexDirection, } from '../../../helpers/constants/design-system'; -import { getPendingTokens } from '../../../ducks/metamask/metamask'; import TokenBalance from '../../ui/token-balance/token-balance'; import { I18nContext } from '../../../contexts/i18n'; diff --git a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js index b6ffda5b8d9e..41a28a5363ab 100644 --- a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js +++ b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js @@ -29,6 +29,7 @@ import { getCurrentNetwork, getTestNetworkBackgroundColor, getTokenExchangeRates, + getPendingTokens, } from '../../../selectors'; import { addImportedTokens, @@ -90,10 +91,7 @@ import { } from '../../../helpers/utils/util'; import { tokenInfoGetter } from '../../../helpers/utils/token-util'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { - getNativeCurrency, - getPendingTokens, -} from '../../../ducks/metamask/metamask'; +import { getNativeCurrency } from '../../../ducks/metamask/metamask'; import { MetaMetricsEventCategory, MetaMetricsEventName, diff --git a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx index d29b679d3111..b6c1d23eb07b 100644 --- a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx +++ b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { parseCaipChainId } from '@metamask/utils'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { getMultichainAccountUrl, getMultichainBlockExplorerUrl, diff --git a/ui/components/multichain/network-list-menu/network-list-menu.test.js b/ui/components/multichain/network-list-menu/network-list-menu.test.js index ec4539aa55da..90ed2fca6809 100644 --- a/ui/components/multichain/network-list-menu/network-list-menu.test.js +++ b/ui/components/multichain/network-list-menu/network-list-menu.test.js @@ -143,7 +143,6 @@ const render = ({ [CHAIN_IDS.LINEA_MAINNET]: true, }, }, - useRequestQueue: true, domains: { ...(selectedTabOriginInDomainsState ? { [origin]: selectedNetworkClientId } diff --git a/ui/components/multichain/network-list-menu/network-list-menu.tsx b/ui/components/multichain/network-list-menu/network-list-menu.tsx index 481ddfe5142f..491ae289b19c 100644 --- a/ui/components/multichain/network-list-menu/network-list-menu.tsx +++ b/ui/components/multichain/network-list-menu/network-list-menu.tsx @@ -46,7 +46,6 @@ import { getOnboardedInThisUISession, getShowNetworkBanner, getOriginOfCurrentTab, - getUseRequestQueue, getEditedNetwork, getOrderedNetworksList, getIsAddingNewNetwork, @@ -120,7 +119,6 @@ export const NetworkListMenu = ({ onClose }: { onClose: () => void }) => { const showTestNetworks = useSelector(getShowTestNetworks); const currentChainId = useSelector(getCurrentChainId); const selectedTabOrigin = useSelector(getOriginOfCurrentTab); - const useRequestQueue = useSelector(getUseRequestQueue); const isUnlocked = useSelector(getIsUnlocked); const domains = useSelector(getAllDomains); const orderedNetworksList = useSelector(getOrderedNetworksList); @@ -309,11 +307,7 @@ export const NetworkListMenu = ({ onClose }: { onClose: () => void }) => { // If presently on a dapp, communicate a change to // the dapp via silent switchEthereumChain that the // network has changed due to user action - if ( - useRequestQueue && - selectedTabOrigin && - domains[selectedTabOrigin] - ) { + if (selectedTabOrigin && domains[selectedTabOrigin]) { setNetworkClientIdForDomain(selectedTabOrigin, networkClientId); } diff --git a/ui/components/multichain/nft-item/index.scss b/ui/components/multichain/nft-item/index.scss index e331c6653131..7977335c6aee 100644 --- a/ui/components/multichain/nft-item/index.scss +++ b/ui/components/multichain/nft-item/index.scss @@ -1,16 +1,20 @@ +@use "design-system"; + .nft-item { + &__card { + cursor: pointer; + } + &__container { width: 100%; padding: 0; border-radius: 8px; - cursor: unset; } &__badge-wrapper { max-width: 100%; position: relative; align-self: center; - cursor: unset; &__clickable { cursor: pointer; @@ -19,7 +23,33 @@ &__item-image { border-radius: 8px; - padding: 0; + width: 100%; + object-fit: cover; + aspect-ratio: 1; + } + + &__item-image--hidden { + border-radius: 8px; + width: 100%; + object-fit: cover; + aspect-ratio: 1; + background: rgba(255, 255, 255, 0.5); + mix-blend-mode: lighten; + } + + + + @include design-system.screen-sm-max { + &__item-image--hidden { + background: rgba(255, 255, 255, 0.5); + mix-blend-mode: lighten; + } + } + + &__item-detail { + border-radius: 8px; + object-fit: cover; + aspect-ratio: 1; width: 100%; height: 100%; } diff --git a/ui/components/multichain/nft-item/index.js b/ui/components/multichain/nft-item/index.ts similarity index 100% rename from ui/components/multichain/nft-item/index.js rename to ui/components/multichain/nft-item/index.ts diff --git a/ui/components/multichain/nft-item/nft-item.js b/ui/components/multichain/nft-item/nft-item.js deleted file mode 100644 index 3ebb247b5c5c..000000000000 --- a/ui/components/multichain/nft-item/nft-item.js +++ /dev/null @@ -1,142 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import classnames from 'classnames'; -import { useSelector } from 'react-redux'; -import NftDefaultImage from '../../app/assets/nfts/nft-default-image/nft-default-image'; -import { - AvatarNetwork, - AvatarNetworkSize, - BadgeWrapper, - BadgeWrapperAnchorElementShape, - Box, -} from '../../component-library'; -import { - BackgroundColor, - Display, - JustifyContent, -} from '../../../helpers/constants/design-system'; -import { - getIpfsGateway, - getOpenSeaEnabled, - getTestNetworkBackgroundColor, -} from '../../../selectors'; - -export const NftItem = ({ - alt, - name, - src, - networkName, - networkSrc, - tokenId, - onClick, - clickable, - isIpfsURL, - badgeWrapperClassname, -}) => { - const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor); - const isIpfsEnabled = useSelector(getIpfsGateway); - const openSeaEnabled = useSelector(getOpenSeaEnabled); - - const ipfsImageIsRenderable = isIpfsEnabled && isIpfsURL && src; - const openseaImageIsRenderable = openSeaEnabled && src && !isIpfsURL; - - const nftImageComponentToRender = - ipfsImageIsRenderable || openseaImageIsRenderable ? ( - - ) : ( - - ); - - return ( - - - } - > - {nftImageComponentToRender} - - - ); -}; - -NftItem.propTypes = { - /** - * NFT media source - */ - src: PropTypes.string, - /** - * Alt text for the NFT - */ - alt: PropTypes.string.isRequired, - /** - * The NFT's name - */ - name: PropTypes.string, - /** - * Name of the network the NFT lives on - */ - networkName: PropTypes.string.isRequired, - /** - * Image that represents the network - */ - networkSrc: PropTypes.string, - /** - * Token ID of the NFT - */ - tokenId: PropTypes.string.isRequired, - /** - * Executes when the NFT is clicked - */ - onClick: PropTypes.func, - /** - * Represents if the NFT is clickable for larger image - */ - clickable: PropTypes.bool, - /** - * Whether the src url resolve to ipfs - */ - isIpfsURL: PropTypes.bool, - badgeWrapperClassname: PropTypes.string, -}; diff --git a/ui/components/multichain/nft-item/nft-item.tsx b/ui/components/multichain/nft-item/nft-item.tsx new file mode 100644 index 000000000000..b477a1439c62 --- /dev/null +++ b/ui/components/multichain/nft-item/nft-item.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import classnames from 'classnames'; +import { useSelector } from 'react-redux'; +import NftDefaultImage from '../../app/assets/nfts/nft-default-image/nft-default-image'; +import { + AvatarNetwork, + AvatarNetworkSize, + BadgeWrapper, + BadgeWrapperAnchorElementShape, + Box, + Icon, + IconName, + Text, +} from '../../component-library'; +import { + AlignItems, + BackgroundColor, + Display, + IconColor, + JustifyContent, + TextColor, + TextVariant, +} from '../../../helpers/constants/design-system'; +import { + getIpfsGateway, + getOpenSeaEnabled, + getTestNetworkBackgroundColor, +} from '../../../selectors'; +import { NFT } from '../asset-picker-amount/asset-picker-modal/types'; + +type NftItemProps = { + nft?: NFT; + alt: string; + src: string | undefined; + name?: string; + tokenId?: string; + networkName: string; + networkSrc?: string; + onClick?: () => void; + isIpfsURL?: boolean; + detailView?: boolean; + clickable?: boolean; + privacyMode?: boolean; + badgeWrapperClassname?: string; +}; + +export const NftItem = ({ + nft, + alt, + src, + networkName, + networkSrc, + onClick, + detailView, + clickable, + privacyMode, + isIpfsURL, + badgeWrapperClassname = '', +}: NftItemProps) => { + const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor); + const isIpfsEnabled = useSelector(getIpfsGateway); + const openSeaEnabled = useSelector(getOpenSeaEnabled); + + const ipfsImageIsRenderable = isIpfsEnabled && isIpfsURL && src; + const openseaImageIsRenderable = openSeaEnabled && src && !isIpfsURL; + + const nftImageComponentToRender = + ipfsImageIsRenderable || openseaImageIsRenderable ? ( + + + {privacyMode && ( + + )} + + ) : ( + + ); + + return ( + + + + } + > + {nftImageComponentToRender} + + + + {nft?.name} + + + {nft?.collection?.name} + + + ); +}; diff --git a/ui/components/multichain/pages/connections/__snapshots__/connections.test.tsx.snap b/ui/components/multichain/pages/connections/__snapshots__/connections.test.tsx.snap index ad2dc490d7c0..9250404743fc 100644 --- a/ui/components/multichain/pages/connections/__snapshots__/connections.test.tsx.snap +++ b/ui/components/multichain/pages/connections/__snapshots__/connections.test.tsx.snap @@ -171,7 +171,7 @@ exports[`Connections Content should render correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    diff --git a/ui/components/multichain/pages/connections/components/connections.types.tsx b/ui/components/multichain/pages/connections/components/connections.types.tsx index 9bdbf86d9d95..2d459e047f46 100644 --- a/ui/components/multichain/pages/connections/components/connections.types.tsx +++ b/ui/components/multichain/pages/connections/components/connections.types.tsx @@ -1,4 +1,4 @@ -import { type InternalAccount } from '@metamask/keyring-api'; +import { type InternalAccount } from '@metamask/keyring-internal-api'; // Define ConnectedSite interface export type ConnectedSite = { diff --git a/ui/components/multichain/pages/connections/connections.tsx b/ui/components/multichain/pages/connections/connections.tsx index 4a8b188b86b6..0592f5de84ee 100644 --- a/ui/components/multichain/pages/connections/connections.tsx +++ b/ui/components/multichain/pages/connections/connections.tsx @@ -18,7 +18,6 @@ import { getURLHost } from '../../../../helpers/utils/util'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { getConnectedSitesList, - getInternalAccounts, getOrderedConnectedAccountsForConnectedDapp, getPermissionSubjects, getPermittedAccountsByOrigin, @@ -43,7 +42,6 @@ import { IconSize, Text, } from '../../../component-library'; -import { mergeAccounts } from '../../account-list-menu/account-list-menu'; import { AccountListItem, AccountListItemMenuTypes, @@ -109,11 +107,6 @@ export const Connections = () => { getOrderedConnectedAccountsForConnectedDapp(state, activeTabOrigin), ); const selectedAccount = useSelector(getSelectedAccount); - const internalAccounts = useSelector(getInternalAccounts); - const mergedAccounts = mergeAccounts( - connectedAccounts, - internalAccounts, - ) as AccountType[]; const permittedAccountsByOrigin = useSelector( getPermittedAccountsByOrigin, @@ -168,14 +161,14 @@ export const Connections = () => { } }; - // In the mergeAccounts, we need the lastSelected value to determine which connectedAccount was last selected. - const latestSelected = mergedAccounts.findIndex( + // In the connectedAccounts, we need the lastSelected value to determine which connectedAccount was last selected. + const latestSelected = connectedAccounts.findIndex( // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any (_account: any, index: any) => { return ( index === - mergedAccounts.reduce( + connectedAccounts.reduce( ( indexOfAccountWIthHighestLastSelected: number, currentAccountToCompare: AccountType, @@ -185,7 +178,7 @@ export const Connections = () => { ) => { const currentLastSelected = currentAccountToCompare.metadata.lastSelected ?? 0; - const accountAtIndexLastSelected = mergedAccounts[ + const accountAtIndexLastSelected = connectedAccounts[ indexOfAccountWIthHighestLastSelected ].metadata.lastSelected ? i @@ -251,11 +244,11 @@ export const Connections = () => {
    - {permittedAccounts.length > 0 && mergeAccounts.length > 0 ? ( + {permittedAccounts.length > 0 && connectedAccounts.length > 0 ? ( {/* TODO: Replace `any` with type */} {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {mergedAccounts.map((account: AccountType, index: any) => { + {connectedAccounts.map((account: AccountType, index: any) => { const connectedSites: ConnectedSites = {}; const connectedSite = connectedSites[account.address]?.find( ({ origin }) => origin === activeTabOrigin, @@ -271,7 +264,7 @@ export const Connections = () => { { /> ) : null} - {permittedAccounts.length > 0 && mergeAccounts.length > 0 ? ( + {permittedAccounts.length > 0 && connectedAccounts.length > 0 ? ( { diff --git a/ui/components/multichain/pages/review-permissions-page/review-permission.types.tsx b/ui/components/multichain/pages/review-permissions-page/review-permission.types.tsx index 6111dd8d946f..a92aba300c1a 100644 --- a/ui/components/multichain/pages/review-permissions-page/review-permission.types.tsx +++ b/ui/components/multichain/pages/review-permissions-page/review-permission.types.tsx @@ -1,4 +1,4 @@ -import { type InternalAccount } from '@metamask/keyring-api'; +import { type InternalAccount } from '@metamask/keyring-internal-api'; // Define ConnectedSite interface export type ConnectedSite = { diff --git a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx index 95a8ea394000..a594635d7cb0 100644 --- a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx +++ b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx @@ -2,7 +2,8 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useParams } from 'react-router-dom'; import { NonEmptyArray } from '@metamask/utils'; -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { NetworkConfiguration } from '@metamask/network-controller'; import { AlignItems, @@ -14,7 +15,6 @@ import { useI18nContext } from '../../../../hooks/useI18nContext'; import { getNetworkConfigurationsByChainId } from '../../../../../shared/modules/selectors/networks'; import { getConnectedSitesList, - getInternalAccounts, getPermissionSubjects, getPermittedAccountsForSelectedTab, getPermittedChainsForSelectedTab, @@ -51,7 +51,6 @@ import { DisconnectType, } from '../../disconnect-all-modal/disconnect-all-modal'; import { PermissionsHeader } from '../../permissions-header/permissions-header'; -import { mergeAccounts } from '../../account-list-menu/account-list-menu'; import { MergedInternalAccount } from '../../../../selectors/selectors.types'; import { TEST_CHAINS } from '../../../../../shared/constants/network'; import { SiteCell } from './site-cell/site-cell'; @@ -147,12 +146,11 @@ export const ReviewPermissions = () => { }; const accounts = useSelector(getUpdatedAndSortedAccounts); - const internalAccounts = useSelector(getInternalAccounts); - const mergedAccounts: MergedInternalAccount[] = useMemo(() => { - return mergeAccounts(accounts, internalAccounts).filter( - (account: InternalAccount) => isEvmAccountType(account.type), + const evmAccounts: MergedInternalAccount[] = useMemo(() => { + return accounts.filter((account: InternalAccount) => + isEvmAccountType(account.type), ); - }, [accounts, internalAccounts]); + }, [accounts]); const connectedAccountAddresses = useSelector((state) => getPermittedAccountsForSelectedTab(state, activeTabOrigin), @@ -175,6 +173,11 @@ export const ReviewPermissions = () => { setShowAccountToast(true); }; + const hideAllToasts = () => { + setShowAccountToast(false); + setShowNetworkToast(false); + }; + return ( { ) : ( diff --git a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.test.tsx b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.test.tsx new file mode 100644 index 000000000000..affd55cfaa66 --- /dev/null +++ b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.test.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import { Provider } from 'react-redux'; +import { render, fireEvent } from '@testing-library/react'; +import configureStore from '../../../../../store/store'; +import { SiteCell } from './site-cell'; + +describe('SiteCell', () => { + const store = configureStore({ + metamask: { + useBlockie: false, + }, + }); + + describe('toast handling', () => { + it('should call hideAllToasts when edit accounts is clicked', () => { + const hideAllToasts = jest.fn(); + const { getAllByTestId } = render( + + undefined} + onSelectChainIds={() => undefined} + selectedAccountAddresses={[]} + selectedChainIds={[]} + hideAllToasts={hideAllToasts} + /> + , + ); + + const editButtons = getAllByTestId('edit'); + fireEvent.click(editButtons[0]); + expect(hideAllToasts).toHaveBeenCalled(); + }); + + it('should call hideAllToasts when edit networks is clicked', () => { + const hideAllToasts = jest.fn(); + const { getAllByTestId } = render( + + undefined} + onSelectChainIds={() => undefined} + selectedAccountAddresses={[]} + selectedChainIds={[]} + hideAllToasts={hideAllToasts} + /> + , + ); + + const editButtons = getAllByTestId('edit'); + fireEvent.click(editButtons[1]); + expect(hideAllToasts).toHaveBeenCalled(); + }); + + it('should not throw if hideAllToasts is not provided', () => { + const { getAllByTestId } = render( + + undefined} + onSelectChainIds={() => undefined} + selectedAccountAddresses={[]} + selectedChainIds={[]} + /> + , + ); + + expect(() => { + const editButtons = getAllByTestId('edit'); + fireEvent.click(editButtons[0]); + fireEvent.click(editButtons[1]); + }).not.toThrow(); + }); + }); +}); diff --git a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.tsx b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.tsx index fcb104937e28..1c91489d0d1f 100644 --- a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.tsx +++ b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell.tsx @@ -38,6 +38,7 @@ type SiteCellProps = { selectedAccountAddresses: string[]; selectedChainIds: string[]; isConnectFlow?: boolean; + hideAllToasts?: () => void; }; export const SiteCell: React.FC = ({ @@ -49,6 +50,7 @@ export const SiteCell: React.FC = ({ selectedAccountAddresses, selectedChainIds, isConnectFlow, + hideAllToasts = () => undefined, }) => { const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); @@ -91,6 +93,30 @@ export const SiteCell: React.FC = ({ ? t('requestingForNetwork', [selectedNetworks[0].name]) : t('requestingFor'); + const handleOpenAccountsModal = () => { + hideAllToasts?.(); + setShowEditAccountsModal(true); + trackEvent({ + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.ViewPermissionedAccounts, + properties: { + location: 'Connect view, Permissions toast, Permissions (dapp)', + }, + }); + }; + + const handleOpenNetworksModal = () => { + hideAllToasts?.(); + setShowEditNetworksModal(true); + trackEvent({ + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.ViewPermissionedNetworks, + properties: { + location: 'Connect view, Permissions toast, Permissions (dapp)', + }, + }); + }; + return ( <> = ({ connectedMessage={accountMessageConnectedState} unconnectedMessage={accountMessageNotConnectedState} isConnectFlow={isConnectFlow} - onClick={() => { - setShowEditAccountsModal(true); - trackEvent({ - category: MetaMetricsEventCategory.Navigation, - event: MetaMetricsEventName.ViewPermissionedAccounts, - properties: { - location: 'Connect view, Permissions toast, Permissions (dapp)', - }, - }); - }} + onClick={handleOpenAccountsModal} paddingBottomValue={2} paddingTopValue={0} content={ @@ -136,16 +153,7 @@ export const SiteCell: React.FC = ({ connectedMessage={networkMessageConnectedState} unconnectedMessage={networkMessageNotConnectedState} isConnectFlow={isConnectFlow} - onClick={() => { - setShowEditNetworksModal(true); - trackEvent({ - category: MetaMetricsEventCategory.Navigation, - event: MetaMetricsEventName.ViewPermissionedNetworks, - properties: { - location: 'Connect view, Permissions toast, Permissions (dapp)', - }, - }); - }} + onClick={handleOpenNetworksModal} paddingTopValue={2} paddingBottomValue={0} content={} diff --git a/ui/components/multichain/pages/send/__snapshots__/send.test.js.snap b/ui/components/multichain/pages/send/__snapshots__/send.test.js.snap index 7b0605b7ea60..a23161205c8e 100644 --- a/ui/components/multichain/pages/send/__snapshots__/send.test.js.snap +++ b/ui/components/multichain/pages/send/__snapshots__/send.test.js.snap @@ -348,7 +348,7 @@ exports[`SendPage render and initialization should render correctly even when a style="bottom: -1px; right: 2px;" >
    diff --git a/ui/components/multichain/pages/send/components/__snapshots__/your-accounts.test.tsx.snap b/ui/components/multichain/pages/send/components/__snapshots__/your-accounts.test.tsx.snap index 71431a330f94..6c0e4e16ef66 100644 --- a/ui/components/multichain/pages/send/components/__snapshots__/your-accounts.test.tsx.snap +++ b/ui/components/multichain/pages/send/components/__snapshots__/your-accounts.test.tsx.snap @@ -122,7 +122,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    @@ -421,7 +421,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    @@ -720,7 +720,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    @@ -1028,7 +1028,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    @@ -1327,7 +1327,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    @@ -1520,7 +1520,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = `

    - snap-name (Beta) + mock snap name (Beta)

    @@ -1639,7 +1639,7 @@ exports[`SendPageYourAccounts render renders correctly 1`] = ` style="bottom: -1px; right: 2px;" >
    diff --git a/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.test.tsx b/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.test.tsx index 1ef3347e3133..9fa58e610bba 100644 --- a/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.test.tsx +++ b/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.test.tsx @@ -4,10 +4,10 @@ import { getNativeCurrency, getConversionRate, getGasFeeEstimates, + getCurrentCurrency, } from '../../../../../../../ducks/metamask/metamask'; import { getUsedSwapsGasPrice } from '../../../../../../../ducks/swaps/swaps'; import { - getCurrentCurrency, checkNetworkAndAccountSupports1559, getIsSwapsChain, } from '../../../../../../../selectors'; diff --git a/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.tsx b/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.tsx index 04fa59ce072a..f08ab47086a9 100644 --- a/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.tsx +++ b/ui/components/multichain/pages/send/components/quote-card/hooks/useEthFeeData.tsx @@ -6,10 +6,10 @@ import { getConversionRate, getGasFeeEstimates, getNativeCurrency, + getCurrentCurrency, } from '../../../../../../../ducks/metamask/metamask'; import { EtherDenomination } from '../../../../../../../../shared/constants/common'; import { - getCurrentCurrency, checkNetworkAndAccountSupports1559, getIsSwapsChain, } from '../../../../../../../selectors/selectors'; diff --git a/ui/components/multichain/pages/send/components/recipient-content.tsx b/ui/components/multichain/pages/send/components/recipient-content.tsx index 6fb1b00134a4..7bd21578a927 100644 --- a/ui/components/multichain/pages/send/components/recipient-content.tsx +++ b/ui/components/multichain/pages/send/components/recipient-content.tsx @@ -95,7 +95,7 @@ export const SendPageRecipientContent = ({ const ipfsGateway = useSelector(getIpfsGateway); const nftImageURL = useGetAssetImageUrl( - sendAsset.details?.image ?? null, + sendAsset.details?.image ?? undefined, ipfsGateway, ); diff --git a/ui/components/multichain/pages/send/components/your-accounts.tsx b/ui/components/multichain/pages/send/components/your-accounts.tsx index e59d0aa2d5a1..6123bb1cac78 100644 --- a/ui/components/multichain/pages/send/components/your-accounts.tsx +++ b/ui/components/multichain/pages/send/components/your-accounts.tsx @@ -1,13 +1,9 @@ import React, { useContext, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { - EthAccountType, - InternalAccount, - KeyringAccountType, -} from '@metamask/keyring-api'; +import { EthAccountType, KeyringAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { getUpdatedAndSortedAccounts, - getInternalAccounts, getSelectedInternalAccount, } from '../../../../../selectors'; import { AccountListItem } from '../../..'; @@ -16,13 +12,11 @@ import { updateRecipient, updateRecipientUserInput, } from '../../../../../ducks/send'; -import { mergeAccounts } from '../../../account-list-menu/account-list-menu'; import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../../../shared/constants/metametrics'; -import { MergedInternalAccount } from '../../../../../selectors/selectors.types'; import { SendPageRow } from '.'; type SendPageYourAccountsProps = { @@ -39,19 +33,18 @@ export const SendPageYourAccounts = ({ // Your Accounts const accounts = useSelector(getUpdatedAndSortedAccounts); - const internalAccounts = useSelector(getInternalAccounts); - const mergedAccounts: MergedInternalAccount[] = useMemo(() => { - return mergeAccounts(accounts, internalAccounts).filter( - (account: InternalAccount) => allowedAccountTypes.includes(account.type), + const filteredAccounts = useMemo(() => { + return accounts.filter((account: InternalAccount) => + allowedAccountTypes.includes(account.type), ); - }, [accounts, internalAccounts]); + }, [accounts]); const selectedAccount = useSelector(getSelectedInternalAccount); return ( {/* TODO: Replace `any` with type */} {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} - {mergedAccounts.map((account: any) => ( + {filteredAccounts.map((account: any) => (
    network logo
    ?
    @@ -191,7 +191,7 @@ exports[`TokenListItem should display warning scam modal fallback when safechain class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    ?
    @@ -270,7 +270,7 @@ exports[`TokenListItem should render correctly 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    network logo
    ?
    @@ -403,7 +403,7 @@ exports[`TokenListItem should render crypto balance with warning scam 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    ?
    diff --git a/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.test.tsx b/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.test.tsx index f157afa64d8b..53ff99bd5d06 100644 --- a/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.test.tsx +++ b/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.test.tsx @@ -5,13 +5,13 @@ import { zeroAddress } from 'ethereumjs-util'; import { MarketDataDetails } from '@metamask/assets-controllers'; import { getIntlLocale } from '../../../../../ducks/locale/locale'; import { - getCurrentCurrency, getSelectedAccountCachedBalance, getTokensMarketData, } from '../../../../../selectors'; import { getCurrentChainId } from '../../../../../../shared/modules/selectors/networks'; import { getConversionRate, + getCurrentCurrency, getNativeCurrency, } from '../../../../../ducks/metamask/metamask'; import { PercentageAndAmountChange } from './percentage-and-amount-change'; @@ -25,7 +25,6 @@ jest.mock('../../../../../ducks/locale/locale', () => ({ })); jest.mock('../../../../../selectors', () => ({ - getCurrentCurrency: jest.fn(), getSelectedAccountCachedBalance: jest.fn(), getTokensMarketData: jest.fn(), })); @@ -35,6 +34,7 @@ jest.mock('../../../../../../shared/modules/selectors/networks', () => ({ })); jest.mock('../../../../../ducks/metamask/metamask', () => ({ + getCurrentCurrency: jest.fn(), getConversionRate: jest.fn(), getNativeCurrency: jest.fn(), })); diff --git a/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.tsx b/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.tsx index dc0aeaa5a25c..c0c3e83addb7 100644 --- a/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.tsx +++ b/ui/components/multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change.tsx @@ -11,7 +11,6 @@ import { } from '../../../../../helpers/constants/design-system'; import { getCurrentChainId } from '../../../../../../shared/modules/selectors/networks'; import { - getCurrentCurrency, getSelectedAccountCachedBalance, getTokensMarketData, } from '../../../../../selectors'; @@ -20,6 +19,7 @@ import { EtherDenomination } from '../../../../../../shared/constants/common'; import { Numeric } from '../../../../../../shared/modules/Numeric'; import { getConversionRate, + getCurrentCurrency, getNativeCurrency, } from '../../../../../ducks/metamask/metamask'; import { diff --git a/ui/components/multichain/token-list-item/token-list-item.tsx b/ui/components/multichain/token-list-item/token-list-item.tsx index 40b91a001f17..d5ce348e0297 100644 --- a/ui/components/multichain/token-list-item/token-list-item.tsx +++ b/ui/components/multichain/token-list-item/token-list-item.tsx @@ -40,7 +40,6 @@ import { } from '../../component-library'; import { getMetaMetricsId, - getTestNetworkBackgroundColor, getParticipateInMetaMetrics, getDataCollectionForMarketing, getMarketData, @@ -228,7 +227,6 @@ export const TokenListItem = ({ ); // Used for badge icon const allNetworks = useSelector(getNetworkConfigurationsByChainId); - const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor); return ( } diff --git a/ui/components/ui/button-group/__snapshots__/button-group-component.test.js.snap b/ui/components/ui/button-group/__snapshots__/button-group-component.test.js.snap index 7e8116227458..b04aa2fbd4f1 100644 --- a/ui/components/ui/button-group/__snapshots__/button-group-component.test.js.snap +++ b/ui/components/ui/button-group/__snapshots__/button-group-component.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ButtonGroup Component should match snapshot 1`] = ` +exports[`ButtonGroup Component should match snapshot with default variant 1`] = `
    `; + +exports[`ButtonGroup Component should match snapshot with radiogroup variant 1`] = ` +
    +
    + +
    +
    +`; diff --git a/ui/components/ui/button-group/button-group-component.test.js b/ui/components/ui/button-group/button-group-component.test.js index 2aaccad78a0c..584042491867 100644 --- a/ui/components/ui/button-group/button-group-component.test.js +++ b/ui/components/ui/button-group/button-group-component.test.js @@ -16,15 +16,25 @@ describe('ButtonGroup Component', () => { , - , - , + diff --git a/ui/components/ui/menu/menu.scss b/ui/components/ui/menu/menu.scss index d43545e67fd0..2eed45745d9e 100644 --- a/ui/components/ui/menu/menu.scss +++ b/ui/components/ui/menu/menu.scss @@ -33,7 +33,7 @@ text-align: start; align-items: center; width: 100%; - padding: 14px 16px; + padding: 16px; cursor: pointer; color: inherit; diff --git a/ui/components/ui/new-network-info/index.js b/ui/components/ui/new-network-info/index.js deleted file mode 100644 index e4bd2dcdbd3e..000000000000 --- a/ui/components/ui/new-network-info/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './new-network-info'; diff --git a/ui/components/ui/new-network-info/index.scss b/ui/components/ui/new-network-info/index.scss deleted file mode 100644 index 989a927bb251..000000000000 --- a/ui/components/ui/new-network-info/index.scss +++ /dev/null @@ -1,59 +0,0 @@ -.new-network-info { - &__wrapper { - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.214); - border-radius: 8px; - - .popover-footer { - border-top: none; - width: 100%; - gap: 16px; - - .footer__button { - flex: 1; - flex-grow: 1; - white-space: nowrap; - overflow: hidden; - } - - a:hover > span { - color: var(--inherit); - } - } - - .popover-header { - padding-bottom: 1px; - } - - .popover-header__button { - color: var(--color-icon-default); - } - } - - &__token-box { - align-self: center; - margin-top: 8px; - max-width: 245px; - } - - &__button { - display: contents; - padding: 0; - } - - &__bullet-icon-container { - background-color: var(--color-info-muted); - border-radius: 50%; - padding: 6px; - - .mm-icon { - display: flex; - color: var(--color-info-default); - } - } -} - -.chip--with-left-icon { - padding-left: 8px; - padding-top: 8px; - padding-bottom: 8px; -} diff --git a/ui/components/ui/new-network-info/new-network-info.js b/ui/components/ui/new-network-info/new-network-info.js deleted file mode 100644 index 9d4df0ec63ec..000000000000 --- a/ui/components/ui/new-network-info/new-network-info.js +++ /dev/null @@ -1,267 +0,0 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { TOKEN_API_METASWAP_CODEFI_URL } from '../../../../shared/constants/tokens'; -import fetchWithCache from '../../../../shared/lib/fetch-with-cache'; -import { I18nContext } from '../../../contexts/i18n'; -import { getProviderConfig } from '../../../../shared/modules/selectors/networks'; -import { - AlignItems, - BackgroundColor, - BorderColor, - Color, - Display, - FlexDirection, - TextAlign, - TextColor, - TextVariant, -} from '../../../helpers/constants/design-system'; -import { - getCurrentNetwork, - getIsBridgeChain, - getMetaMetricsId, - getUseTokenDetection, - getUseExternalServices, - getParticipateInMetaMetrics, - getDataCollectionForMarketing, -} from '../../../selectors'; -import { - PickerNetwork, - Text, - Box, - Button, - Icon, - IconName, - ButtonPrimarySize, - IconSize, - AvatarNetworkSize, -} from '../../component-library'; -import Popover from '../popover'; -import { getPortfolioUrl } from '../../../helpers/utils/portfolio'; -import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; - -export default function NewNetworkInfo() { - const t = useContext(I18nContext); - const [tokenDetectionSupported, setTokenDetectionSupported] = useState(false); - const [showPopup, setShowPopup] = useState(true); - const [isLoading, setIsLoading] = useState(true); - const autoDetectToken = useSelector(getUseTokenDetection); - const areExternalServicesEnabled = useSelector(getUseExternalServices); - const providerConfig = useSelector(getProviderConfig); - const currentNetwork = useSelector(getCurrentNetwork); - const metaMetricsId = useSelector(getMetaMetricsId); - const isBridgeChain = useSelector(getIsBridgeChain); - const isMetaMetricsEnabled = useSelector(getParticipateInMetaMetrics); - const isMarketingEnabled = useSelector(getDataCollectionForMarketing); - - const onCloseClick = () => { - setShowPopup(false); - }; - - const checkTokenDetection = useCallback(async () => { - setIsLoading(true); - const fetchedTokenData = await fetchWithCache({ - url: `${TOKEN_API_METASWAP_CODEFI_URL}${providerConfig.chainId}?occurrenceFloor=100&includeNativeAssets=false`, - functionName: 'getIsTokenDetectionSupported', - }); - const isTokenDetectionSupported = !fetchedTokenData?.error; - setTokenDetectionSupported(isTokenDetectionSupported); - setIsLoading(false); - }, [providerConfig.chainId]); - - useEffect(() => { - if (!areExternalServicesEnabled) { - return; - } - checkTokenDetection(); - // we want to only fetch once - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return ( - !isLoading && - showPopup && ( - - - - - } - > - - - - {t('thingsToKeep')} - - - {providerConfig.ticker && ( - - - - - - - {t('gasIsETH', [providerConfig.ticker])} - - - {t('nativeToken', [providerConfig.ticker])} - - - - )} - - - - - - - {t('bridgeDontSend')} - - - {isBridgeChain - ? t('attemptSendingAssetsWithPortfolio', [ - - - {t('metamaskPortfolio')} - - , - ]) - : t('attemptSendingAssets')} - - - - - {!autoDetectToken || !tokenDetectionSupported ? ( - - - - - - - {t('addingTokens')} - - - {t('tokenShowUp')} - {t('clickToManuallyAdd')} - - - - ) : null} - - - - ) - ); -} diff --git a/ui/components/ui/new-network-info/new-network-info.stories.js b/ui/components/ui/new-network-info/new-network-info.stories.js deleted file mode 100644 index 9d70ef07b5f0..000000000000 --- a/ui/components/ui/new-network-info/new-network-info.stories.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import NewNetworkInfo from '.'; - -export default { - title: 'Components/UI/NewNetworkInfo', -}; - -export const DefaultStory = () => ; - -DefaultStory.storyName = 'Default'; diff --git a/ui/components/ui/new-network-info/new-network-info.test.js b/ui/components/ui/new-network-info/new-network-info.test.js deleted file mode 100644 index 59d98ab358fd..000000000000 --- a/ui/components/ui/new-network-info/new-network-info.test.js +++ /dev/null @@ -1,223 +0,0 @@ -import React from 'react'; -import { waitFor } from '@testing-library/react'; -import configureMockStore from 'redux-mock-store'; -import nock from 'nock'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; -import { mockNetworkState } from '../../../../test/stub/networks'; -import { CHAIN_IDS } from '../../../../shared/constants/network'; -import NewNetworkInfo from './new-network-info'; - -const fetchWithCache = - require('../../../../shared/lib/fetch-with-cache').default; - -const localStorageMock = (function () { - let store = {}; - return { - getItem(key) { - return store[key]; - }, - - setItem(key, value) { - store[key] = value.toString(); - }, - - clear() { - store = {}; - }, - - removeItem(key) { - delete store[key]; - }, - }; -})(); -Object.defineProperty(window, 'localStorage', { value: localStorageMock }); - -const responseOfTokenList = []; -describe('NewNetworkInfo', () => { - afterEach(() => { - nock.cleanAll(); - }); - - describe('fetch token successfully', () => { - const state = { - metamask: { - ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }), - useExternalServices: true, - useTokenDetection: false, - currencyRates: {}, - }, - }; - - it('should match snapshot and render component', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .reply(200, responseOfTokenList); - - const store = configureMockStore()(state); - const { getByText, getByTestId } = renderWithProvider( - , - store, - ); - // wait for the fetch to finish - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - // render title - expect(getByText("You're now using")).toBeInTheDocument(); - // render the network name - expect(getByText('Ethereum Mainnet')).toBeInTheDocument(); - expect( - getByTestId('new-network-info__bullet-paragraph').textContent, - ).toMatchInlineSnapshot( - `"Gas is ETH The native token on this network is ETH. It is the token used for gas fees. "`, - ); - }); - - it('should render a question mark icon image for non-main network', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .reply(200, responseOfTokenList); - - const updateTokenDetectionSupportStatus = await fetchWithCache({ - url: 'https://token.api.cx.metamask.io/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false', - functionName: 'getTokenDetectionSupportStatus', - }); - - state.metamask.nativeCurrency = ''; - - const store = configureMockStore()( - state, - updateTokenDetectionSupportStatus, - ); - const { container, getByTestId } = renderWithProvider( - , - store, - ); - // wait for the fetch to finish - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - - const questionMark = container.querySelector('.question'); - - expect(questionMark).toBeDefined(); - }); - - it('should not render first bullet when provider ticker is null', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x3?occurrenceFloor=100&includeNativeAssets=false') - .reply(200, '{"error":"ChainId 0x3 is not supported"}'); - - const store = configureMockStore()({ - metamask: { - ...state.metamask, - ...mockNetworkState({ chainId: '0x3', ticker: undefined }), - }, - }); - const { container, getByTestId } = renderWithProvider( - , - store, - ); - // wait for the fetch to finish - await new Promise((r) => setTimeout(r, 2000)); - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - const firstBox = container.querySelector( - 'new-network-info__content-box-1', - ); - - expect(firstBox).toBeNull(); - }); - - describe('add token link', () => { - const newState = { - metamask: { - ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }), - - useExternalServices: true, - useTokenDetection: true, - currencyRates: {}, - }, - }; - - it('should not render link when auto token detection is set true and token detection is supported', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .reply(200, responseOfTokenList); - - const store = configureMockStore()(newState); - const { getByTestId, queryByTestId } = renderWithProvider( - , - store, - ); - // should not render add token link - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - expect( - queryByTestId('new-network-info__add-token-manually'), - ).toBeNull(); - }); - - it('should render link when auto token detection is set true and token detection is not supported', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .replyWithError('something awful happened'); - - const store = configureMockStore()(newState); - const { getByTestId } = renderWithProvider(, store); - // render add token link when token is supported - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - }); - - it('should render link when auto token detection is set false but token detection is not supported', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .reply(403); - - const store = configureMockStore()(state); - const { getByTestId } = renderWithProvider(, store); - // render add token link when token is supported - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - expect( - getByTestId('new-network-info__add-token-manually'), - ).toBeInTheDocument(); - }); - - it('should render link when auto token detection is set false and token detection is supported', async () => { - nock('https://token.api.cx.metamask.io') - .get('/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false') - .reply(200, responseOfTokenList); - - const updateTokenDetectionSupportStatus = await fetchWithCache({ - url: 'https://token.api.cx.metamask.io/tokens/0x1?occurrenceFloor=100&includeNativeAssets=false', - functionName: 'getTokenDetectionSupportStatus', - }); - - const store = configureMockStore()( - state, - updateTokenDetectionSupportStatus, - ); - const { getByText, getByTestId } = renderWithProvider( - , - store, - ); - // wait for the fetch to finish - await waitFor(() => { - expect(getByTestId('new-network-info__wrapper')).toBeInTheDocument(); - }); - // render add token link when token is supported - expect( - getByText( - 'Your tokens may not automatically show up in your wallet. You can always add tokens manually.', - ), - ).toBeInTheDocument(); - }); - }); - }); -}); diff --git a/ui/components/ui/origin-pill/origin-pill.test.tsx b/ui/components/ui/origin-pill/origin-pill.test.tsx new file mode 100644 index 000000000000..13034a6a83e1 --- /dev/null +++ b/ui/components/ui/origin-pill/origin-pill.test.tsx @@ -0,0 +1,27 @@ +import { screen } from '@testing-library/dom'; +import React from 'react'; +import configureMockStore from 'redux-mock-store'; +import mockState from '../../../../test/data/mock-state.json'; +import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import OriginPill from './origin-pill'; + +describe('', () => { + it('renders correct elements', () => { + const defaultProps = { + origin: 'Test Origin', + dataTestId: 'test-data-test-id', + }; + const store = configureMockStore()(mockState); + + renderWithProvider(, store); + + expect(screen.getByTestId(defaultProps.dataTestId)).toBeDefined(); + expect( + screen.getByTestId(`${defaultProps.dataTestId}-avatar-favicon`), + ).toBeDefined(); + expect(screen.getByTestId(`${defaultProps.dataTestId}-text`)).toBeDefined(); + expect( + screen.getByTestId(`${defaultProps.dataTestId}-text`), + ).toHaveTextContent(defaultProps.origin); + }); +}); diff --git a/ui/components/ui/origin-pill/origin-pill.tsx b/ui/components/ui/origin-pill/origin-pill.tsx new file mode 100644 index 000000000000..6a0863f43a71 --- /dev/null +++ b/ui/components/ui/origin-pill/origin-pill.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { + AlignItems, + BorderColor, + BorderRadius, + BorderStyle, + Display, + JustifyContent, + TextColor, + TextVariant, +} from '../../../helpers/constants/design-system'; +import { getSubjectMetadata } from '../../../selectors'; +import { AvatarFavicon, Box, Text } from '../../component-library'; + +type OriginPillProps = { + origin: string; + dataTestId: string; +}; + +export default function OriginPill({ origin, dataTestId }: OriginPillProps) { + const subjectMetadata = useSelector(getSubjectMetadata); + + const { iconUrl: siteImage = '' } = subjectMetadata[origin] || {}; + + return ( + + + + {origin} + + + ); +} diff --git a/ui/components/ui/ui-components.scss b/ui/components/ui/ui-components.scss index a851a6fd72d5..a1a901ac2a4d 100644 --- a/ui/components/ui/ui-components.scss +++ b/ui/components/ui/ui-components.scss @@ -29,7 +29,6 @@ @import 'logo/logo-coinbasepay.scss'; @import 'loading-screen/index'; @import 'menu/menu'; -@import 'new-network-info/index'; @import 'numeric-input/numeric-input'; @import 'nickname-popover/index'; @import 'form-field/index'; diff --git a/ui/components/ui/unit-input/unit-input.component.js b/ui/components/ui/unit-input/unit-input.component.js index 727a33e98c4a..3aaa0c5c315c 100644 --- a/ui/components/ui/unit-input/unit-input.component.js +++ b/ui/components/ui/unit-input/unit-input.component.js @@ -95,7 +95,7 @@ export default class UnitInput extends PureComponent { } this.props.onBlur && this.props.onBlur(value); - this.unitInput.scrollTo && this.unitInput.scrollTo(0, 0); + this.unitInput?.scrollTo?.(0, 0); }; handleChange = (event) => { diff --git a/ui/contexts/identity/index.test.tsx b/ui/contexts/identity/index.test.tsx new file mode 100644 index 000000000000..435875151edc --- /dev/null +++ b/ui/contexts/identity/index.test.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { useAccountSyncing } from '../../hooks/identity/useProfileSyncing'; +import { useAutoSignIn } from '../../hooks/identity/useAuthentication'; +import { MetamaskIdentityProvider } from '.'; + +jest.mock('../../hooks/identity/useProfileSyncing'); +jest.mock('../../hooks/identity/useAuthentication'); + +describe('MetamaskIdentityProvider', () => { + const mockUseAccountSyncing = jest.mocked(useAccountSyncing); + const mockUseAutoSignIn = jest.mocked(useAutoSignIn); + + beforeEach(() => { + mockUseAccountSyncing.mockReturnValue({ + dispatchAccountSyncing: jest.fn(), + shouldDispatchAccountSyncing: false, + }); + + mockUseAutoSignIn.mockReturnValue({ + autoSignIn: jest.fn(), + shouldAutoSignIn: jest.fn().mockReturnValue(false), + }); + }); + + it('renders children correctly', () => { + render( + +
    Child Component
    +
    , + ); + + expect(screen.getByTestId('child')).toBeInTheDocument(); + }); + + it('calls dispatchAccountSyncing if shouldDispatchAccountSyncing is true', () => { + const dispatchAccountSyncing = jest.fn(); + mockUseAccountSyncing.mockReturnValue({ + dispatchAccountSyncing, + shouldDispatchAccountSyncing: true, + }); + + render( + +
    Child Component
    +
    , + ); + + expect(dispatchAccountSyncing).toHaveBeenCalled(); + }); + + it('does not call dispatchAccountSyncing if shouldDispatchAccountSyncing is false', () => { + const dispatchAccountSyncing = jest.fn(); + mockUseAccountSyncing.mockReturnValue({ + dispatchAccountSyncing, + shouldDispatchAccountSyncing: false, + }); + + render( + +
    Child Component
    +
    , + ); + + expect(dispatchAccountSyncing).not.toHaveBeenCalled(); + }); + + it('calls autoSignIn if shouldAutoSignIn returns true', () => { + const autoSignIn = jest.fn(); + const shouldAutoSignIn = jest.fn().mockReturnValue(true); + mockUseAutoSignIn.mockReturnValue({ + autoSignIn, + shouldAutoSignIn, + }); + + render( + +
    Child Component
    +
    , + ); + + expect(autoSignIn).toHaveBeenCalled(); + }); + + it('does not call autoSignIn if shouldAutoSignIn returns false', () => { + const autoSignIn = jest.fn(); + const shouldAutoSignIn = jest.fn().mockReturnValue(false); + mockUseAutoSignIn.mockReturnValue({ + autoSignIn, + shouldAutoSignIn, + }); + + render( + +
    Child Component
    +
    , + ); + + expect(autoSignIn).not.toHaveBeenCalled(); + }); +}); diff --git a/ui/contexts/identity/index.tsx b/ui/contexts/identity/index.tsx index 647e91c54d63..7bdd7257d6a9 100644 --- a/ui/contexts/identity/index.tsx +++ b/ui/contexts/identity/index.tsx @@ -1,9 +1,11 @@ import React, { useEffect } from 'react'; import { useAccountSyncing } from '../../hooks/identity/useProfileSyncing'; +import { useAutoSignIn } from '../../hooks/identity/useAuthentication'; export const MetamaskIdentityProvider: React.FC = ({ children }) => { const { dispatchAccountSyncing, shouldDispatchAccountSyncing } = useAccountSyncing(); + const { autoSignIn, shouldAutoSignIn } = useAutoSignIn(); useEffect(() => { if (shouldDispatchAccountSyncing) { @@ -11,5 +13,11 @@ export const MetamaskIdentityProvider: React.FC = ({ children }) => { } }, [shouldDispatchAccountSyncing, dispatchAccountSyncing]); + useEffect(() => { + if (shouldAutoSignIn()) { + autoSignIn(); + } + }, [shouldAutoSignIn, autoSignIn]); + return <>{children}; }; diff --git a/ui/ducks/app/app.test.js b/ui/ducks/app/app.test.js index 27b20a5841b3..e827251a9866 100644 --- a/ui/ducks/app/app.test.js +++ b/ui/ducks/app/app.test.js @@ -358,4 +358,73 @@ describe('App State', () => { expect(state.errorInSettings).toBeNull(); }); + + it('toggles account menu', () => { + const state = reduceApp( + {}, + { + type: actionConstants.TOGGLE_ACCOUNT_MENU, + }, + ); + + expect(state.isAccountMenuOpen).toStrictEqual(true); + }); + + it('toggles network menu', () => { + const state = reduceApp( + {}, + { + type: actionConstants.TOGGLE_NETWORK_MENU, + }, + ); + + expect(state.isNetworkMenuOpen).toStrictEqual(true); + }); + + it('close welcome screen', () => { + const state = reduceApp( + {}, + { + type: actionConstants.CLOSE_WELCOME_SCREEN, + }, + ); + + expect(state.welcomeScreenSeen).toStrictEqual(true); + }); + + it('sets pending tokens', () => { + const payload = { + address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', + decimals: 18, + symbol: 'META', + }; + + const pendingTokensState = reduceApp( + {}, + { + type: actionConstants.SET_PENDING_TOKENS, + payload, + }, + ); + + expect(pendingTokensState.pendingTokens).toStrictEqual(payload); + }); + + it('clears pending tokens', () => { + const payload = { + address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', + decimals: 18, + symbol: 'META', + }; + + const pendingTokensState = { + pendingTokens: payload, + }; + + const state = reduceApp(pendingTokensState, { + type: actionConstants.CLEAR_PENDING_TOKENS, + }); + + expect(state.pendingTokens).toStrictEqual({}); + }); }); diff --git a/ui/ducks/app/app.ts b/ui/ducks/app/app.ts index 81f875446f1e..d2314f3dcd9a 100644 --- a/ui/ducks/app/app.ts +++ b/ui/ducks/app/app.ts @@ -1,3 +1,7 @@ +import type { + ContractExchangeRates, + Token, +} from '@metamask/assets-controllers'; import { AnyAction, Action } from 'redux'; import { PayloadAction } from '@reduxjs/toolkit'; import { @@ -7,6 +11,15 @@ import { import * as actionConstants from '../../store/actionConstants'; type AppState = { + customNonceValue: string; + isAccountMenuOpen: boolean; + isNetworkMenuOpen: boolean; + nextNonce: string | null; + pendingTokens: { + [address: string]: Token & { isCustom?: boolean; unlisted?: boolean }; + }; + welcomeScreenSeen: boolean; + confirmationExchangeRates: ContractExchangeRates; shouldClose: boolean; menuOpen: boolean; modal: { @@ -114,6 +127,13 @@ export type AppSliceState = { // default state const initialState: AppState = { + customNonceValue: '', + isAccountMenuOpen: false, + isNetworkMenuOpen: false, + nextNonce: null, + pendingTokens: {}, + welcomeScreenSeen: false, + confirmationExchangeRates: {}, shouldClose: false, menuOpen: false, modal: { @@ -206,6 +226,57 @@ export default function reduceApp( }; switch (action.type) { + case actionConstants.UPDATE_CUSTOM_NONCE: + return { + ...appState, + customNonceValue: action.value, + }; + + case actionConstants.TOGGLE_ACCOUNT_MENU: + return { + ...appState, + isAccountMenuOpen: !appState.isAccountMenuOpen, + }; + + case actionConstants.SET_NEXT_NONCE: { + return { + ...appState, + nextNonce: action.payload, + }; + } + + case actionConstants.SET_PENDING_TOKENS: + return { + ...appState, + pendingTokens: { ...action.payload }, + }; + + case actionConstants.CLEAR_PENDING_TOKENS: { + return { + ...appState, + pendingTokens: {}, + }; + } + + case actionConstants.CLOSE_WELCOME_SCREEN: + return { + ...appState, + welcomeScreenSeen: true, + }; + + case actionConstants.SET_CONFIRMATION_EXCHANGE_RATES: + return { + ...appState, + confirmationExchangeRates: action.value, + }; + + case actionConstants.RESET_ONBOARDING: { + return { + ...appState, + welcomeScreenSeen: false, + }; + } + // dropdown methods case actionConstants.NETWORK_DROPDOWN_OPEN: return { @@ -613,6 +684,7 @@ export default function reduceApp( ...appState, isAddingNewNetwork: Boolean(action.payload?.isAddingNewNetwork), isMultiRpcOnboarding: Boolean(action.payload?.isMultiRpcOnboarding), + isNetworkMenuOpen: !appState.isNetworkMenuOpen, }; case actionConstants.DELETE_METAMETRICS_DATA_MODAL_OPEN: return { diff --git a/ui/ducks/bridge-status/actions.ts b/ui/ducks/bridge-status/actions.ts index e9198914966c..dd5de256fe61 100644 --- a/ui/ducks/bridge-status/actions.ts +++ b/ui/ducks/bridge-status/actions.ts @@ -1,6 +1,6 @@ import { - StartPollingForBridgeTxStatusArgs, BridgeStatusAction, + StartPollingForBridgeTxStatusArgsSerialized, } from '../../../shared/types/bridge-status'; import { forceUpdateMetamaskState } from '../../store/actions'; import { submitRequestToBackground } from '../../store/background-connection'; @@ -17,14 +17,15 @@ const callBridgeStatusControllerMethod = ( }; export const startPollingForBridgeTxStatus = ( - startPollingForBridgeTxStatusArgs: StartPollingForBridgeTxStatusArgs, + startPollingForBridgeTxStatusArgs: StartPollingForBridgeTxStatusArgsSerialized, ) => { return async (dispatch: MetaMaskReduxDispatch) => { return dispatch( - callBridgeStatusControllerMethod<[StartPollingForBridgeTxStatusArgs]>( - BridgeStatusAction.START_POLLING_FOR_BRIDGE_TX_STATUS, - [startPollingForBridgeTxStatusArgs], - ), + callBridgeStatusControllerMethod< + [StartPollingForBridgeTxStatusArgsSerialized] + >(BridgeStatusAction.START_POLLING_FOR_BRIDGE_TX_STATUS, [ + startPollingForBridgeTxStatusArgs, + ]), ); }; }; diff --git a/ui/ducks/bridge/actions.ts b/ui/ducks/bridge/actions.ts index 5597503206da..e2ea02bad39d 100644 --- a/ui/ducks/bridge/actions.ts +++ b/ui/ducks/bridge/actions.ts @@ -1,16 +1,12 @@ -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BridgeBackgroundAction, BridgeUserAction, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; + QuoteRequest, +} from '../../../shared/types/bridge'; import { forceUpdateMetamaskState } from '../../store/actions'; import { submitRequestToBackground } from '../../store/background-connection'; -import { QuoteRequest } from '../../pages/bridge/types'; -import { MetaMaskReduxDispatch } from '../../store/store'; +import type { MetaMaskReduxDispatch } from '../../store/store'; import { bridgeSlice, setDestTokenExchangeRates, diff --git a/ui/ducks/bridge/bridge.test.ts b/ui/ducks/bridge/bridge.test.ts index d317d1b53bb8..30e2f0fe880a 100644 --- a/ui/ducks/bridge/bridge.test.ts +++ b/ui/ducks/bridge/bridge.test.ts @@ -7,9 +7,7 @@ import { setBackgroundConnection } from '../../store/background-connection'; import { BridgeBackgroundAction, BridgeUserAction, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; +} from '../../../shared/types/bridge'; import * as util from '../../helpers/utils/util'; import { BRIDGE_DEFAULT_SLIPPAGE } from '../../../shared/constants/bridge'; import bridgeReducer from './bridge'; diff --git a/ui/ducks/bridge/bridge.ts b/ui/ducks/bridge/bridge.ts index 82bbba964868..14786b51d4dd 100644 --- a/ui/ducks/bridge/bridge.ts +++ b/ui/ducks/bridge/bridge.ts @@ -1,12 +1,11 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { Hex } from '@metamask/utils'; -import { swapsSlice } from '../swaps/swaps'; import { - BridgeToken, - QuoteMetadata, - QuoteResponse, + type BridgeToken, + type QuoteMetadata, + type QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; +} from '../../../shared/types/bridge'; import { BRIDGE_DEFAULT_SLIPPAGE } from '../../../shared/constants/bridge'; import { getTokenExchangeRate } from './utils'; @@ -57,7 +56,6 @@ const bridgeSlice = createSlice({ name: 'bridge', initialState: { ...initialState }, reducers: { - ...swapsSlice.reducer, setToChainId: (state, action) => { state.toChainId = action.payload; }, diff --git a/ui/ducks/bridge/selectors.test.ts b/ui/ducks/bridge/selectors.test.ts index 0e948ee18784..f44b5d8dacea 100644 --- a/ui/ducks/bridge/selectors.test.ts +++ b/ui/ducks/bridge/selectors.test.ts @@ -11,10 +11,10 @@ import { mockNetworkState } from '../../../test/stub/networks'; import mockErc20Erc20Quotes from '../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import mockBridgeQuotesNativeErc20 from '../../../test/data/bridge/mock-quotes-native-erc20.json'; import { - QuoteMetadata, - QuoteResponse, + type QuoteMetadata, + type QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; +} from '../../../shared/types/bridge'; import { getAllBridgeableNetworks, getBridgeQuotes, @@ -1212,7 +1212,7 @@ describe('Bridge selectors', () => { ).toStrictEqual(false); }); - it('should return isEstimatedReturnLow=true return value is 20% less than sent funds', () => { + it('should return isEstimatedReturnLow=true return value is 50% less than sent funds', () => { const state = createBridgeMockStore({ featureFlagOverrides: { extensionConfig: { @@ -1228,7 +1228,7 @@ describe('Bridge selectors', () => { toToken: { address: zeroAddress(), symbol: 'TEST' }, fromTokenInputValue: '1', fromTokenExchangeRate: 2524.25, - toTokenExchangeRate: 0.798781, + toTokenExchangeRate: 0.61, }, bridgeStateOverrides: { quotes: mockBridgeQuotesNativeErc20, @@ -1264,11 +1264,11 @@ describe('Bridge selectors', () => { expect( getBridgeQuotes(state as never).activeQuote?.adjustedReturn .valueInCurrency, - ).toStrictEqual(new BigNumber('16.99676538473491988')); + ).toStrictEqual(new BigNumber('12.38316502627291988')); expect(result.isEstimatedReturnLow).toStrictEqual(true); }); - it('should return isEstimatedReturnLow=false when return value is more than 80% of sent funds', () => { + it('should return isEstimatedReturnLow=false when return value is more than 50% of sent funds', () => { const state = createBridgeMockStore({ featureFlagOverrides: { extensionConfig: { @@ -1283,7 +1283,8 @@ describe('Bridge selectors', () => { fromToken: { address: zeroAddress(), symbol: 'ETH' }, toToken: { address: zeroAddress(), symbol: 'TEST' }, fromTokenExchangeRate: 2524.25, - toTokenExchangeRate: 0.998781, + toTokenExchangeRate: 0.63, + fromTokenInputValue: 1, }, bridgeStateOverrides: { quotes: mockBridgeQuotesNativeErc20, @@ -1320,7 +1321,7 @@ describe('Bridge selectors', () => { expect( getBridgeQuotes(state as never).activeQuote?.adjustedReturn .valueInCurrency, - ).toStrictEqual(new BigNumber('21.88454578473491988')); + ).toStrictEqual(new BigNumber('12.87194306627291988')); expect(result.isEstimatedReturnLow).toStrictEqual(false); }); diff --git a/ui/ducks/bridge/selectors.ts b/ui/ducks/bridge/selectors.ts index 9241af57db6d..f86745e69ae3 100644 --- a/ui/ducks/bridge/selectors.ts +++ b/ui/ducks/bridge/selectors.ts @@ -1,11 +1,11 @@ -import { +import type { AddNetworkFields, NetworkConfiguration, NetworkState, } from '@metamask/network-controller'; import { orderBy, uniqBy } from 'lodash'; import { createSelector } from 'reselect'; -import { GasFeeEstimates } from '@metamask/gas-fee-controller'; +import type { GasFeeEstimates } from '@metamask/gas-fee-controller'; import { BigNumber } from 'bignumber.js'; import { calcTokenAmount } from '@metamask/notification-services-controller/push-services'; import { @@ -20,12 +20,7 @@ import { BRIDGE_PREFERRED_GAS_ESTIMATE, BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE, } from '../../../shared/constants/bridge'; -import { - BridgeControllerState, - BridgeFeatureFlagsKey, - // TODO: Remove restricted import - // eslint-disable-next-line import/no-restricted-paths -} from '../../../app/scripts/controllers/bridge/types'; +import type { BridgeControllerState } from '../../../shared/types/bridge'; import { createDeepEqualSelector } from '../../../shared/modules/selectors/util'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../shared/constants/swaps'; import { @@ -33,16 +28,15 @@ import { getNetworkConfigurationsByChainId, } from '../../../shared/modules/selectors/networks'; import { getConversionRate, getGasFeeEstimates } from '../metamask/metamask'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../app/scripts/controllers/bridge/constants'; import { - L1GasFees, - BridgeToken, - QuoteMetadata, - QuoteResponse, + type L1GasFees, + type BridgeToken, + type QuoteMetadata, + type QuoteResponse, SortOrder, -} from '../../pages/bridge/types'; + BridgeFeatureFlagsKey, + RequestStatus, +} from '../../../shared/types/bridge'; import { calcAdjustedReturn, calcCost, @@ -64,7 +58,7 @@ import { exchangeRateFromMarketData, tokenPriceInNativeAsset, } from './utils'; -import { BridgeState } from './bridge'; +import type { BridgeState } from './bridge'; type BridgeAppState = { metamask: { bridgeState: BridgeControllerState } & NetworkState & { diff --git a/ui/ducks/bridge/utils.ts b/ui/ducks/bridge/utils.ts index a563b5af2c73..050829d3ca65 100644 --- a/ui/ducks/bridge/utils.ts +++ b/ui/ducks/bridge/utils.ts @@ -1,14 +1,14 @@ -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BigNumber } from 'bignumber.js'; import { getAddress } from 'ethers/lib/utils'; -import { ContractMarketData } from '@metamask/assets-controllers'; +import type { ContractMarketData } from '@metamask/assets-controllers'; import { AddNetworkFields, NetworkConfiguration, } from '@metamask/network-controller'; import { decGWEIToHexWEI } from '../../../shared/modules/conversion.utils'; import { Numeric } from '../../../shared/modules/Numeric'; -import { TxData } from '../../pages/bridge/types'; +import type { TxData } from '../../../shared/types/bridge'; import { getTransaction1559GasFeeEstimates } from '../../pages/swaps/swaps.util'; import { fetchTokenExchangeRates as fetchTokenExchangeRatesUtil } from '../../helpers/utils/util'; diff --git a/ui/ducks/confirm-transaction/confirm-transaction.duck.test.js b/ui/ducks/confirm-transaction/confirm-transaction.duck.test.js index 4420db36df80..ecf34922a59b 100644 --- a/ui/ducks/confirm-transaction/confirm-transaction.duck.test.js +++ b/ui/ducks/confirm-transaction/confirm-transaction.duck.test.js @@ -1,6 +1,5 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import sinon from 'sinon'; import { TransactionStatus } from '@metamask/transaction-controller'; import { CHAIN_IDS } from '../../../shared/constants/network'; @@ -289,20 +288,6 @@ describe('Confirm Transaction Duck', () => { }); describe('Thunk actions', () => { - beforeEach(() => { - global.eth = { - getCode: sinon - .stub() - .callsFake((address) => - Promise.resolve(address?.match(/isContract/u) ? 'not-0x' : '0x'), - ), - }; - }); - - afterEach(function () { - global.eth.getCode.resetHistory(); - }); - it('updates txData and updates gas values in confirmTransaction', () => { const txData = { history: [], diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js index 93550d45fc10..20d25fb58129 100644 --- a/ui/ducks/metamask/metamask.js +++ b/ui/ducks/metamask/metamask.js @@ -28,18 +28,12 @@ import { setCustomGasLimit, setCustomGasPrice } from '../gas/gas.duck'; const initialState = { isInitialized: false, isUnlocked: false, - isAccountMenuOpen: false, - isNetworkMenuOpen: false, internalAccounts: { accounts: {}, selectedAccount: '' }, transactions: [], networkConfigurations: {}, addressBook: [], - confirmationExchangeRates: {}, - pendingTokens: {}, - customNonceValue: '', useBlockie: false, featureFlags: {}, - welcomeScreenSeen: false, currentLocale: '', currentBlockGasLimit: '', currentBlockGasLimitByChainId: {}, @@ -60,7 +54,6 @@ const initialState = { use4ByteResolution: true, participateInMetaMetrics: null, dataCollectionForMarketing: null, - nextNonce: null, currencyRates: { ETH: { conversionRate: null, @@ -121,24 +114,6 @@ export default function reduceMetamask(state = initialState, action) { return Object.assign(metamaskState, { internalAccounts }); } - case actionConstants.UPDATE_CUSTOM_NONCE: - return { - ...metamaskState, - customNonceValue: action.value, - }; - - case actionConstants.TOGGLE_ACCOUNT_MENU: - return { - ...metamaskState, - isAccountMenuOpen: !metamaskState.isAccountMenuOpen, - }; - - case actionConstants.TOGGLE_NETWORK_MENU: - return { - ...metamaskState, - isNetworkMenuOpen: !metamaskState.isNetworkMenuOpen, - }; - case actionConstants.UPDATE_TRANSACTION_PARAMS: { const { id: txId, value } = action; let { transactions } = metamaskState; @@ -169,25 +144,6 @@ export default function reduceMetamask(state = initialState, action) { dataCollectionForMarketing: action.value, }; - case actionConstants.CLOSE_WELCOME_SCREEN: - return { - ...metamaskState, - welcomeScreenSeen: true, - }; - - case actionConstants.SET_PENDING_TOKENS: - return { - ...metamaskState, - pendingTokens: { ...action.payload }, - }; - - case actionConstants.CLEAR_PENDING_TOKENS: { - return { - ...metamaskState, - pendingTokens: {}, - }; - } - case actionConstants.COMPLETE_ONBOARDING: { return { ...metamaskState, @@ -198,13 +154,12 @@ export default function reduceMetamask(state = initialState, action) { case actionConstants.RESET_ONBOARDING: { return { ...metamaskState, + isInitialized: false, completedOnboarding: false, firstTimeFlowType: null, - isInitialized: false, isUnlocked: false, onboardingTabs: {}, seedPhraseBackedUp: null, - welcomeScreenSeen: false, }; } @@ -215,18 +170,6 @@ export default function reduceMetamask(state = initialState, action) { }; } - case actionConstants.SET_NEXT_NONCE: { - return { - ...metamaskState, - nextNonce: action.payload, - }; - } - case actionConstants.SET_CONFIRMATION_EXCHANGE_RATES: - return { - ...metamaskState, - confirmationExchangeRates: action.value, - }; - default: return metamaskState; } @@ -284,8 +227,6 @@ export const getWeb3ShimUsageAlertEnabledness = (state) => export const getUnconnectedAccountAlertShown = (state) => state.metamask.unconnectedAccountAlertShownOrigins; -export const getPendingTokens = (state) => state.metamask.pendingTokens; - export const getTokens = (state) => state.metamask.tokens; export function getNftsDropdownState(state) { @@ -373,7 +314,7 @@ export function isEIP1559Network(state, networkClientId) { return ( state.metamask.networksMetadata?.[ networkClientId ?? selectedNetworkClientId - ].EIPS[1559] === true + ]?.EIPS[1559] === true ); } @@ -604,3 +545,7 @@ export function doesUserHaveALedgerAccount(state) { return kr.type === KeyringType.ledger; }); } + +export function getCurrentCurrency(state) { + return state.metamask.currentCurrency; +} diff --git a/ui/ducks/metamask/metamask.test.js b/ui/ducks/metamask/metamask.test.js index 5f3021297c96..250fff8ff06e 100644 --- a/ui/ducks/metamask/metamask.test.js +++ b/ui/ducks/metamask/metamask.test.js @@ -21,6 +21,7 @@ import reduceMetamask, { getSendHexDataFeatureFlagState, getSendToAccounts, isNotEIP1559Network, + getCurrentCurrency, } from './metamask'; jest.mock('@metamask/transaction-controller', () => ({ @@ -126,6 +127,7 @@ describe('MetaMask Reducers', () => { conversionRate: 1200.88200327, }, }, + currentCurrency: 'usd', ...mockNetworkState({ chainId: CHAIN_IDS.GOERLI }), accounts: { '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825': { @@ -265,28 +267,6 @@ describe('MetaMask Reducers', () => { }); }); - it('toggles account menu', () => { - const state = reduceMetamask( - {}, - { - type: actionConstants.TOGGLE_ACCOUNT_MENU, - }, - ); - - expect(state.isAccountMenuOpen).toStrictEqual(true); - }); - - it('toggles network menu', () => { - const state = reduceMetamask( - {}, - { - type: actionConstants.TOGGLE_NETWORK_MENU, - }, - ); - - expect(state.isNetworkMenuOpen).toStrictEqual(true); - }); - it('updates value of tx by id', () => { const oldState = { transactions: [ @@ -306,53 +286,6 @@ describe('MetaMask Reducers', () => { expect(state.transactions[0].txParams).toStrictEqual('bar'); }); - it('close welcome screen', () => { - const state = reduceMetamask( - {}, - { - type: actionConstants.CLOSE_WELCOME_SCREEN, - }, - ); - - expect(state.welcomeScreenSeen).toStrictEqual(true); - }); - - it('sets pending tokens', () => { - const payload = { - address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', - decimals: 18, - symbol: 'META', - }; - - const pendingTokensState = reduceMetamask( - {}, - { - type: actionConstants.SET_PENDING_TOKENS, - payload, - }, - ); - - expect(pendingTokensState.pendingTokens).toStrictEqual(payload); - }); - - it('clears pending tokens', () => { - const payload = { - address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', - decimals: 18, - symbol: 'META', - }; - - const pendingTokensState = { - pendingTokens: payload, - }; - - const state = reduceMetamask(pendingTokensState, { - type: actionConstants.CLEAR_PENDING_TOKENS, - }); - - expect(state.pendingTokens).toStrictEqual({}); - }); - describe('metamask state selectors', () => { describe('getBlockGasLimit', () => { it('should return the current block gas limit', () => { @@ -384,6 +317,13 @@ describe('MetaMask Reducers', () => { }); }); + describe('getCurrentCurrency', () => { + it('should return the `currentCurrency`', () => { + const currentCurrency = getCurrentCurrency(mockState); + expect(currentCurrency).toStrictEqual('usd'); + }); + }); + describe('getSendHexDataFeatureFlagState()', () => { it('should return the sendHexData feature flag state', () => { expect(getSendHexDataFeatureFlagState(mockState)).toStrictEqual(true); diff --git a/ui/ducks/send/helpers.js b/ui/ducks/send/helpers.js index 5fcee6f7c88b..23492fe5e264 100644 --- a/ui/ducks/send/helpers.js +++ b/ui/ducks/send/helpers.js @@ -1,5 +1,4 @@ import { addHexPrefix, toChecksumAddress } from 'ethereumjs-util'; -import abi from 'human-standard-token-abi'; import BigNumber from 'bignumber.js'; import { TransactionEnvelopeType } from '@metamask/transaction-controller'; import { getErrorMessage } from '../../../shared/modules/error'; @@ -90,12 +89,12 @@ export async function estimateGasLimitForSend({ paramsForGasEstimate.to = sendToken.address; } else { if (!data) { - // eth.getCode will return the compiled smart contract code at the + // eth_getCode will return the compiled smart contract code at the // address. If this returns 0x, 0x0 or a nullish value then the address // is an externally owned account (NOT a contract account). For these // types of transactions the gasLimit will always be 21,000 or 0x5208 const { isContractAddress } = to - ? await readAddressAsContract(global.eth, to) + ? await readAddressAsContract(global.ethereumProvider, to) : {}; if (!isContractAddress && !isNonStandardEthChain) { return GAS_LIMITS.SIMPLE; @@ -104,7 +103,7 @@ export async function estimateGasLimitForSend({ } } - paramsForGasEstimate.data = data; + paramsForGasEstimate.data = data || '0x'; if (to) { paramsForGasEstimate.to = to; @@ -405,19 +404,6 @@ export function getRoundedGasPrice(gasPriceEstimate) { return getGasPriceInHexWei(gasPriceAsNumber); } -export async function getERC20Balance(token, accountAddress) { - const contract = global.eth.contract(abi).at(token.address); - const usersToken = (await contract.balanceOf(accountAddress)) ?? null; - if (!usersToken) { - return '0x0'; - } - const amount = calcTokenAmount( - usersToken.balance.toString(), - token.decimals, - ).toString(16); - return addHexPrefix(amount); -} - /** * returns if a given draft transaction is a swap and send * diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index cdb6e3ad7e94..04246dd76c55 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -1,4 +1,3 @@ -import sinon from 'sinon'; import createMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { BigNumber } from '@ethersproject/bignumber'; @@ -90,15 +89,6 @@ const mockStore = createMockStore([thunk]); const mockAddress1 = '0xdafea492d9c6733ae3d56b7ed1adb60692c98123'; const mockNftAddress1 = 'f4831105676a5fc024684d056390b8bc529daf51c7'; -jest.mock('./send', () => { - const actual = jest.requireActual('./send'); - return { - __esModule: true, - ...actual, - getERC20Balance: jest.fn(() => '0x0'), - }; -}); - jest.mock('lodash', () => ({ ...jest.requireActual('lodash'), debounce: (fn) => fn, @@ -2177,13 +2167,6 @@ describe('Send Slice', () => { decimals: 18, }), ); - global.eth = { - contract: sinon.stub().returns({ - at: sinon.stub().returns({ - balanceOf: sinon.stub().returns(undefined), - }), - }), - }; const store = mockStore(defaultSendAssetState); const newSendAsset = { @@ -2243,13 +2226,6 @@ describe('Send Slice', () => { [tokenAddress]: { hex: '0x0' }, }), ); - global.eth = { - contract: sinon.stub().returns({ - at: sinon.stub().returns({ - balanceOf: sinon.stub().returns(undefined), - }), - }), - }; const store = mockStore(defaultSendAssetState); const newSendAsset = { @@ -2482,10 +2458,6 @@ describe('Send Slice', () => { }; it('should create actions to update recipient and recalculate gas limit if the asset type is not set', async () => { - global.eth = { - getCode: sinon.stub(), - }; - const updateRecipientState = { metamask: { addressBook: {}, @@ -2532,10 +2504,6 @@ describe('Send Slice', () => { }); it('should update recipient nickname if the passed address exists in the addressBook state but no nickname param is provided', async () => { - global.eth = { - getCode: sinon.stub(), - }; - const TEST_RECIPIENT_ADDRESS = '0x0000000000000000000000000000000000000001'; const TEST_RECIPIENT_NAME = 'The 1 address'; @@ -3499,15 +3467,6 @@ describe('Send Slice', () => { }, }; - global.eth = { - contract: sinon.stub().returns({ - at: sinon.stub().returns({ - balanceOf: sinon.stub().returns(undefined), - }), - }), - getCode: jest.fn(() => '0xa'), - }; - const store = mockStore(editTransactionState); await store.dispatch(editExistingTransaction(AssetType.NFT, 1)); @@ -3730,15 +3689,6 @@ describe('Send Slice', () => { }, }; - global.eth = { - contract: sinon.stub().returns({ - at: sinon.stub().returns({ - balanceOf: sinon.stub().returns(undefined), - }), - }), - getCode: jest.fn(() => '0xa'), - }; - const store = mockStore(editTransactionState); await store.dispatch(editExistingTransaction(AssetType.token, 1)); @@ -3980,15 +3930,6 @@ describe('Send Slice', () => { }, }; - global.eth = { - contract: sinon.stub().returns({ - at: sinon.stub().returns({ - balanceOf: sinon.stub().returns(undefined), - }), - }), - getCode: jest.fn(() => '0xa'), - }; - const store = mockStore(editTransactionState); store.clearActions(); diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index e044fdf42b3f..dc9662fe5fcf 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -57,6 +57,7 @@ import { hexWEIToDecGWEI, } from '../../../shared/modules/conversion.utils'; import { getCurrentChainId } from '../../../shared/modules/selectors/networks'; +import { getFeatureFlagsByChainId } from '../../../shared/modules/selectors/feature-flags'; import { getSelectedAccount, getTokenExchangeRates, @@ -896,12 +897,12 @@ export const signAndSendSwapsSmartTransaction = ({ const { metaData, value: swapTokenValue, slippage } = fetchParams; const { sourceTokenInfo = {}, destinationTokenInfo = {} } = metaData; const usedQuote = getUsedQuote(state); - const swapsNetworkConfig = getSwapsNetworkConfig(state); const selectedNetwork = getSelectedNetwork(state); + const swapsFeatureFlags = getFeatureFlagsByChainId(state); dispatch( setSmartTransactionsRefreshInterval( - swapsNetworkConfig?.stxBatchStatusRefreshTime, + swapsFeatureFlags?.smartTransactions?.batchStatusPollingInterval, ), ); @@ -1365,7 +1366,25 @@ export function fetchMetaSwapsGasPriceEstimates() { dispatch(swapGasPriceEstimatesFetchFailed()); try { - const gasPrice = await global.ethQuery.gasPrice(); + const gasPrice = await new Promise((resolve, reject) => { + global.ethereumProvider.sendAsync( + { + method: 'eth_gasPrice', + params: [], + }, + (err, response) => { + let error = err; + if (!error && response.error) { + error = new Error(`RPC Error - ${response.error.message}`); + } + if (error) { + reject(error); + return; + } + resolve(response.result); + }, + ); + }); const gasPriceInDecGWEI = hexWEIToDecGWEI(gasPrice.toString(10)); dispatch(retrievedFallbackSwapsGasPrice(gasPriceInDecGWEI)); diff --git a/ui/helpers/constants/routes.ts b/ui/helpers/constants/routes.ts index da12a52be812..ac21c32a2b1b 100644 --- a/ui/helpers/constants/routes.ts +++ b/ui/helpers/constants/routes.ts @@ -62,6 +62,9 @@ PATH_NAME_MAP[CONTACT_ADD_ROUTE] = 'Add Contact Settings Page'; export const CONTACT_VIEW_ROUTE = '/settings/contact-list/view-contact'; PATH_NAME_MAP[`${CONTACT_VIEW_ROUTE}/:address`] = 'View Contact Settings Page'; +export const SNAP_SETTINGS_ROUTE = '/settings/snap'; +PATH_NAME_MAP[`${SNAP_SETTINGS_ROUTE}/:snapId`] = 'Snap Settings Page'; + export const REVEAL_SEED_ROUTE = '/seed'; PATH_NAME_MAP[REVEAL_SEED_ROUTE] = 'Reveal Secret Recovery Phrase Page'; diff --git a/ui/helpers/constants/settings.js b/ui/helpers/constants/settings.js index adb3102da571..b7a11a1df8f4 100644 --- a/ui/helpers/constants/settings.js +++ b/ui/helpers/constants/settings.js @@ -485,14 +485,6 @@ const SETTINGS_CONSTANTS = [ route: `${EXPERIMENTAL_ROUTE}#redesigned-confirmations`, icon: 'fas fa-flask', }, - // experimental settingsRefs[3] - { - tabMessage: (t) => t('experimental'), - sectionMessage: (t) => t('redesignedTransactionsEnabledToggle'), - descriptionMessage: (t) => t('redesignedTransactionsToggleDescription'), - route: `${EXPERIMENTAL_ROUTE}#redesigned-transactions`, - icon: 'fas fa-flask', - }, ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) // since this route is only included with keyring-snaps feature flag, this needs to be the last settingsRef for the experimental tab // experimental settingsRefs[4] diff --git a/ui/helpers/utils/accounts.js b/ui/helpers/utils/accounts.js index bb789cb74b6a..b80e9bd84ee9 100644 --- a/ui/helpers/utils/accounts.js +++ b/ui/helpers/utils/accounts.js @@ -72,7 +72,13 @@ export function getAvatarNetworkColor(name) { } } -export function getAccountLabel(type, account) { +export function getAccountLabel( + type, + account, + ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) + snapName, + ///: END:ONLY_INCLUDE_IF +) { if (!account) { return null; } @@ -91,8 +97,8 @@ export function getAccountLabel(type, account) { return HardwareKeyringNames.lattice; ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) case KeyringType.snap: - if (account.metadata.snap?.name) { - return `${account.metadata.snap?.name} (${t('beta')})`; + if (snapName) { + return `${snapName} (${t('beta')})`; } return `${t('snaps')} (${t('beta')})`; ///: END:ONLY_INCLUDE_IF diff --git a/ui/helpers/utils/accounts.test.js b/ui/helpers/utils/accounts.test.js index e284ad886f56..d3ffc3a67511 100644 --- a/ui/helpers/utils/accounts.test.js +++ b/ui/helpers/utils/accounts.test.js @@ -162,12 +162,13 @@ describe('Accounts', () => { }); describe('Snap Account Label', () => { + const mockSnapName = 'Test Snap Name'; const mockSnapAccountWithName = { ...mockAccount, metadata: { ...mockAccount.metadata, type: KeyringType.snap, - snap: { name: 'Test Snap Name' }, + snap: { name: mockSnapName }, }, }; const mockSnapAccountWithoutName = { @@ -179,9 +180,13 @@ describe('Accounts', () => { }; it('should return snap name with beta tag if snap name is provided', () => { - expect(getAccountLabel(KeyringType.snap, mockSnapAccountWithName)).toBe( - 'Test Snap Name (Beta)', - ); + expect( + getAccountLabel( + KeyringType.snap, + mockSnapAccountWithName, + mockSnapName, + ), + ).toBe('Test Snap Name (Beta)'); }); it('should return generic snap label with beta tag if snap name is not provided', () => { diff --git a/ui/helpers/utils/permissions.test.ts b/ui/helpers/utils/permissions.test.ts index 43857afb1815..7dd37d3a6c96 100644 --- a/ui/helpers/utils/permissions.test.ts +++ b/ui/helpers/utils/permissions.test.ts @@ -1,8 +1,5 @@ -import { - BtcAccountType, - BtcMethod, - InternalAccount, -} from '@metamask/keyring-api'; +import { BtcAccountType, BtcMethod } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { createMockInternalAccount } from '../../../test/jest/mocks'; import { containsEthPermissionsAndNonEvmAccount } from './permissions'; diff --git a/ui/helpers/utils/permissions.ts b/ui/helpers/utils/permissions.ts index 2e9d25a065f9..605f4e721d48 100644 --- a/ui/helpers/utils/permissions.ts +++ b/ui/helpers/utils/permissions.ts @@ -1,4 +1,5 @@ -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; import { RestrictedEthMethods } from '../../../shared/constants/permissions'; export const containsEthPermissionsAndNonEvmAccount = ( diff --git a/ui/helpers/utils/settings-search.test.js b/ui/helpers/utils/settings-search.test.js index 30af3ee6b9da..2c67ca598996 100644 --- a/ui/helpers/utils/settings-search.test.js +++ b/ui/helpers/utils/settings-search.test.js @@ -186,7 +186,7 @@ describe('Settings Search Utils', () => { it('returns "Experimental" section count', () => { expect(getNumberOfSettingRoutesInTab(t, t('experimental'))).toStrictEqual( - 5, + 4, ); }); diff --git a/ui/helpers/utils/snaps.js b/ui/helpers/utils/snaps.js deleted file mode 100644 index 8a57ce516cf2..000000000000 --- a/ui/helpers/utils/snaps.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Check if the given value is a valid snap ID. - * - * NOTE: This function is a duplicate oF a yet to be released version in @metamask/snaps-utils. - * - * @param value - The value to check. - * @returns `true` if the value is a valid snap ID, and `false` otherwise. - */ -export function isSnapId(value) { - return ( - (typeof value === 'string' || value instanceof String) && - (value.startsWith('local:') || value.startsWith('npm:')) - ); -} diff --git a/ui/helpers/utils/snaps.ts b/ui/helpers/utils/snaps.ts new file mode 100644 index 000000000000..d7527f89b482 --- /dev/null +++ b/ui/helpers/utils/snaps.ts @@ -0,0 +1,24 @@ +import { isProduction } from '../../../shared/modules/environment'; + +/** + * Decode a snap ID fron a pathname. + * + * @param pathname - The pathname to decode the snap ID from. + * @returns The decoded snap ID, or `undefined` if the snap ID could not be decoded. + */ +export const decodeSnapIdFromPathname = (pathname: string) => { + const snapIdURI = pathname?.match(/[^/]+$/u)?.[0]; + return snapIdURI && decodeURIComponent(snapIdURI); +}; + +const IGNORED_EXAMPLE_SNAPS = ['npm:@metamask/preinstalled-example-snap']; + +/** + * Check if the given snap ID is ignored in production. + * + * @param snapId - The snap ID to check. + * @returns `true` if the snap ID is ignored in production, and `false` otherwise. + */ +export const isSnapIgnoredInProd = (snapId: string) => { + return isProduction() ? IGNORED_EXAMPLE_SNAPS.includes(snapId) : false; +}; diff --git a/ui/helpers/utils/token-util.js b/ui/helpers/utils/token-util.js index 10beae68b39e..92efd04bf555 100644 --- a/ui/helpers/utils/token-util.js +++ b/ui/helpers/utils/token-util.js @@ -12,10 +12,16 @@ import { formatCurrency } from './confirm-tx.util'; const DEFAULT_SYMBOL = ''; async function getSymbolFromContract(tokenAddress) { - const token = util.getContractAtAddress(tokenAddress); + const contract = util.getContractAtAddress(tokenAddress); + try { - const result = await token.symbol(); - return result[0]; + const code = await contract.provider.getCode(tokenAddress); + + if (code === '0x') { + return ''; + } + + return await contract.symbol(); } catch (error) { log.warn( `symbol() call for token at address ${tokenAddress} resulted in error:`, @@ -26,10 +32,16 @@ async function getSymbolFromContract(tokenAddress) { } async function getNameFromContract(tokenAddress) { - const token = util.getContractAtAddress(tokenAddress); + const contract = util.getContractAtAddress(tokenAddress); + try { - const [name] = await token.name(); - return name; + const code = await contract.provider.getCode(tokenAddress); + + if (code === '0x') { + return ''; + } + + return await contract.name(); } catch (error) { log.warn( `name() call for token at address ${tokenAddress} resulted in error:`, @@ -40,11 +52,16 @@ async function getNameFromContract(tokenAddress) { } async function getDecimalsFromContract(tokenAddress) { - const token = util.getContractAtAddress(tokenAddress); + const contract = util.getContractAtAddress(tokenAddress); try { - const result = await token.decimals(); - const decimalsBN = result[0]; + const code = await contract.provider.getCode(tokenAddress); + + if (code === '0x') { + return '0'; + } + + const decimalsBN = await contract.decimals(); return decimalsBN?.toString(); } catch (error) { log.warn( diff --git a/ui/helpers/utils/transactions.util.js b/ui/helpers/utils/transactions.util.js index 51f36523676f..cfa820135e0f 100644 --- a/ui/helpers/utils/transactions.util.js +++ b/ui/helpers/utils/transactions.util.js @@ -63,7 +63,7 @@ export function getLatestSubmittedTxWithNonce( export async function isSmartContractAddress(address) { const { isContractAddress } = await readAddressAsContract( - global.eth, + global.ethereumProvider, address, ); return isContractAddress; diff --git a/ui/helpers/utils/util.js b/ui/helpers/utils/util.js index d687d9b82338..7544e35c4cfc 100644 --- a/ui/helpers/utils/util.js +++ b/ui/helpers/utils/util.js @@ -13,6 +13,8 @@ import bowser from 'bowser'; import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/snaps-rpc-methods'; import { stripSnapPrefix } from '@metamask/snaps-utils'; import { isObject, isStrictHexString } from '@metamask/utils'; +import { Web3Provider } from '@ethersproject/providers'; +import { Contract } from '@ethersproject/contracts'; import { CHAIN_IDS, NETWORK_TYPES } from '../../../shared/constants/network'; import { logErrorWithMessage } from '../../../shared/modules/error'; import { @@ -227,7 +229,11 @@ export function formatBalance( } export function getContractAtAddress(tokenAddress) { - return global.eth.contract(abi).at(tokenAddress); + return new Contract( + tokenAddress, + abi, + new Web3Provider(global.ethereumProvider), + ); } export function getRandomFileName() { diff --git a/ui/hooks/accounts/useMultichainWalletSnapClient.ts b/ui/hooks/accounts/useMultichainWalletSnapClient.ts index 98dfa9b429d3..702f07771a28 100644 --- a/ui/hooks/accounts/useMultichainWalletSnapClient.ts +++ b/ui/hooks/accounts/useMultichainWalletSnapClient.ts @@ -1,4 +1,4 @@ -import { KeyringClient, Sender } from '@metamask/keyring-api'; +import { KeyringClient, Sender } from '@metamask/keyring-snap-client'; import { HandlerType } from '@metamask/snaps-utils'; import { CaipChainId, Json, JsonRpcRequest } from '@metamask/utils'; import { SnapId } from '@metamask/snaps-sdk'; diff --git a/ui/hooks/bridge/events/useConvertedUsdAmounts.ts b/ui/hooks/bridge/events/useConvertedUsdAmounts.ts index 7ad432579c43..5afbfa6d0e23 100644 --- a/ui/hooks/bridge/events/useConvertedUsdAmounts.ts +++ b/ui/hooks/bridge/events/useConvertedUsdAmounts.ts @@ -8,7 +8,8 @@ import { getToTokenConversionRate, getFromAmount, } from '../../../ducks/bridge/selectors'; -import { getCurrentCurrency, getUSDConversionRate } from '../../../selectors'; +import { getCurrentCurrency } from '../../../ducks/metamask/metamask'; +import { getUSDConversionRate } from '../../../selectors'; import { tokenAmountToCurrency } from '../../../ducks/bridge/utils'; const USD_CURRENCY_CODE = 'usd'; diff --git a/ui/hooks/bridge/useBridgeExchangeRates.ts b/ui/hooks/bridge/useBridgeExchangeRates.ts index 20f70b17dfd6..c2755ffda9ee 100644 --- a/ui/hooks/bridge/useBridgeExchangeRates.ts +++ b/ui/hooks/bridge/useBridgeExchangeRates.ts @@ -5,11 +5,8 @@ import { getQuoteRequest, getToChain, } from '../../ducks/bridge/selectors'; -import { - getCurrentCurrency, - getMarketData, - getParticipateInMetaMetrics, -} from '../../selectors'; +import { getMarketData, getParticipateInMetaMetrics } from '../../selectors'; +import { getCurrentCurrency } from '../../ducks/metamask/metamask'; import { decimalToPrefixedHex } from '../../../shared/modules/conversion.utils'; import { getCurrentChainId } from '../../../shared/modules/selectors/networks'; import { diff --git a/ui/hooks/bridge/useBridgeTokens.ts b/ui/hooks/bridge/useBridgeTokens.ts index acddb7ec2fb0..354b90bc4a09 100644 --- a/ui/hooks/bridge/useBridgeTokens.ts +++ b/ui/hooks/bridge/useBridgeTokens.ts @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { getAllBridgeableNetworks } from '../../ducks/bridge/selectors'; -import { fetchBridgeTokens } from '../../pages/bridge/bridge.util'; +import { fetchBridgeTokens } from '../../../shared/modules/bridge-utils/bridge.util'; // This hook is used to fetch the bridge tokens for all bridgeable networks export const useBridgeTokens = () => { diff --git a/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts b/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts index ad4b3698fe84..bd3a14b4ce4b 100644 --- a/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts +++ b/ui/hooks/bridge/useCrossChainSwapsEventTracker.ts @@ -5,7 +5,7 @@ import { MetaMetricsEventName, MetaMetricsSwapsEventSource, } from '../../../shared/constants/metametrics'; -import { SortOrder } from '../../pages/bridge/types'; +import { SortOrder } from '../../../shared/types/bridge'; import { RequestParams, RequestMetadata, diff --git a/ui/hooks/bridge/useLatestBalance.test.ts b/ui/hooks/bridge/useLatestBalance.test.ts index 25f0d0936791..f255a3a10b9b 100644 --- a/ui/hooks/bridge/useLatestBalance.test.ts +++ b/ui/hooks/bridge/useLatestBalance.test.ts @@ -1,8 +1,8 @@ import { BigNumber } from 'bignumber.js'; +import { zeroAddress } from 'ethereumjs-util'; import { renderHookWithProvider } from '../../../test/lib/render-helpers'; import { CHAIN_IDS } from '../../../shared/constants/network'; import { createBridgeMockStore } from '../../../test/jest/mock-store'; -import { zeroAddress } from '../../__mocks__/ethereumjs-util'; import { createTestProviderTools } from '../../../test/stub/provider'; import * as tokenutil from '../../../shared/lib/token-util'; import useLatestBalance from './useLatestBalance'; diff --git a/ui/hooks/bridge/useTokensWithFiltering.ts b/ui/hooks/bridge/useTokensWithFiltering.ts index 56b16ddc4b68..61a92b7b9190 100644 --- a/ui/hooks/bridge/useTokensWithFiltering.ts +++ b/ui/hooks/bridge/useTokensWithFiltering.ts @@ -7,11 +7,13 @@ import { useParams } from 'react-router-dom'; import { zeroAddress } from 'ethereumjs-util'; import { getAllDetectedTokensForSelectedAddress, - getCurrentCurrency, getSelectedInternalAccountWithBalance, getTokenExchangeRates, } from '../../selectors'; -import { getConversionRate } from '../../ducks/metamask/metamask'; +import { + getConversionRate, + getCurrentCurrency, +} from '../../ducks/metamask/metamask'; import { SwapsTokenObject } from '../../../shared/constants/swaps'; import { AssetWithDisplayData, diff --git a/ui/hooks/identity/useAuthentication/index.ts b/ui/hooks/identity/useAuthentication/index.ts new file mode 100644 index 000000000000..a1166b23836b --- /dev/null +++ b/ui/hooks/identity/useAuthentication/index.ts @@ -0,0 +1,2 @@ +export { useSignIn } from './useSignIn'; +export { useAutoSignIn } from './useAutoSignIn'; diff --git a/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx new file mode 100644 index 000000000000..3c88101700fe --- /dev/null +++ b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx @@ -0,0 +1,101 @@ +import { act } from '@testing-library/react-hooks'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import * as actions from '../../../store/actions'; +import { MetamaskIdentityProvider } from '../../../contexts/identity'; +import { useAutoSignIn } from './useAutoSignIn'; + +type ArrangeMocksMetamaskStateOverrides = { + isUnlocked: boolean; + completedOnboarding: boolean; + isSignedIn: boolean; + isProfileSyncingEnabled: boolean; + participateInMetaMetrics: boolean; +}; + +const arrangeMockState = ( + stateOverrides: ArrangeMocksMetamaskStateOverrides, +) => { + return { + metamask: { + ...stateOverrides, + }, + }; +}; + +const arrangeMocks = () => { + const mockPerformSignInAction = jest.spyOn(actions, 'performSignIn'); + return { + mockPerformSignInAction, + }; +}; + +describe('useAutoSignIn', () => { + it('should initialize correctly', () => { + const state = arrangeMockState({ + isUnlocked: false, + completedOnboarding: false, + isProfileSyncingEnabled: false, + isSignedIn: false, + participateInMetaMetrics: false, + }); + arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useAutoSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + expect(hook.result.current.autoSignIn).toBeDefined(); + }); + + // @ts-expect-error This is missing from the Mocha type definitions + it.each` + isUnlocked | completedOnboarding | isSignedIn | isProfileSyncingEnabled | participateInMetaMetrics + ${false} | ${false} | ${false} | ${true} | ${true} + ${true} | ${false} | ${false} | ${true} | ${true} + ${false} | ${true} | ${false} | ${true} | ${true} + `( + 'should not call performSignIn if isUnlocked: $isUnlocked, completedOnboarding: $completedOnboarding', + async (stateOverrides: ArrangeMocksMetamaskStateOverrides) => { + const state = arrangeMockState(stateOverrides); + const { mockPerformSignInAction } = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useAutoSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + await act(async () => { + await hook.result.current.autoSignIn(); + }); + + expect(mockPerformSignInAction).not.toHaveBeenCalled(); + }, + ); + + it('should call performSignIn if all conditions are met', async () => { + const state = arrangeMockState({ + isUnlocked: true, + completedOnboarding: true, + // These values ensure that shouldSignIn from the useSignIn hook returns true + isProfileSyncingEnabled: true, + isSignedIn: false, + participateInMetaMetrics: true, + }); + const { mockPerformSignInAction } = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useAutoSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + await act(async () => { + await hook.result.current.autoSignIn(); + }); + + expect(mockPerformSignInAction).toHaveBeenCalled(); + }); +}); diff --git a/ui/hooks/identity/useAuthentication/useAutoSignIn.ts b/ui/hooks/identity/useAuthentication/useAutoSignIn.ts new file mode 100644 index 000000000000..b7185d53692c --- /dev/null +++ b/ui/hooks/identity/useAuthentication/useAutoSignIn.ts @@ -0,0 +1,51 @@ +import { useCallback } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import log from 'loglevel'; +import { + getCompletedOnboarding, + getIsUnlocked, +} from '../../../ducks/metamask/metamask'; +import { performSignIn } from '../../../store/actions'; +import { useSignIn } from './useSignIn'; + +/** + * Custom hook to manage automatically signing in a user based on the app state. + * + * @returns An object containing: + * - `autoSignIn`: A function to automatically sign in the user if necessary. + * - `shouldAutoSignIn`: A function to determine if the user should be automatically signed in. + */ +export function useAutoSignIn(): { + autoSignIn: () => Promise; + shouldAutoSignIn: () => boolean; +} { + const dispatch = useDispatch(); + + const isUnlocked: boolean | undefined = useSelector(getIsUnlocked); + const completedOnboarding: boolean | undefined = useSelector( + getCompletedOnboarding, + ); + + const { shouldSignIn } = useSignIn(); + + const shouldAutoSignIn = useCallback(() => { + return Boolean(shouldSignIn() && isUnlocked && completedOnboarding); + }, [shouldSignIn, isUnlocked, completedOnboarding]); + + const autoSignIn = useCallback(async () => { + if (shouldAutoSignIn()) { + try { + await dispatch(performSignIn()); + } catch (e) { + const errorMessage = + e instanceof Error ? e.message : JSON.stringify(e ?? ''); + log.error(errorMessage); + } + } + }, [dispatch, shouldAutoSignIn]); + + return { + autoSignIn, + shouldAutoSignIn, + }; +} diff --git a/ui/hooks/identity/useAuthentication/useSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx new file mode 100644 index 000000000000..313ccc82f644 --- /dev/null +++ b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx @@ -0,0 +1,121 @@ +import { act } from '@testing-library/react-hooks'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import * as actions from '../../../store/actions'; +import { MetamaskIdentityProvider } from '../../../contexts/identity'; +import { useSignIn } from './useSignIn'; + +type ArrangeMocksMetamaskStateOverrides = { + isSignedIn: boolean; + isProfileSyncingEnabled: boolean; + participateInMetaMetrics: boolean; +}; + +const arrangeMockState = ( + stateOverrides: ArrangeMocksMetamaskStateOverrides, +) => { + return { + metamask: { + ...stateOverrides, + }, + }; +}; + +const arrangeMocks = () => { + const mockPerformSignInAction = jest.spyOn(actions, 'performSignIn'); + + const mockDisableProfileSyncingAction = jest.spyOn( + actions, + 'disableProfileSyncing', + ); + return { + mockPerformSignInAction, + mockDisableProfileSyncingAction, + }; +}; + +describe('useSignIn', () => { + it('should initialize correctly', () => { + const state = arrangeMockState({ + isProfileSyncingEnabled: false, + isSignedIn: false, + participateInMetaMetrics: false, + }); + arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + expect(hook.result.current.signIn).toBeDefined(); + expect(hook.result.current.shouldSignIn).toBeDefined(); + }); + + // @ts-expect-error This is missing from the Mocha type definitions + it.each` + isSignedIn | isProfileSyncingEnabled | participateInMetaMetrics + ${false} | ${false} | ${false} + ${true} | ${true} | ${false} + ${true} | ${false} | ${true} + ${true} | ${true} | ${true} + `( + 'should return false for shouldSignIn if alreadySignedIn: $alreadySignedIn, profileSyncingEnabled: $profileSyncingEnabled, metaMetricsEnabled: $metaMetricsEnabled', + (stateOverrides: ArrangeMocksMetamaskStateOverrides) => { + const state = arrangeMockState(stateOverrides); + arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + expect(hook.result.current.shouldSignIn()).toBe(false); + }, + ); + + // @ts-expect-error This is missing from the Mocha type definitions + it.each` + isSignedIn | isProfileSyncingEnabled | participateInMetaMetrics + ${false} | ${true} | ${false} + ${false} | ${false} | ${true} + ${false} | ${true} | ${true} + `( + 'should return true for shouldSignIn if alreadySignedIn: $alreadySignedIn, profileSyncingEnabled: $profileSyncingEnabled, metaMetricsEnabled: $metaMetricsEnabled', + (stateOverrides: ArrangeMocksMetamaskStateOverrides) => { + const state = arrangeMockState(stateOverrides); + arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + expect(hook.result.current.shouldSignIn()).toBe(true); + }, + ); + + it('should call performSignIn if shouldSignIn returns true', async () => { + // This state is set up so that shouldSignIn returns true + const state = arrangeMockState({ + isSignedIn: false, + isProfileSyncingEnabled: true, + participateInMetaMetrics: false, + }); + const { mockPerformSignInAction } = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSignIn(), + state, + undefined, + MetamaskIdentityProvider, + ); + + await act(async () => { + await hook.result.current.signIn(); + }); + + expect(mockPerformSignInAction).toHaveBeenCalled(); + }); +}); diff --git a/ui/hooks/identity/useAuthentication/useSignIn.ts b/ui/hooks/identity/useAuthentication/useSignIn.ts new file mode 100644 index 000000000000..82568c60c8c0 --- /dev/null +++ b/ui/hooks/identity/useAuthentication/useSignIn.ts @@ -0,0 +1,54 @@ +import { useCallback } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import log from 'loglevel'; +import { selectIsSignedIn } from '../../../selectors/identity/authentication'; +import { selectIsProfileSyncingEnabled } from '../../../selectors/identity/profile-syncing'; +import { performSignIn } from '../../../store/actions'; +import { getParticipateInMetaMetrics } from '../../../selectors'; + +/** + * Custom hook to manage sign-in based on the user's authentication status, + * profile syncing preference, and participation in MetaMetrics. + * + * This hook encapsulates the logic for initiating a sign-in process if the user is not already signed in + * and either profile syncing or MetaMetrics participation is enabled. It handles loading state and errors + * during the sign-in process. + * + * @returns An object containing: + * - `signIn`: A function to initiate the sign-in process. + * - `shouldSignIn`: A function to determine if the user should sign in based on the current state. + */ +export function useSignIn(): { + signIn: () => Promise; + shouldSignIn: () => boolean; +} { + const dispatch = useDispatch(); + + const isSignedIn = useSelector(selectIsSignedIn); + const isProfileSyncingEnabled = useSelector(selectIsProfileSyncingEnabled); + const isParticipateInMetaMetrics = useSelector(getParticipateInMetaMetrics); + + const shouldSignIn = useCallback(() => { + return ( + !isSignedIn && (isProfileSyncingEnabled || isParticipateInMetaMetrics) + ); + }, [isSignedIn, isProfileSyncingEnabled, isParticipateInMetaMetrics]); + + const signIn = useCallback(async () => { + if (shouldSignIn()) { + try { + await dispatch(performSignIn()); + } catch (e) { + // If an error occurs during the sign-in process, silently fail + const errorMessage = + e instanceof Error ? e.message : JSON.stringify(e ?? ''); + log.error(errorMessage); + } + } + }, [dispatch, shouldSignIn]); + + return { + signIn, + shouldSignIn, + }; +} diff --git a/ui/hooks/metamask-notifications/useNotifications.ts b/ui/hooks/metamask-notifications/useNotifications.ts index 60eb154bc75e..b2ada59c2f7a 100644 --- a/ui/hooks/metamask-notifications/useNotifications.ts +++ b/ui/hooks/metamask-notifications/useNotifications.ts @@ -1,6 +1,6 @@ import { useState, useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import type { InternalAccount } from '@metamask/keyring-api'; +import type { InternalAccount } from '@metamask/keyring-internal-api'; import log from 'loglevel'; import { type MarkAsReadNotificationsParam } from '@metamask/notification-services-controller/notification-services'; diff --git a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx index b67c2ea80cef..b228698f391e 100644 --- a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx +++ b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx @@ -1,125 +1,183 @@ -import React from 'react'; -import { Provider } from 'react-redux'; -import { renderHook, act } from '@testing-library/react-hooks'; -import configureStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import type { Store } from 'redux'; -import * as actions from '../../store/actions'; -import { MetamaskNotificationsProvider } from '../../contexts/metamask-notifications/metamask-notifications'; +import { waitFor } from '@testing-library/react'; +import * as ActionsModule from '../../store/actions'; +import * as NotificationSelectorsModule from '../../selectors/metamask-notifications/metamask-notifications'; +import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers'; import { useSwitchFeatureAnnouncementsChange, - useSwitchAccountNotifications, useSwitchAccountNotificationsChange, + useAccountSettingsProps, } from './useSwitchNotifications'; -const middlewares = [thunk]; -const mockStore = configureStore(middlewares); - -jest.mock('../../store/actions', () => ({ - setFeatureAnnouncementsEnabled: jest.fn(), - checkAccountsPresence: jest.fn(), - updateOnChainTriggersByAccount: jest.fn(), - deleteOnChainTriggersByAccount: jest.fn(), - showLoadingIndication: jest.fn(), - hideLoadingIndication: jest.fn(), - fetchAndUpdateMetamaskNotifications: jest.fn(), -})); - -describe('useSwitchNotifications', () => { - let store: Store; - +describe('useSwitchFeatureAnnouncementsChange() tests', () => { beforeEach(() => { - store = mockStore({ - metamask: { - isFeatureAnnouncementsEnabled: false, - internalAccounts: { - accounts: { - '0x123': { - address: '0x123', - id: 'account1', - metadata: {}, - options: {}, - methods: [], - type: 'eip155:eoa', - }, - }, - }, - }, - }); - - store.dispatch = jest.fn().mockImplementation((action) => { - if (typeof action === 'function') { - return action(store.dispatch, store.getState); - } - return Promise.resolve(); - }); + jest.restoreAllMocks(); + }); - jest.clearAllMocks(); + const arrangeMocks = () => { + const mockSetFeatureAnnouncementsEnabled = jest.spyOn( + ActionsModule, + 'setFeatureAnnouncementsEnabled', + ); + return { + mockSetFeatureAnnouncementsEnabled, + }; + }; + + it('should update feature announcement when callback invoked', async () => { + const mocks = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSwitchFeatureAnnouncementsChange(), + {}, + ); + + await hook.result.current.onChange(true); + expect(mocks.mockSetFeatureAnnouncementsEnabled).toHaveBeenCalled(); }); - it('should toggle feature announcements', async () => { - const { result } = renderHook(() => useSwitchFeatureAnnouncementsChange(), { - wrapper: ({ children }) => ( - - - {children} - - - ), + it('should update error state when callback fails', async () => { + const mocks = arrangeMocks(); + mocks.mockSetFeatureAnnouncementsEnabled.mockImplementation(() => { + throw new Error('Mock Fail'); }); + const hook = renderHookWithProviderTyped( + () => useSwitchFeatureAnnouncementsChange(), + {}, + ); - await act(async () => { - await result.current.onChange(true); - }); + await hook.result.current.onChange(true); + expect(hook.result.current.error).toBeDefined(); + }); +}); - expect(actions.setFeatureAnnouncementsEnabled).toHaveBeenCalledWith(true); +describe('useSwitchAccountNotificationsChange() tests', () => { + const arrangeMocks = () => { + const mockUpdateOnChainTriggersByAccount = jest.spyOn( + ActionsModule, + 'updateOnChainTriggersByAccount', + ); + const mockDeleteOnChainTriggersByAccount = jest.spyOn( + ActionsModule, + 'deleteOnChainTriggersByAccount', + ); + + return { + mockUpdateOnChainTriggersByAccount, + mockDeleteOnChainTriggersByAccount, + }; + }; + + it('should invoke update notification triggers when an address is enabled', async () => { + const mocks = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSwitchAccountNotificationsChange(), + {}, + ); + + await hook.result.current.onChange(['0x1'], true); + expect(mocks.mockUpdateOnChainTriggersByAccount).toHaveBeenCalledWith([ + '0x1', + ]); + expect(mocks.mockDeleteOnChainTriggersByAccount).not.toHaveBeenCalled(); }); - it('should check account presence', async () => { - const { result } = renderHook(() => useSwitchAccountNotifications(), { - wrapper: ({ children }) => ( - - - {children} - - - ), - }); + it('should invoke delete notification triggers when an address is disabled', async () => { + const mocks = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useSwitchAccountNotificationsChange(), + {}, + ); + + await hook.result.current.onChange(['0x1'], false); + expect(mocks.mockUpdateOnChainTriggersByAccount).not.toHaveBeenCalled(); + expect(mocks.mockDeleteOnChainTriggersByAccount).toHaveBeenCalledWith([ + '0x1', + ]); + }); - await act(async () => { - await result.current.switchAccountNotifications(['0x123']); + it('should return an error value if it fails to update or delete triggers', async () => { + const mocks = arrangeMocks(); + mocks.mockUpdateOnChainTriggersByAccount.mockImplementation(() => { + throw new Error('Mock Error'); + }); + mocks.mockDeleteOnChainTriggersByAccount.mockImplementation(() => { + throw new Error('Mock Error'); }); - expect(actions.checkAccountsPresence).toHaveBeenCalledWith(['0x123']); - }); + const act = async (testEnableOrDisable: boolean) => { + const hook = renderHookWithProviderTyped( + () => useSwitchAccountNotificationsChange(), + {}, + ); + await hook.result.current.onChange(['0x1'], testEnableOrDisable); + return hook.result.current.error; + }; - it('should handle account notification changes', async () => { - const { result } = renderHook(() => useSwitchAccountNotificationsChange(), { - wrapper: ({ children }) => ( - - - {children} - - - ), - }); + const enableError = await act(true); + expect(enableError).toBeDefined(); + + const disableError = await act(false); + expect(disableError).toBeDefined(); + }); +}); - // Test enabling notifications - await act(async () => { - await result.current.onChange(['0x123'], true); +describe('useAccountSettingsProps() tests', () => { + const arrangeMocks = () => { + const mockCheckAccountsPresence = jest.spyOn( + ActionsModule, + 'checkAccountsPresence', + ); + const mockGetIsUpdatingMetamaskNotificationsAccount = jest + .spyOn( + NotificationSelectorsModule, + 'getIsUpdatingMetamaskNotificationsAccount', + ) + .mockReturnValue([]); + const mockSelectIsMetamaskNotificationsEnabled = jest + .spyOn( + NotificationSelectorsModule, + 'selectIsMetamaskNotificationsEnabled', + ) + .mockReturnValue(true); + + return { + mockCheckAccountsPresence, + mockGetIsUpdatingMetamaskNotificationsAccount, + mockSelectIsMetamaskNotificationsEnabled, + }; + }; + + it('Should invoke effect when notifications are enabled', async () => { + const mocks = arrangeMocks(); + renderHookWithProviderTyped(() => useAccountSettingsProps(['0x1']), {}); + + await waitFor(() => { + expect(mocks.mockCheckAccountsPresence).toHaveBeenCalled(); }); + }); - expect(actions.updateOnChainTriggersByAccount).toHaveBeenCalledWith([ - '0x123', - ]); + it('Should not invoke effect when notifications are disabled', async () => { + const mocks = arrangeMocks(); + mocks.mockSelectIsMetamaskNotificationsEnabled.mockReturnValue(false); + renderHookWithProviderTyped(() => useAccountSettingsProps(['0x1']), {}); - // Test disabling notifications - await act(async () => { - await result.current.onChange(['0x123'], false); + await waitFor(() => { + expect(mocks.mockCheckAccountsPresence).not.toHaveBeenCalled(); }); + }); - expect(actions.deleteOnChainTriggersByAccount).toHaveBeenCalledWith([ - '0x123', - ]); + it('Should be able to invoke refetch accounts function', async () => { + const mocks = arrangeMocks(); + const hook = renderHookWithProviderTyped( + () => useAccountSettingsProps(['0x1']), + {}, + ); + + await hook.result.current.update(['0x1', '0x2']); + await waitFor(() => { + expect(mocks.mockCheckAccountsPresence).toHaveBeenCalledWith([ + '0x1', + '0x2', + ]); + }); }); }); diff --git a/ui/hooks/metamask-notifications/useSwitchNotifications.ts b/ui/hooks/metamask-notifications/useSwitchNotifications.ts index 53e121473bac..08a03c33e4f1 100644 --- a/ui/hooks/metamask-notifications/useSwitchNotifications.ts +++ b/ui/hooks/metamask-notifications/useSwitchNotifications.ts @@ -8,7 +8,10 @@ import { updateOnChainTriggersByAccount, hideLoadingIndication, } from '../../store/actions'; -import { getIsUpdatingMetamaskNotificationsAccount } from '../../selectors/metamask-notifications/metamask-notifications'; +import { + getIsUpdatingMetamaskNotificationsAccount, + selectIsMetamaskNotificationsEnabled, +} from '../../selectors/metamask-notifications/metamask-notifications'; export function useSwitchFeatureAnnouncementsChange(): { onChange: (state: boolean) => Promise; @@ -28,7 +31,6 @@ export function useSwitchFeatureAnnouncementsChange(): { const errorMessage = e instanceof Error ? e.message : JSON.stringify(e ?? ''); setError(errorMessage); - throw e; } }, [dispatch], @@ -42,44 +44,6 @@ export function useSwitchFeatureAnnouncementsChange(): { export type UseSwitchAccountNotificationsData = { [address: string]: boolean }; -export function useSwitchAccountNotifications(): { - switchAccountNotifications: ( - accounts: string[], - ) => Promise; - isLoading: boolean; - error: string | null; -} { - const dispatch = useDispatch(); - - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(null); - - const switchAccountNotifications = useCallback( - async ( - accounts: string[], - ): Promise => { - setIsLoading(true); - setError(null); - - try { - const data = await dispatch(checkAccountsPresence(accounts)); - return data as unknown as UseSwitchAccountNotificationsData; - } catch (e) { - const errorMessage = - e instanceof Error ? e.message : JSON.stringify(e ?? ''); - setError(errorMessage); - log.error(errorMessage); - throw e; - } finally { - setIsLoading(false); - } - }, - [dispatch], - ); - - return { switchAccountNotifications, isLoading, error }; -} - export function useSwitchAccountNotificationsChange(): { onChange: (addresses: string[], state: boolean) => Promise; error: string | null; @@ -103,7 +67,6 @@ export function useSwitchAccountNotificationsChange(): { e instanceof Error ? e.message : JSON.stringify(e ?? ''); log.error(errorMessage); setError(errorMessage); - throw e; } dispatch(hideLoadingIndication()); }, @@ -146,6 +109,7 @@ export function useAccountSettingsProps(accounts: string[]) { const accountsBeingUpdated = useSelector( getIsUpdatingMetamaskNotificationsAccount, ); + const isEnabled = useSelector(selectIsMetamaskNotificationsEnabled); const fetchAccountSettings = useRefetchAccountSettings(); const [data, setData] = useState({}); const [loading, setLoading] = useState(false); @@ -169,15 +133,12 @@ export function useAccountSettingsProps(accounts: string[]) { // Effect - async get if accounts are enabled/disabled useEffect(() => { - try { - const memoAccounts: string[] = JSON.parse(jsonAccounts); - update(memoAccounts); - } catch { - setError('Failed to get account settings'); - } finally { - setLoading(false); + if (!isEnabled) { + return; } - }, [jsonAccounts, fetchAccountSettings]); + const memoAccounts: string[] = JSON.parse(jsonAccounts); + update(memoAccounts); + }, [jsonAccounts, fetchAccountSettings, isEnabled]); return { data, diff --git a/ui/hooks/snaps/useSnapSettings.ts b/ui/hooks/snaps/useSnapSettings.ts new file mode 100644 index 000000000000..ad2debc8cac2 --- /dev/null +++ b/ui/hooks/snaps/useSnapSettings.ts @@ -0,0 +1,55 @@ +import { useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { + forceUpdateMetamaskState, + handleSnapRequest, +} from '../../store/actions'; + +export function useSnapSettings({ snapId }: { snapId?: string }) { + const dispatch = useDispatch(); + const [loading, setLoading] = useState(true); + const [data, setData] = useState<{ id: string } | undefined>(undefined); + const [error, setError] = useState(undefined); + + useEffect(() => { + let cancelled = false; + async function fetchPage(id: string) { + try { + setError(undefined); + setLoading(true); + + const newData = (await handleSnapRequest({ + snapId: id, + origin: '', + handler: 'onSettingsPage', + request: { + jsonrpc: '2.0', + method: ' ', + }, + })) as { id: string }; + if (!cancelled) { + setData(newData); + forceUpdateMetamaskState(dispatch); + } + } catch (err) { + if (!cancelled) { + setError(err as Error); + } + } finally { + if (!cancelled) { + setLoading(false); + } + } + } + + if (snapId) { + fetchPage(snapId); + } + + return () => { + cancelled = true; + }; + }, [snapId]); + + return { data, error, loading }; +} diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts index b41fc38a9930..978b3ef8f098 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts @@ -2,11 +2,13 @@ import { renderHook } from '@testing-library/react-hooks'; import { act } from 'react-dom/test-utils'; import { - getCurrentCurrency, getCrossChainTokenExchangeRates, getCrossChainMetaMaskCachedBalances, } from '../selectors'; -import { getCurrencyRates } from '../ducks/metamask/metamask'; +import { + getCurrentCurrency, + getCurrencyRates, +} from '../ducks/metamask/metamask'; import { getNetworkConfigurationsByChainId } from '../../shared/modules/selectors/networks'; import { FormattedTokensWithBalances, @@ -18,11 +20,11 @@ jest.mock('react-redux', () => ({ })); jest.mock('../selectors', () => ({ - getCurrentCurrency: jest.fn(), getCrossChainTokenExchangeRates: jest.fn(), getCrossChainMetaMaskCachedBalances: jest.fn(), })); jest.mock('../ducks/metamask/metamask', () => ({ + getCurrentCurrency: jest.fn(), getCurrencyRates: jest.fn(), })); jest.mock('../../shared/modules/selectors/networks', () => ({ diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index ac5658278946..aa82f7823f44 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -2,6 +2,9 @@ import { shallowEqual, useSelector } from 'react-redux'; import { toChecksumAddress } from 'ethereumjs-util'; import { getCurrentCurrency, + getCurrencyRates, +} from '../ducks/metamask/metamask'; +import { getCrossChainTokenExchangeRates, getCrossChainMetaMaskCachedBalances, } from '../selectors'; @@ -9,7 +12,6 @@ import { getValueFromWeiHex, sumDecimals, } from '../../shared/modules/conversion.utils'; -import { getCurrencyRates } from '../ducks/metamask/metamask'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; import { TokenWithBalance } from '../components/app/assets/asset-list/asset-list'; import { getNetworkConfigurationsByChainId } from '../../shared/modules/selectors/networks'; diff --git a/ui/hooks/useAccountTotalFiatBalance.js b/ui/hooks/useAccountTotalFiatBalance.js index 1c86b29ea8ea..08c2f9eeb5f2 100644 --- a/ui/hooks/useAccountTotalFiatBalance.js +++ b/ui/hooks/useAccountTotalFiatBalance.js @@ -3,7 +3,6 @@ import { toChecksumAddress } from 'ethereumjs-util'; import { getCurrentChainId } from '../../shared/modules/selectors/networks'; import { getAllTokens, - getCurrentCurrency, getMetaMaskCachedBalances, getTokenExchangeRates, getConfirmationExchangeRates, @@ -18,6 +17,7 @@ import { import { getConversionRate, getNativeCurrency, + getCurrentCurrency, } from '../ducks/metamask/metamask'; import { formatCurrency } from '../helpers/utils/confirm-tx.util'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; diff --git a/ui/hooks/useEthFiatAmount.js b/ui/hooks/useEthFiatAmount.js index de6d4488e84f..dadb634cdf86 100644 --- a/ui/hooks/useEthFiatAmount.js +++ b/ui/hooks/useEthFiatAmount.js @@ -1,8 +1,11 @@ import { useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { getCurrentCurrency, getShouldShowFiat } from '../selectors'; +import { getShouldShowFiat } from '../selectors'; import { formatCurrency } from '../helpers/utils/confirm-tx.util'; -import { getConversionRate } from '../ducks/metamask/metamask'; +import { + getConversionRate, + getCurrentCurrency, +} from '../ducks/metamask/metamask'; import { decEthToConvertedCurrency } from '../../shared/modules/conversion.utils'; /** diff --git a/ui/hooks/useFiatFormatter.test.ts b/ui/hooks/useFiatFormatter.test.ts index 7e6423f1df34..51b896e5bc10 100644 --- a/ui/hooks/useFiatFormatter.test.ts +++ b/ui/hooks/useFiatFormatter.test.ts @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react-hooks'; import { getIntlLocale } from '../ducks/locale/locale'; -import { getCurrentCurrency } from '../selectors'; +import { getCurrentCurrency } from '../ducks/metamask/metamask'; import { useFiatFormatter } from './useFiatFormatter'; jest.mock('react-redux', () => ({ @@ -11,7 +11,7 @@ jest.mock('../ducks/locale/locale', () => ({ getIntlLocale: jest.fn(), })); -jest.mock('../selectors', () => ({ +jest.mock('../ducks/metamask/metamask', () => ({ getCurrentCurrency: jest.fn(), })); diff --git a/ui/hooks/useFiatFormatter.ts b/ui/hooks/useFiatFormatter.ts index 0c9bd33ffee5..c671db5668b5 100644 --- a/ui/hooks/useFiatFormatter.ts +++ b/ui/hooks/useFiatFormatter.ts @@ -1,6 +1,6 @@ import { useSelector } from 'react-redux'; import { getIntlLocale } from '../ducks/locale/locale'; -import { getCurrentCurrency } from '../selectors'; +import { getCurrentCurrency } from '../ducks/metamask/metamask'; import { shortenString } from '../helpers/utils/util'; /** diff --git a/ui/hooks/useGetAssetImageUrl.test.ts b/ui/hooks/useGetAssetImageUrl.test.ts index a6fe1bdc68a3..dffbb10fe9fb 100644 --- a/ui/hooks/useGetAssetImageUrl.test.ts +++ b/ui/hooks/useGetAssetImageUrl.test.ts @@ -33,7 +33,7 @@ describe('useGetAssetImageUrl', () => { it('should return data successfully when image is null', async () => { mockGetAssetImageURL.mockResolvedValueOnce(''); - const testImage = null; + const testImage = undefined; let result; await act(async () => { result = renderHook(() => diff --git a/ui/hooks/useGetAssetImageUrl.ts b/ui/hooks/useGetAssetImageUrl.ts index b84a588ff68d..636a0f519e25 100644 --- a/ui/hooks/useGetAssetImageUrl.ts +++ b/ui/hooks/useGetAssetImageUrl.ts @@ -1,7 +1,10 @@ import { useState, useEffect } from 'react'; import { getAssetImageURL } from '../helpers/utils/util'; -const useGetAssetImageUrl = (image: string | null, ipfsGateway: string) => { +const useGetAssetImageUrl = ( + image: string | undefined, + ipfsGateway: string, +) => { const [imageUrl, setImageUrl] = useState(''); useEffect(() => { diff --git a/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx b/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx index 921baaebab08..9b6cd5e51455 100644 --- a/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx +++ b/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { Provider } from 'react-redux'; -import { BtcAccountType, InternalAccount } from '@metamask/keyring-api'; +import { BtcAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import mockState from '../../test/data/mock-state.json'; import configureStore from '../store/store'; import { createMockInternalAccount } from '../../test/jest/mocks'; diff --git a/ui/hooks/useMultichainAccountTotalFiatBalance.ts b/ui/hooks/useMultichainAccountTotalFiatBalance.ts index 335b8399c6d5..816be806142c 100644 --- a/ui/hooks/useMultichainAccountTotalFiatBalance.ts +++ b/ui/hooks/useMultichainAccountTotalFiatBalance.ts @@ -1,5 +1,6 @@ import { useSelector } from 'react-redux'; -import { InternalAccount, isEvmAccountType } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; +import { isEvmAccountType } from '@metamask/keyring-api'; import { getMultichainCurrencyImage, getMultichainBalances, diff --git a/ui/hooks/useMultichainSelector.test.ts b/ui/hooks/useMultichainSelector.test.ts index e5d7f197ffcb..f04fef64783a 100644 --- a/ui/hooks/useMultichainSelector.test.ts +++ b/ui/hooks/useMultichainSelector.test.ts @@ -1,4 +1,4 @@ -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { createMockInternalAccount } from '../../test/jest/mocks'; import { renderHookWithProvider } from '../../test/lib/render-helpers'; import { getSelectedNetworkClientId } from '../../shared/modules/selectors/networks'; diff --git a/ui/hooks/useMultichainSelector.ts b/ui/hooks/useMultichainSelector.ts index 9bd979df7e7e..286e8b111cd7 100644 --- a/ui/hooks/useMultichainSelector.ts +++ b/ui/hooks/useMultichainSelector.ts @@ -1,5 +1,5 @@ import { useSelector, DefaultRootState } from 'react-redux'; -import { InternalAccount } from '@metamask/keyring-api'; +import { InternalAccount } from '@metamask/keyring-internal-api'; import { getSelectedInternalAccount } from '../selectors'; export function useMultichainSelector< diff --git a/ui/hooks/useNfts.ts b/ui/hooks/useNfts.ts new file mode 100644 index 000000000000..18e69226463b --- /dev/null +++ b/ui/hooks/useNfts.ts @@ -0,0 +1,71 @@ +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import { isEqual } from 'lodash'; +import { getNfts, getNftContracts } from '../ducks/metamask/metamask'; +import { getSelectedInternalAccount } from '../selectors'; +import { getCurrentChainId } from '../../shared/modules/selectors/networks'; +import { NFT } from '../components/multichain/asset-picker-amount/asset-picker-modal/types'; +import { usePrevious } from './usePrevious'; +import { useI18nContext } from './useI18nContext'; + +export function useNfts() { + const t = useI18nContext(); + const nfts = useSelector(getNfts); + const { address: selectedAddress } = useSelector(getSelectedInternalAccount); + const chainId = useSelector(getCurrentChainId); + const nftContracts = useSelector(getNftContracts); + + const previouslyOwnedText = t('nftsPreviouslyOwned'); + const unknownCollectionText = t('unknownCollection'); + + const [currentlyOwnedNfts, setCurrentlyOwnedNfts] = useState([]); + const [previouslyOwnedNfts, setPreviouslyOwnedNfts] = useState([]); + const [loading, setNftsLoading] = useState(() => nfts?.length >= 0); + const prevNfts = usePrevious(nfts); + const prevChainId = usePrevious(chainId); + const prevSelectedAddress = usePrevious(selectedAddress); + + useEffect(() => { + const selectNfts = () => { + setNftsLoading(true); + if (selectedAddress === undefined || chainId === undefined) { + return; + } + + const previousNfts: NFT[] = []; + const currentNfts: NFT[] = []; + + nfts.forEach((nft: NFT) => { + if (nft?.isCurrentlyOwned === false) { + previousNfts.push(nft); + } else { + currentNfts.push(nft); + } + }); + setPreviouslyOwnedNfts(previousNfts); + setCurrentlyOwnedNfts(currentNfts); + setNftsLoading(false); + }; + + if ( + !isEqual(prevNfts, nfts) || + !isEqual(prevSelectedAddress, selectedAddress) || + !isEqual(prevChainId, chainId) + ) { + selectNfts(); + } + }, [ + nfts, + prevNfts, + nftContracts, + setNftsLoading, + chainId, + prevChainId, + selectedAddress, + prevSelectedAddress, + previouslyOwnedText, + unknownCollectionText, + ]); + + return { loading, currentlyOwnedNfts, previouslyOwnedNfts }; +} diff --git a/ui/hooks/useTokenFiatAmount.js b/ui/hooks/useTokenFiatAmount.js index 325dbf5eea22..6f48715b7fae 100644 --- a/ui/hooks/useTokenFiatAmount.js +++ b/ui/hooks/useTokenFiatAmount.js @@ -2,7 +2,6 @@ import { useMemo } from 'react'; import { shallowEqual, useSelector } from 'react-redux'; import { getTokenExchangeRates, - getCurrentCurrency, getShouldShowFiat, getConfirmationExchangeRates, getMarketData, @@ -10,7 +9,10 @@ import { } from '../selectors'; import { getNetworkConfigurationsByChainId } from '../../shared/modules/selectors/networks'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; -import { getConversionRate } from '../ducks/metamask/metamask'; +import { + getConversionRate, + getCurrentCurrency, +} from '../ducks/metamask/metamask'; import { isEqualCaseInsensitive } from '../../shared/modules/string-utils'; /** diff --git a/ui/hooks/useTokensToSearch.js b/ui/hooks/useTokensToSearch.js index bf37f6cb08fe..657bb0afed09 100644 --- a/ui/hooks/useTokensToSearch.js +++ b/ui/hooks/useTokensToSearch.js @@ -6,13 +6,14 @@ import { formatIconUrlWithProxy } from '@metamask/assets-controllers'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; import { getTokenExchangeRates, - getCurrentCurrency, getSwapsDefaultToken, getTokenList, } from '../selectors'; import { getCurrentChainId } from '../../shared/modules/selectors/networks'; -import { getConversionRate } from '../ducks/metamask/metamask'; - +import { + getConversionRate, + getCurrentCurrency, +} from '../ducks/metamask/metamask'; import { getSwapsTokens } from '../ducks/swaps/swaps'; import { isSwapsDefaultTokenSymbol } from '../../shared/modules/swaps.utils'; import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils'; diff --git a/ui/hooks/useTransactionDisplayData.js b/ui/hooks/useTransactionDisplayData.js index 07c4d0ade382..28a1c913b938 100644 --- a/ui/hooks/useTransactionDisplayData.js +++ b/ui/hooks/useTransactionDisplayData.js @@ -40,6 +40,7 @@ import { selectBridgeHistoryForAccount } from '../ducks/bridge-status/selectors' import { useBridgeTokenDisplayData } from '../pages/bridge/hooks/useBridgeTokenDisplayData'; import { formatAmount } from '../pages/confirmations/components/simulation-details/formatAmount'; import { getIntlLocale } from '../ducks/locale/locale'; +import { NETWORK_TO_SHORT_NETWORK_NAME_MAP } from '../../shared/constants/bridge'; import { useI18nContext } from './useI18nContext'; import { useTokenFiatAmount } from './useTokenFiatAmount'; import { useUserPreferencedCurrency } from './useUserPreferencedCurrency'; @@ -122,7 +123,7 @@ export function useTransactionDisplayData(transactionGroup) { bridgeHistoryItem, srcTxMeta: transactionGroup.initialTransaction, }); - const destChainName = destNetwork?.name; + const destChainName = NETWORK_TO_SHORT_NETWORK_NAME_MAP[destNetwork?.chainId]; const { initialTransaction, primaryTransaction } = transactionGroup; // initialTransaction contains the data we need to derive the primary purpose of this transaction group diff --git a/ui/index.js b/ui/index.js index a63b2acc86fa..54d952eb85f4 100644 --- a/ui/index.js +++ b/ui/index.js @@ -29,7 +29,6 @@ import { getUnapprovedTransactions, getNetworkToAutomaticallySwitchTo, getSwitchedNetworkDetails, - getUseRequestQueue, } from './selectors'; import { ALERT_STATE } from './ducks/alerts'; import { @@ -243,10 +242,7 @@ async function runInitialActions(store) { // Register this window as the current popup // and set in background state - if ( - getUseRequestQueue(state) && - getEnvironmentType() === ENVIRONMENT_TYPE_POPUP - ) { + if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { const thisPopupId = Date.now(); global.metamask.id = thisPopupId; await store.dispatch(actions.setCurrentExtensionPopupId(thisPopupId)); diff --git a/ui/pages/asset/asset.tsx b/ui/pages/asset/asset.tsx index 1d1acdaaa582..19f487987110 100644 --- a/ui/pages/asset/asset.tsx +++ b/ui/pages/asset/asset.tsx @@ -2,12 +2,12 @@ import React, { useEffect } from 'react'; import { useSelector } from 'react-redux'; import { Redirect, useParams } from 'react-router-dom'; import { Hex } from '@metamask/utils'; +import { Nft } from '@metamask/assets-controllers'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import NftDetails from '../../components/app/assets/nfts/nft-details/nft-details'; import { getSelectedAccountTokensAcrossChains } from '../../selectors'; import { getNFTsByChainId } from '../../ducks/metamask/metamask'; import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; - import { Token } from '../../components/app/assets/token-list/token-list'; import TokenAsset from './components/token-asset'; import { findAssetByAddress } from './util'; @@ -29,7 +29,7 @@ const Asset = () => { const token = findAssetByAddress(selectedAccountTokensChains, asset, chainId); - const nft = nfts.find( + const nft: Nft = nfts.find( ({ address, tokenId }: { address: Hex; tokenId: string }) => // @ts-expect-error TODO: Fix this type error by handling undefined parameters isEqualCaseInsensitive(address, asset) && id === tokenId.toString(), diff --git a/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap b/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap index dc3cf4c408de..2caa7f6eb5bb 100644 --- a/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap +++ b/ui/pages/asset/components/__snapshots__/asset-page.test.tsx.snap @@ -198,7 +198,7 @@ exports[`AssetPage should render a native asset 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    static-logo - $0.00 -

    + />
    +
    +

    + Network: +

    +

    +

    + static-logo +
    + Ethereum Mainnet +

    +
    @@ -318,17 +340,7 @@ exports[`AssetPage should render a native asset 1`] = ` >
    -
    -
    - You have no transactions -
    -
    -
    + />
    @@ -517,7 +529,7 @@ exports[`AssetPage should render an ERC20 asset without prices 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    static-logo +
    +

    + Network: +

    +

    +

    + static-logo +
    + Ethereum Mainnet +

    +
    @@ -697,17 +733,7 @@ exports[`AssetPage should render an ERC20 asset without prices 1`] = ` >
    -
    -
    - You have no transactions -
    -
    -
    + />
    @@ -1022,7 +1048,7 @@ exports[`AssetPage should render an ERC20 token with prices 1`] = ` class="mm-box mm-badge-wrapper__badge-container mm-badge-wrapper__badge-container--rectangular-bottom-right" >
    static-logo +
    +

    + Network: +

    +

    +

    + static-logo +
    + Ethereum Mainnet +

    +
    @@ -1230,17 +1280,7 @@ exports[`AssetPage should render an ERC20 token with prices 1`] = ` >
    -
    -
    - You have no transactions -
    -
    -
    + />
    diff --git a/ui/pages/asset/components/asset-page.test.tsx b/ui/pages/asset/components/asset-page.test.tsx index 71ca5483b50c..9e7a2f146942 100644 --- a/ui/pages/asset/components/asset-page.test.tsx +++ b/ui/pages/asset/components/asset-page.test.tsx @@ -4,7 +4,10 @@ import thunk from 'redux-thunk'; import { fireEvent, waitFor } from '@testing-library/react'; import { EthAccountType } from '@metamask/keyring-api'; import nock from 'nock'; -import { CHAIN_IDS } from '../../../../shared/constants/network'; +import { + CHAIN_IDS, + MAINNET_DISPLAY_NAME, +} from '../../../../shared/constants/network'; import { renderWithProvider } from '../../../../test/jest/rendering'; import { KeyringType } from '../../../../shared/constants/keyring'; import { AssetType } from '../../../../shared/constants/transaction'; @@ -52,6 +55,9 @@ describe('AssetPage', () => { localeMessages: { currentLocale: 'en', }, + appState: { + confirmationExchangeRates: {}, + }, metamask: { tokenList: {}, tokenBalances: { @@ -327,6 +333,18 @@ describe('AssetPage', () => { expect(mmiPortfolioButton).toBeInTheDocument(); }); + it('should render the network name', async () => { + const mockedStore = configureMockStore([thunk])(mockStore); + + const { queryByTestId } = renderWithProvider( + , + mockedStore, + ); + const networkNode = queryByTestId('asset-network'); + expect(networkNode).toBeInTheDocument(); + expect(networkNode?.textContent).toBe(MAINNET_DISPLAY_NAME); + }); + it('should render a native asset', () => { const { container } = renderWithProvider( , diff --git a/ui/pages/asset/components/asset-page.tsx b/ui/pages/asset/components/asset-page.tsx index 566a85d3c02e..e65e263d088c 100644 --- a/ui/pages/asset/components/asset-page.tsx +++ b/ui/pages/asset/components/asset-page.tsx @@ -6,7 +6,6 @@ import { isEqual } from 'lodash'; import { getNativeTokenAddress } from '@metamask/assets-controllers'; import { Hex } from '@metamask/utils'; import { - getCurrentCurrency, getDataCollectionForMarketing, getIsBridgeChain, getIsSwapsChain, @@ -22,6 +21,7 @@ import { getShowFiatInTestnets, } from '../../../selectors'; import { + AlignItems, Display, FlexDirection, IconColor, @@ -30,6 +30,8 @@ import { TextVariant, } from '../../../helpers/constants/design-system'; import { + AvatarNetwork, + AvatarNetworkSize, Box, ButtonIcon, ButtonIconSize, @@ -45,14 +47,21 @@ import TokenCell from '../../../components/app/assets/token-cell'; import TransactionList from '../../../components/app/transaction-list'; import { getPricePrecision, localizeLargeNumber } from '../util'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; -import { getConversionRate } from '../../../ducks/metamask/metamask'; +import { + getConversionRate, + getCurrentCurrency, +} from '../../../ducks/metamask/metamask'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import CoinButtons from '../../../components/app/wallet-overview/coin-buttons'; import { getIsNativeTokenBuyable } from '../../../ducks/ramps'; import { calculateTokenBalance } from '../../../components/app/assets/util/calculateTokenBalance'; import { useTokenBalances } from '../../../hooks/useTokenBalances'; import { useMultichainSelector } from '../../../hooks/useMultichainSelector'; -import { getMultichainShouldShowFiat } from '../../../selectors/multichain'; +import { + getImageForChainId, + getMultichainShouldShowFiat, +} from '../../../selectors/multichain'; +import { getNetworkConfigurationsByChainId } from '../../../../shared/modules/selectors/networks'; import { getPortfolioUrl } from '../../../helpers/utils/portfolio'; import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; import AssetChart from './chart/asset-chart'; @@ -73,7 +82,7 @@ export type Asset = ( /** The number of decimal places to move left when displaying balances */ decimals: number; /** An array of token list sources the asset appears in, e.g. [1inch,Sushiswap] */ - aggregators?: []; + aggregators?: string[]; } ) & { /** The hexadecimal chain id */ @@ -166,7 +175,7 @@ const AssetPage = ({ // Market and conversion rate data const baseCurrency = marketData[chainId]?.[address]?.currency; - const tokenMarketPrice = marketData[chainId]?.[address]?.price || 0; + const tokenMarketPrice = marketData[chainId]?.[address]?.price || undefined; const tokenExchangeRate = type === AssetType.native ? currencyRates[symbol]?.conversionRate @@ -212,6 +221,12 @@ const AssetPage = ({ [account.address, isMarketingEnabled, isMetaMetricsEnabled, metaMetricsId], ); + const networkConfigurationsByChainId = useSelector( + getNetworkConfigurationsByChainId, + ); + const networkName = networkConfigurationsByChainId[chainId]?.name; + const tokenChainImage = getImageForChainId(chainId); + return ( + {renderRow( + t('network'), + + + {networkName} + , + )} {type === AssetType.token && ( {renderRow( @@ -330,7 +363,13 @@ const AssetPage = ({ > {t('tokenList')}
    - {asset.aggregators.join(', ')} + + {asset.aggregators + .map((agg) => + agg.replace(/^metamask$/iu, 'MetaMask'), + ) + .join(', ')} + )} @@ -428,9 +467,9 @@ const AssetPage = ({ {t('yourActivity')} {type === AssetType.native ? ( - + ) : ( - + )} diff --git a/ui/pages/bridge/__snapshots__/index.test.tsx.snap b/ui/pages/bridge/__snapshots__/index.test.tsx.snap index 51473d6fefa0..072c7d7eee6b 100644 --- a/ui/pages/bridge/__snapshots__/index.test.tsx.snap +++ b/ui/pages/bridge/__snapshots__/index.test.tsx.snap @@ -222,11 +222,15 @@ exports[`Bridge renders the component with initial props 1`] = ` diff --git a/ui/pages/bridge/hooks/useAddToken.ts b/ui/pages/bridge/hooks/useAddToken.ts index 1f2dc117513b..f1a148ce7732 100644 --- a/ui/pages/bridge/hooks/useAddToken.ts +++ b/ui/pages/bridge/hooks/useAddToken.ts @@ -1,6 +1,6 @@ import { useDispatch, useSelector } from 'react-redux'; -import { NetworkConfiguration } from '@metamask/network-controller'; -import { QuoteResponse } from '../types'; +import type { NetworkConfiguration } from '@metamask/network-controller'; +import type { QuoteResponse } from '../../../../shared/types/bridge'; import { FEATURED_RPCS } from '../../../../shared/constants/network'; import { addToken, addNetwork } from '../../../store/actions'; import { diff --git a/ui/pages/bridge/hooks/useHandleApprovalTx.ts b/ui/pages/bridge/hooks/useHandleApprovalTx.ts index 23f4b19cf2b8..7e469bc78ead 100644 --- a/ui/pages/bridge/hooks/useHandleApprovalTx.ts +++ b/ui/pages/bridge/hooks/useHandleApprovalTx.ts @@ -1,8 +1,15 @@ import { TransactionType } from '@metamask/transaction-controller'; -import { Hex } from '@metamask/utils'; +import type { Hex } from '@metamask/utils'; import { BigNumber } from 'bignumber.js'; -import { TxData, QuoteResponse, FeeType } from '../types'; -import { isEthUsdt, getEthUsdtResetData } from '../bridge.util'; +import { + type TxData, + type QuoteResponse, + FeeType, +} from '../../../../shared/types/bridge'; +import { + isEthUsdt, + getEthUsdtResetData, +} from '../../../../shared/modules/bridge-utils/bridge.util'; import { ETH_USDT_ADDRESS } from '../../../../shared/constants/bridge'; import { getBridgeERC20Allowance } from '../../../ducks/bridge/actions'; import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils'; diff --git a/ui/pages/bridge/hooks/useHandleBridgeTx.ts b/ui/pages/bridge/hooks/useHandleBridgeTx.ts index feb7400acc71..5d7e1a1b527c 100644 --- a/ui/pages/bridge/hooks/useHandleBridgeTx.ts +++ b/ui/pages/bridge/hooks/useHandleBridgeTx.ts @@ -1,7 +1,7 @@ import { BigNumber } from 'bignumber.js'; import { TransactionType } from '@metamask/transaction-controller'; import { Numeric } from '../../../../shared/modules/Numeric'; -import { FeeType, QuoteResponse } from '../types'; +import { FeeType, type QuoteResponse } from '../../../../shared/types/bridge'; import useHandleTx from './useHandleTx'; export default function useHandleBridgeTx() { diff --git a/ui/pages/bridge/hooks/useHandleTx.ts b/ui/pages/bridge/hooks/useHandleTx.ts index c3a3ede01002..59b6c7ee9c89 100644 --- a/ui/pages/bridge/hooks/useHandleTx.ts +++ b/ui/pages/bridge/hooks/useHandleTx.ts @@ -15,7 +15,7 @@ import { } from '../../../ducks/bridge/utils'; import { getGasFeeEstimates } from '../../../ducks/metamask/metamask'; import { checkNetworkAndAccountSupports1559 } from '../../../selectors'; -import { ChainId } from '../types'; +import type { ChainId } from '../../../../shared/types/bridge'; import { decimalToPrefixedHex } from '../../../../shared/modules/conversion.utils'; import { getIsSmartTransaction } from '../../../../shared/modules/selectors'; diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx index b64768cb47e8..bef9e4d6bf86 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx @@ -465,7 +465,10 @@ describe('ui/pages/bridge/hooks/useSubmitBridgeTransaction', () => { ); // Assert - expect(mockHistory.push).toHaveBeenCalledWith('/'); + expect(mockHistory.push).toHaveBeenCalledWith({ + pathname: '/', + state: { stayOnHomePage: true }, + }); }); }); }); diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts index eb9cd3c440d8..fdcf1ed46bfc 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts @@ -3,7 +3,10 @@ import { zeroAddress } from 'ethereumjs-util'; import { useHistory } from 'react-router-dom'; import { TransactionMeta } from '@metamask/transaction-controller'; import { createProjectLogger, Hex } from '@metamask/utils'; -import { QuoteMetadata, QuoteResponse } from '../types'; +import type { + QuoteMetadata, + QuoteResponse, +} from '../../../../shared/types/bridge'; import { AWAITING_SIGNATURES_ROUTE, CROSS_CHAIN_SWAP_ROUTE, @@ -134,7 +137,15 @@ export default function useSubmitBridgeTransaction() { startPollingForBridgeTxStatus({ bridgeTxMeta, statusRequest, - quoteResponse, + quoteResponse: { + ...quoteResponse, + sentAmount: { + amount: quoteResponse.sentAmount.amount.toString(), + valueInCurrency: quoteResponse.sentAmount.valueInCurrency + ? quoteResponse.sentAmount.valueInCurrency.toString() + : null, + }, + }, slippagePercentage: slippage ?? 0, startTime: bridgeTxMeta.time, }), @@ -150,7 +161,10 @@ export default function useSubmitBridgeTransaction() { // Route user to activity tab on Home page await dispatch(setDefaultHomeActiveTabName('activity')); - history.push(DEFAULT_ROUTE); + history.push({ + pathname: DEFAULT_ROUTE, + state: { stayOnHomePage: true }, + }); }; return { diff --git a/ui/pages/bridge/index.test.tsx b/ui/pages/bridge/index.test.tsx index 7878126c47e1..e5f225108b88 100644 --- a/ui/pages/bridge/index.test.tsx +++ b/ui/pages/bridge/index.test.tsx @@ -90,6 +90,6 @@ describe('Bridge', () => { expect(getByText('Bridge')).toBeInTheDocument(); expect(container).toMatchSnapshot(); - expect(mockResetBridgeState).toHaveBeenCalledTimes(2); + expect(mockResetBridgeState).toHaveBeenCalledTimes(1); }); }); diff --git a/ui/pages/bridge/index.tsx b/ui/pages/bridge/index.tsx index fa815a0de2b9..15c3a0365cc9 100644 --- a/ui/pages/bridge/index.tsx +++ b/ui/pages/bridge/index.tsx @@ -67,8 +67,6 @@ const CrossChainSwap = () => { useEffect(() => { // Reset controller and inputs before unloading the page - resetControllerAndInputStates(); - window.addEventListener('beforeunload', resetControllerAndInputStates); return () => { diff --git a/ui/pages/bridge/prepare/__snapshots__/bridge-cta-button.test.tsx.snap b/ui/pages/bridge/prepare/__snapshots__/bridge-cta-button.test.tsx.snap index 0b46d2764523..6014dbaddb23 100644 --- a/ui/pages/bridge/prepare/__snapshots__/bridge-cta-button.test.tsx.snap +++ b/ui/pages/bridge/prepare/__snapshots__/bridge-cta-button.test.tsx.snap @@ -2,9 +2,13 @@ exports[`BridgeCTAButton should disable the component when quotes are loading and there are no existing quotes 1`] = `
    -

    +

    +

    +

    `; @@ -23,20 +27,28 @@ exports[`BridgeCTAButton should enable the component when quotes are loading and exports[`BridgeCTAButton should render the component when amount and dest token is missing 1`] = `
    -

    - Select token and amount -

    +

    + Select token and amount +

    +
    `; exports[`BridgeCTAButton should render the component's initial state 1`] = `
    -

    - Select token -

    +

    + Select token +

    +
    `; diff --git a/ui/pages/bridge/prepare/__snapshots__/prepare-bridge-page.test.tsx.snap b/ui/pages/bridge/prepare/__snapshots__/prepare-bridge-page.test.tsx.snap index d5b980d13fd6..c69368d0b88e 100644 --- a/ui/pages/bridge/prepare/__snapshots__/prepare-bridge-page.test.tsx.snap +++ b/ui/pages/bridge/prepare/__snapshots__/prepare-bridge-page.test.tsx.snap @@ -172,11 +172,15 @@ exports[`PrepareBridgePage should render the component, with initial state 1`] = @@ -357,11 +361,15 @@ exports[`PrepareBridgePage should render the component, with inputs set 1`] = ` diff --git a/ui/pages/bridge/prepare/bridge-cta-button.test.tsx b/ui/pages/bridge/prepare/bridge-cta-button.test.tsx index d4e0fd0855c5..92d6591a2808 100644 --- a/ui/pages/bridge/prepare/bridge-cta-button.test.tsx +++ b/ui/pages/bridge/prepare/bridge-cta-button.test.tsx @@ -4,9 +4,7 @@ import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import mockBridgeQuotesNativeErc20 from '../../../../test/data/bridge/mock-quotes-native-erc20.json'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; +import { RequestStatus } from '../../../../shared/types/bridge'; import { BridgeCTAButton } from './bridge-cta-button'; describe('BridgeCTAButton', () => { @@ -23,7 +21,7 @@ describe('BridgeCTAButton', () => { bridgeSliceOverrides: { fromTokenInputValue: 1 }, }); const { container, getByText } = renderWithProvider( - , + , configureStore(mockStore), ); @@ -54,7 +52,7 @@ describe('BridgeCTAButton', () => { }, }); const { getByText } = renderWithProvider( - , + , configureStore(mockStore), ); @@ -83,7 +81,7 @@ describe('BridgeCTAButton', () => { }, }); const { getByText, container } = renderWithProvider( - , + , configureStore(mockStore), ); @@ -118,7 +116,7 @@ describe('BridgeCTAButton', () => { }, }); const { getByText, getByRole } = renderWithProvider( - , + , configureStore(mockStore), ); @@ -159,7 +157,7 @@ describe('BridgeCTAButton', () => { }, }); const { container } = renderWithProvider( - , + , configureStore(mockStore), ); @@ -199,7 +197,7 @@ describe('BridgeCTAButton', () => { }, }); const { getByText, getByRole, container } = renderWithProvider( - , + , configureStore(mockStore), ); diff --git a/ui/pages/bridge/prepare/bridge-cta-button.tsx b/ui/pages/bridge/prepare/bridge-cta-button.tsx index 97e6c6680d9f..7b8fdf397e5a 100644 --- a/ui/pages/bridge/prepare/bridge-cta-button.tsx +++ b/ui/pages/bridge/prepare/bridge-cta-button.tsx @@ -1,6 +1,7 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { + ButtonLink, ButtonPrimary, ButtonPrimarySize, Text, @@ -18,7 +19,9 @@ import { import { useI18nContext } from '../../../hooks/useI18nContext'; import useSubmitBridgeTransaction from '../hooks/useSubmitBridgeTransaction'; import { + AlignItems, BlockSize, + JustifyContent, TextAlign, TextColor, TextVariant, @@ -32,8 +35,14 @@ import { useTradeProperties } from '../../../hooks/bridge/events/useTradePropert import { MetaMetricsEventName } from '../../../../shared/constants/metametrics'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../../shared/constants/swaps'; import { getNativeCurrency } from '../../../ducks/metamask/metamask'; - -export const BridgeCTAButton = () => { +import { Row } from '../layout'; +import { isQuoteExpired as isQuoteExpiredUtil } from '../utils/quote'; + +export const BridgeCTAButton = ({ + onFetchNewQuotes, +}: { + onFetchNewQuotes: () => void; +}) => { const t = useI18nContext(); const fromToken = useSelector(getFromToken); @@ -43,9 +52,14 @@ export const BridgeCTAButton = () => { const fromAmount = useSelector(getFromAmount); - const { isLoading, activeQuote, isQuoteGoingToRefresh, quotesRefreshCount } = + const { isLoading, activeQuote, isQuoteGoingToRefresh, quotesLastFetchedMs } = useSelector(getBridgeQuotes); - const { maxRefreshCount, refreshRate } = useSelector(getBridgeQuotesConfig); + const { refreshRate } = useSelector(getBridgeQuotesConfig); + const isQuoteExpired = isQuoteExpiredUtil( + isQuoteGoingToRefresh, + refreshRate, + quotesLastFetchedMs, + ); const { submitBridgeTransaction } = useSubmitBridgeTransaction(); const [isSubmitting, setIsSubmitting] = useState(false); @@ -76,7 +90,6 @@ export const BridgeCTAButton = () => { const tradeProperties = useTradeProperties(); const ticker = useSelector(getNativeCurrency); - const [isQuoteExpired, setIsQuoteExpired] = useState(false); const isInsufficientBalance = isInsufficientBalance_(balanceAmount); @@ -85,28 +98,12 @@ export const BridgeCTAButton = () => { const isInsufficientGasForQuote = isInsufficientGasForQuote_(nativeAssetBalance); - useEffect(() => { - let timeout: NodeJS.Timeout; - // Reset the isQuoteExpired if quote fethching restarts - if (quotesRefreshCount === 0) { - setIsQuoteExpired(false); - return () => clearTimeout(timeout); - } - // After the last quote refresh, set a timeout to expire the quote and disable the CTA - if (quotesRefreshCount >= maxRefreshCount && !isQuoteGoingToRefresh) { - timeout = setTimeout(() => { - setIsQuoteExpired(true); - }, refreshRate); - } - return () => clearTimeout(timeout); - }, [isQuoteGoingToRefresh, quotesRefreshCount]); - const label = useMemo(() => { if (wasTxDeclined) { return t('youDeclinedTheTransaction'); } - if (isQuoteExpired && !isNoQuotesAvailable) { + if (isQuoteExpired) { return t('bridgeQuoteExpired'); } @@ -149,7 +146,15 @@ export const BridgeCTAButton = () => { isQuoteExpired, ]); - return activeQuote && !wasTxDeclined ? ( + // Label for the secondary button that re-starts quote fetching + const secondaryButtonLabel = useMemo(() => { + if (wasTxDeclined || isQuoteExpired) { + return t('bridgeFetchNewQuotes'); + } + return undefined; + }, [wasTxDeclined, isQuoteExpired]); + + return activeQuote && !secondaryButtonLabel ? ( { {label} ) : ( - - {label} - + + {label} + + {secondaryButtonLabel && ( + + {secondaryButtonLabel} + + )} + ); }; diff --git a/ui/pages/bridge/prepare/bridge-input-group.tsx b/ui/pages/bridge/prepare/bridge-input-group.tsx index 4365138d6e3a..f7ba1c19b0e4 100644 --- a/ui/pages/bridge/prepare/bridge-input-group.tsx +++ b/ui/pages/bridge/prepare/bridge-input-group.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef } from 'react'; import { useSelector } from 'react-redux'; import { BigNumber } from 'bignumber.js'; import { getAddress } from 'ethers/lib/utils'; @@ -7,15 +7,18 @@ import { TextField, TextFieldType, ButtonLink, - PopoverPosition, Button, ButtonSize, } from '../../../components/component-library'; import { AssetPicker } from '../../../components/multichain/asset-picker-amount/asset-picker'; import { TabName } from '../../../components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-tabs'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { formatCurrencyAmount, formatTokenAmount } from '../utils/quote'; -import { Column, Row, Tooltip } from '../layout'; +import { + formatCurrencyAmount, + formatTokenAmount, + isNativeAddress, +} from '../utils/quote'; +import { Column, Row } from '../layout'; import { Display, FontWeight, @@ -25,18 +28,17 @@ import { TextColor, } from '../../../helpers/constants/design-system'; import { AssetType } from '../../../../shared/constants/transaction'; -import { BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE } from '../../../../shared/constants/bridge'; import useLatestBalance from '../../../hooks/bridge/useLatestBalance'; import { getBridgeQuotes, getValidationErrors, } from '../../../ducks/bridge/selectors'; import { shortenString } from '../../../helpers/utils/util'; -import { BridgeToken } from '../types'; +import type { BridgeToken } from '../../../../shared/types/bridge'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { MINUTE } from '../../../../shared/constants/time'; import { getIntlLocale } from '../../../ducks/locale/locale'; -import { getCurrentCurrency } from '../../../selectors'; +import { getCurrentCurrency } from '../../../ducks/metamask/metamask'; import { BridgeAssetPickerButton } from './components/bridge-asset-picker-button'; export const BridgeInputGroup = ({ @@ -87,17 +89,15 @@ export const BridgeInputGroup = ({ const inputRef = useRef(null); - const [isLowReturnTooltipOpen, setIsLowReturnTooltipOpen] = useState(true); + const isAmountReadOnly = + amountFieldProps?.readOnly || amountFieldProps?.disabled; useEffect(() => { - if (inputRef.current) { + if (!isAmountReadOnly && inputRef.current) { inputRef.current.value = amountFieldProps?.value?.toString() ?? ''; inputRef.current.focus(); } - }, [amountFieldProps]); - - const isAmountReadOnly = - amountFieldProps?.readOnly || amountFieldProps?.disabled; + }, [amountFieldProps?.value, isAmountReadOnly, token]); return ( @@ -161,7 +161,6 @@ export const BridgeInputGroup = ({ customTokenListGenerator={customTokenListGenerator} isTokenListLoading={isTokenListLoading} isMultiselectEnabled={isMultiselectEnabled} - autoFocus={false} > {(onClickHandler, networkImageSrc) => isAmountReadOnly && !token ? ( @@ -189,23 +188,6 @@ export const BridgeInputGroup = ({ - {isAmountReadOnly && - isEstimatedReturnLow && - isLowReturnTooltipOpen && ( - setIsLowReturnTooltipOpen(false)} - triggerElement={} - flip={false} - offset={[0, 80]} - > - {t('lowEstimatedReturnTooltipMessage', [ - BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE * 100, - ])} - - )} ( slippage, ); - const [customSlippage, setCustomSlippage] = useState( - slippage && HARDCODED_SLIPPAGE_OPTIONS.includes(slippage) - ? undefined - : slippage, + const [customSlippage, setCustomSlippage] = useState( + slippage && !HARDCODED_SLIPPAGE_OPTIONS.includes(slippage) + ? slippage.toString() + : undefined, ); const [showCustomButton, setShowCustomButton] = useState(true); + const getNotificationConfig = () => { + if (!customSlippage) { + return null; + } + + const slippageValue = Number(customSlippage.replace(',', '.')); + if (slippageValue < 0.5) { + return { + severity: SEVERITIES.WARNING, + text: t('swapSlippageLowDescription', [slippageValue]), + title: t('swapSlippageLowTitle'), + }; + } + + return null; + }; + + const notificationConfig = getNotificationConfig(); + return ( @@ -156,47 +179,49 @@ export const BridgeTransactionSettingsModal = ({ type={TextFieldType.Text} value={customSlippage} onChange={(e) => { - // Remove characters that are not numbers or decimal points if rendering a controlled or pasted value - const cleanedValue = e.target.value.replace(/[^0-9.]+/gu, ''); - setLocalSlippage(undefined); - setCustomSlippage( - cleanedValue.length > 0 ? Number(cleanedValue) : undefined, - ); + const { value } = e.target; + if (value === '' || /^\d*[.,]?\d*$/u.test(value)) { + setLocalSlippage(undefined); + setCustomSlippage(value); + } }} autoFocus={true} onBlur={() => { - console.log('====blur'); setShowCustomButton(true); }} onFocus={() => { - console.log('====focus'); setShowCustomButton(false); }} - onKeyPress={(e?: React.KeyboardEvent) => { - // Only allow numbers and at most one decimal point - if ( - e && - !/^[0-9]*\.{0,1}[0-9]*$/u.test( - `${customSlippage ?? ''}${e.key}`, - ) - ) { - e.preventDefault(); - } - }} endAccessory={%} /> )} + {notificationConfig && ( + + + {notificationConfig.text} + + + )} { - const newSlippage = localSlippage || customSlippage; - newSlippage && + const newSlippage = + localSlippage ?? Number(customSlippage?.replace(',', '.')); + if (newSlippage) { trackCrossChainSwapsEvent({ event: MetaMetricsEventName.InputChanged, properties: { @@ -204,8 +229,9 @@ export const BridgeTransactionSettingsModal = ({ value: newSlippage.toString(), }, }); - dispatch(setSlippage(newSlippage)); - onClose(); + dispatch(setSlippage(newSlippage)); + onClose(); + } }} > {t('submit')} diff --git a/ui/pages/bridge/prepare/index.scss b/ui/pages/bridge/prepare/index.scss index cfefc86e52e0..8c501fad332f 100644 --- a/ui/pages/bridge/prepare/index.scss +++ b/ui/pages/bridge/prepare/index.scss @@ -70,6 +70,14 @@ border: none; border-radius: 8px; + .row-with-warning { + padding-left: 16px; + padding-right: 12px; + margin-left: -16px; + max-width: calc(100% + 32px); + width: calc(100% + 32px); + } + [data-theme='light'], .light { box-shadow: 0 0 2px 0 #e2e4e9, 0 0 16px 0 rgba(226, 228, 233, 0.16); diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx index 3e955d3e34ef..4d0de6feb9b9 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx @@ -3,7 +3,6 @@ import { Provider } from 'react-redux'; import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/jest/mock-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; -import { RequestStatus } from '../../../../app/scripts/controllers/bridge/constants'; import CrossChainSwap from '../index'; import { MemoryRouter } from 'react-router-dom'; import { @@ -11,6 +10,7 @@ import { PREPARE_SWAP_ROUTE, } from '../../../helpers/constants/routes'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; +import { RequestStatus } from '../../../../shared/types/bridge'; const storybook = { title: 'Pages/Bridge/CrossChainSwapPage', @@ -28,12 +28,15 @@ const Wrapper = ({ children }) => ( ); const mockFeatureFlags = { - srcNetworkAllowlist: [CHAIN_IDS.MAINNET, CHAIN_IDS.LINEA_MAINNET], - destNetworkAllowlist: [CHAIN_IDS.MAINNET, CHAIN_IDS.LINEA_MAINNET], extensionSupport: true, extensionConfig: { refreshRate: 30000, maxRefreshCount: 5, + support: true, + chains: { + '0x1': { isActiveSrc: true, isActiveDest: true }, + '0xa': { isActiveSrc: true, isActiveDest: true }, + }, }, }; const mockBridgeSlice = { diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx index de8fdfc25b36..0238ebbbf4b6 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx @@ -16,8 +16,7 @@ describe('PrepareBridgePage', () => { chainId: CHAIN_IDS.MAINNET, }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - global.ethereumProvider = provider as any; + global.ethereumProvider = provider; }); beforeEach(() => { diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.tsx index 030e0167caeb..a13e888df95b 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.tsx @@ -63,11 +63,18 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { SWAPS_CHAINID_DEFAULT_TOKEN_MAP } from '../../../../shared/constants/swaps'; import { useTokensWithFiltering } from '../../../hooks/bridge/useTokensWithFiltering'; import { setActiveNetwork } from '../../../store/actions'; -import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; -import { QuoteRequest } from '../types'; +import { + hexToDecimal, + decimalToPrefixedHex, +} from '../../../../shared/modules/conversion.utils'; +import type { QuoteRequest } from '../../../../shared/types/bridge'; import { calcTokenValue } from '../../../../shared/lib/swaps-utils'; import { BridgeQuoteCard } from '../quotes/bridge-quote-card'; -import { formatTokenAmount, isValidQuoteRequest } from '../utils/quote'; +import { + formatTokenAmount, + isQuoteExpired as isQuoteExpiredUtil, +} from '../utils/quote'; +import { isValidQuoteRequest } from '../../../../shared/modules/bridge-utils/quote'; import { getProviderConfig } from '../../../../shared/modules/selectors/networks'; import { CrossChainSwapsEventProperties, @@ -87,6 +94,7 @@ import { useBridgeTokens } from '../../../hooks/bridge/useBridgeTokens'; import { getCurrentKeyring } from '../../../selectors'; import { isHardwareKeyring } from '../../../helpers/utils/hardware'; import { SECOND } from '../../../../shared/constants/time'; +import { BRIDGE_QUOTE_MAX_RETURN_DIFFERENCE_PERCENTAGE } from '../../../../shared/constants/bridge'; import { getIntlLocale } from '../../../ducks/locale/locale'; import { BridgeInputGroup } from './bridge-input-group'; import { BridgeCTAButton } from './bridge-cta-button'; @@ -122,12 +130,24 @@ const PrepareBridgePage = () => { const slippage = useSelector(getSlippage); const quoteRequest = useSelector(getQuoteRequest); - const { isLoading, activeQuote, isQuoteGoingToRefresh } = - useSelector(getBridgeQuotes); - + const { + isLoading, + activeQuote: activeQuote_, + isQuoteGoingToRefresh, + quotesLastFetchedMs, + } = useSelector(getBridgeQuotes); const { refreshRate } = useSelector(getBridgeQuotesConfig); const wasTxDeclined = useSelector(getWasTxDeclined); + // If latest quote is expired and user has sufficient balance + // set activeQuote to undefined to hide stale quotes but keep inputs filled + const isQuoteExpired = isQuoteExpiredUtil( + isQuoteGoingToRefresh, + refreshRate, + quotesLastFetchedMs, + ); + const activeQuote = + isQuoteExpired && !quoteRequest.insufficientBal ? undefined : activeQuote_; const keyring = useSelector(getCurrentKeyring); // @ts-expect-error keyring type is wrong maybe? @@ -136,10 +156,12 @@ const PrepareBridgePage = () => { const ticker = useSelector(getNativeCurrency); const { + isEstimatedReturnLow, isNoQuotesAvailable, isInsufficientGasForQuote, isInsufficientBalance, } = useSelector(getValidationErrors); + const { quotesRefreshCount } = useSelector(getBridgeQuotes); const { openBuyCryptoInPdapp } = useRamps(); const { balanceAmount: nativeAssetBalance } = useLatestBalance( @@ -175,6 +197,10 @@ const PrepareBridgePage = () => { const [rotateSwitchTokens, setRotateSwitchTokens] = useState(false); + // Resets the banner visibility when the estimated return is low + const [isLowReturnBannerOpen, setIsLowReturnBannerOpen] = useState(true); + useEffect(() => setIsLowReturnBannerOpen(true), [quotesRefreshCount]); + // Background updates are debounced when the switch button is clicked // To prevent putting the frontend in an unexpected state, prevent the user // from switching tokens within the debounce period @@ -192,20 +218,51 @@ const PrepareBridgePage = () => { }, [rotateSwitchTokens]); useEffect(() => { - // Reset controller and inputs on load - dispatch(resetBridgeState()); + if (activeQuote) { + // Get input data from active quote + const { srcAsset, destAsset, destChainId } = activeQuote.quote; + const quoteSrcToken = fromTokens[srcAsset.address.toLowerCase()]; + const quoteDestChainId = decimalToPrefixedHex(destChainId); + const quoteDestToken = toTokens[destAsset.address.toLowerCase()]; + + if (quoteSrcToken && quoteDestToken && quoteDestChainId) { + // Set inputs to values from active quote + dispatch(setFromTokenInputValue(null)); + dispatch( + setFromToken({ ...quoteSrcToken, image: quoteSrcToken.iconUrl }), + ); + dispatch(setToChainId(quoteDestChainId)); + dispatch( + setToToken({ ...quoteDestToken, image: quoteDestToken.iconUrl }), + ); + } + } else { + // Reset controller and inputs on load + dispatch(resetBridgeState()); + } }, []); - const scrollRef = useRef(null); - + // Scroll to bottom of the page when banners are shown + const insufficientBalanceBannerRef = useRef(null); + const isEstimatedReturnLowRef = useRef(null); useEffect(() => { if (isInsufficientGasForQuote(nativeAssetBalance)) { - scrollRef.current?.scrollIntoView({ + insufficientBalanceBannerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start', }); } - }, [isInsufficientGasForQuote(nativeAssetBalance)]); + if (isEstimatedReturnLow) { + isEstimatedReturnLowRef.current?.scrollIntoView({ + behavior: 'smooth', + block: 'start', + }); + } + }, [ + isEstimatedReturnLow, + isInsufficientGasForQuote(nativeAssetBalance), + isLowReturnBannerOpen, + ]); const quoteParams = useMemo( () => ({ @@ -325,8 +382,6 @@ const PrepareBridgePage = () => { input: 'token_source', value: token.address, }); - dispatch(setFromToken(token)); - dispatch(setFromTokenInputValue(null)); }} networkProps={{ network: fromChain, @@ -534,9 +589,13 @@ const PrepareBridgePage = () => { backgroundColor={BackgroundColor.primaryMuted} /> )} - {!wasTxDeclined && } + {!wasTxDeclined && activeQuote && }