mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
Merge branch 'develop' of github.com:MetaMask/metamask-extension into minimal
This commit is contained in:
commit
4988e033ad
@ -30,11 +30,44 @@ rc_branch_only: &rc_branch_only
|
||||
only:
|
||||
- /^Version-v(\d+)[.](\d+)[.](\d+)/
|
||||
|
||||
rc_or_master_branch_only: &rc_or_master_branch_only
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^Version-v(\d+)[.](\d+)[.](\d+)|master/
|
||||
aliases:
|
||||
# Shallow Git Clone
|
||||
- &shallow-git-clone
|
||||
name: Shallow Git Clone
|
||||
command: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
# This Shallow Git Clone code is adapted from what the standard CircleCI `checkout` command does for the case of an external PR (link to example below):
|
||||
# https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/49817/workflows/dc195ea6-ac06-4de1-9edf-4c949427b5fb/jobs/1430976/parallel-runs/0/steps/0-101
|
||||
### git clone --no-checkout "$CIRCLE_REPOSITORY_URL" .
|
||||
### git fetch --force origin +refs/pull/18748/head:refs/remotes/origin/pull/18748
|
||||
### git checkout --force -B "$CIRCLE_BRANCH" "$CIRCLE_SHA1"
|
||||
### git --no-pager log --no-color -n 1 --format='HEAD is now at %h %s'
|
||||
|
||||
# Set up SSH access
|
||||
# This SSH key is the current github.com SSH key as of June 2023, but it will need to be changed whenever github changes their key (probably every few years)
|
||||
GITHUB_SSH_KEY="AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"
|
||||
mkdir -p ~/.ssh
|
||||
echo github.com ssh-ed25519 $GITHUB_SSH_KEY >> ~/.ssh/known_hosts
|
||||
|
||||
# Take a different clone path depending on if it's a tag, a PR from an external repo, or the normal case
|
||||
if [ -n "${CIRCLE_TAG-}" ]; then
|
||||
# tag
|
||||
git clone --depth 1 --no-checkout "$CIRCLE_REPOSITORY_URL" .
|
||||
git fetch --depth 1 --force origin "+refs/tags/${CIRCLE_TAG}:refs/tags/${CIRCLE_TAG}"
|
||||
git checkout --force -q "$CIRCLE_TAG" "$CIRCLE_SHA1"
|
||||
elif [[ "$CIRCLE_BRANCH" =~ ^pull\/* ]]; then
|
||||
# pull request
|
||||
git clone --depth 1 --no-checkout "$CIRCLE_REPOSITORY_URL" .
|
||||
git fetch --depth 1 --force origin "${CIRCLE_BRANCH}/head:remotes/origin/${CIRCLE_BRANCH}"
|
||||
git checkout --force -B "$CIRCLE_BRANCH" "$CIRCLE_SHA1"
|
||||
else
|
||||
# normal case
|
||||
git clone --depth 1 "$CIRCLE_REPOSITORY_URL" --branch "$CIRCLE_BRANCH" .
|
||||
fi
|
||||
|
||||
workflows:
|
||||
test_and_release:
|
||||
@ -57,15 +90,12 @@ workflows:
|
||||
requires:
|
||||
- prep-deps
|
||||
- validate-lavamoat-allow-scripts:
|
||||
<<: *rc_or_master_branch_only
|
||||
requires:
|
||||
- prep-deps
|
||||
- validate-lavamoat-policy-build:
|
||||
<<: *rc_or_master_branch_only
|
||||
requires:
|
||||
- prep-deps
|
||||
- validate-lavamoat-policy-webapp:
|
||||
<<: *rc_or_master_branch_only
|
||||
matrix:
|
||||
parameters:
|
||||
build-type: [main, beta, flask, mmi, desktop]
|
||||
@ -250,7 +280,7 @@ jobs:
|
||||
trigger-beta-build:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
@ -279,7 +309,7 @@ jobs:
|
||||
create_release_pull_request:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -298,7 +328,7 @@ jobs:
|
||||
prep-deps:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- restore_cache:
|
||||
keys:
|
||||
# First try to get the specific cache for the checksum of the yarn.lock file.
|
||||
@ -348,7 +378,7 @@ jobs:
|
||||
validate-lavamoat-allow-scripts:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -361,7 +391,7 @@ jobs:
|
||||
validate-lavamoat-policy-build:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -377,7 +407,7 @@ jobs:
|
||||
build-type:
|
||||
type: string
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -390,7 +420,7 @@ jobs:
|
||||
prep-build:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
@ -424,7 +454,7 @@ jobs:
|
||||
prep-build-desktop:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -448,7 +478,7 @@ jobs:
|
||||
prep-build-flask:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
@ -488,7 +518,7 @@ jobs:
|
||||
prep-build-test-flask:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -509,7 +539,7 @@ jobs:
|
||||
prep-build-test-mv3:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -530,7 +560,7 @@ jobs:
|
||||
prep-build-test:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -551,7 +581,7 @@ jobs:
|
||||
prep-build-storybook:
|
||||
executor: node-browsers-large
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -565,7 +595,7 @@ jobs:
|
||||
prep-build-ts-migration-dashboard:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -579,7 +609,7 @@ jobs:
|
||||
test-yarn-dedupe:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -589,7 +619,7 @@ jobs:
|
||||
test-lint:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -602,7 +632,7 @@ jobs:
|
||||
test-storybook:
|
||||
executor: node-browsers-large
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -624,7 +654,7 @@ jobs:
|
||||
test-lint-lockfile:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -634,7 +664,7 @@ jobs:
|
||||
test-lint-changelog:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- when:
|
||||
@ -660,7 +690,7 @@ jobs:
|
||||
test-deps-audit:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -670,7 +700,7 @@ jobs:
|
||||
test-deps-depcheck:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -681,7 +711,7 @@ jobs:
|
||||
executor: node-browsers
|
||||
parallelism: 8
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -718,7 +748,7 @@ jobs:
|
||||
executor: node-browsers
|
||||
parallelism: 8
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -746,7 +776,7 @@ jobs:
|
||||
executor: node-browsers
|
||||
parallelism: 4
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Install Firefox
|
||||
command: ./.circleci/scripts/firefox-install.sh
|
||||
@ -783,7 +813,7 @@ jobs:
|
||||
executor: node-browsers
|
||||
parallelism: 4
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -820,7 +850,7 @@ jobs:
|
||||
executor: node-browsers-medium-plus
|
||||
parallelism: 8
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Install Firefox
|
||||
command: ./.circleci/scripts/firefox-install.sh
|
||||
@ -856,7 +886,7 @@ jobs:
|
||||
benchmark:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -882,7 +912,7 @@ jobs:
|
||||
user-actions-benchmark:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -908,7 +938,7 @@ jobs:
|
||||
stats-module-load-init:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- run:
|
||||
name: Re-Install Chrome
|
||||
command: ./.circleci/scripts/chrome-install.sh
|
||||
@ -1005,7 +1035,7 @@ jobs:
|
||||
job-publish-release:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1025,7 +1055,7 @@ jobs:
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- '3d:49:29:f4:b2:e8:ea:af:d1:32:eb:2a:fc:15:85:d8'
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1040,7 +1070,7 @@ jobs:
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- '8b:21:e3:20:7c:c9:db:82:74:2d:86:d6:11:a7:2f:49'
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1054,7 +1084,7 @@ jobs:
|
||||
test-unit-mocha:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1069,7 +1099,7 @@ jobs:
|
||||
test-unit-jest-development:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1086,7 +1116,7 @@ jobs:
|
||||
executor: node-browsers-medium-plus
|
||||
parallelism: 12
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1102,7 +1132,7 @@ jobs:
|
||||
upload-and-validate-coverage:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- codecov/upload
|
||||
@ -1117,7 +1147,7 @@ jobs:
|
||||
test-unit-global:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1127,7 +1157,7 @@ jobs:
|
||||
validate-source-maps:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1137,7 +1167,7 @@ jobs:
|
||||
validate-source-maps-beta:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1148,7 +1178,7 @@ jobs:
|
||||
validate-source-maps-desktop:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1164,7 +1194,7 @@ jobs:
|
||||
validate-source-maps-flask:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1180,7 +1210,7 @@ jobs:
|
||||
test-mozilla-lint:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1190,7 +1220,7 @@ jobs:
|
||||
test-mozilla-lint-desktop:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
@ -1206,7 +1236,7 @@ jobs:
|
||||
test-mozilla-lint-flask:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run: *shallow-git-clone
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
|
177
.github/scripts/label-prs.ts
vendored
177
.github/scripts/label-prs.ts
vendored
@ -1,177 +0,0 @@
|
||||
import * as core from '@actions/core';
|
||||
import { context, getOctokit } from '@actions/github';
|
||||
import { GitHub } from '@actions/github/lib/utils';
|
||||
|
||||
main().catch((error: Error): void => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const token = process.env.GITHUB_TOKEN;
|
||||
|
||||
if (!token) {
|
||||
core.setFailed('GITHUB_TOKEN not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const octokit = getOctokit(token);
|
||||
|
||||
const headRef = context.payload.pull_request?.head.ref || '';
|
||||
|
||||
let issueNumber = await getIssueNumberFromPullRequestBody();
|
||||
if (issueNumber === "") {
|
||||
bailIfIsBranchNameInvalid(headRef);
|
||||
bailIfIsNotFeatureBranch(headRef);
|
||||
issueNumber = getIssueNumberFromBranchName(headRef);
|
||||
}
|
||||
|
||||
if (Number(issueNumber) === 0) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
await updateLabels(octokit, issueNumber);
|
||||
}
|
||||
|
||||
async function getIssueNumberFromPullRequestBody(): Promise<string> {
|
||||
console.log("Checking if the PR's body references an issue...");
|
||||
|
||||
let ISSUE_LINK_IN_PR_DESCRIPTION_REGEX =
|
||||
/(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\s#\d+/gi;
|
||||
|
||||
const prBody = await getPullRequestBody();
|
||||
|
||||
let matches = prBody.match(ISSUE_LINK_IN_PR_DESCRIPTION_REGEX);
|
||||
if (!matches || matches?.length === 0) {
|
||||
console.log(
|
||||
'No direct link can be drawn between the PR and an issue from the PR body because no issue number was referenced.',
|
||||
);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (matches?.length > 1) {
|
||||
console.log(
|
||||
'No direct link can be drawn between the PR and an issue from the PR body because more than one issue number was referenced.',
|
||||
);
|
||||
return "";
|
||||
}
|
||||
|
||||
const ISSUE_NUMBER_REGEX = /\d+/;
|
||||
const issueNumber = matches[0].match(ISSUE_NUMBER_REGEX)?.[0] || '';
|
||||
|
||||
console.log(`Found issue number ${issueNumber} in PR body.`);
|
||||
|
||||
return issueNumber;
|
||||
}
|
||||
|
||||
async function getPullRequestBody(): Promise<string> {
|
||||
if (context.eventName !== 'pull_request') {
|
||||
console.log('This action should only run on pull_request events.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const prBody = context.payload.pull_request?.body || '';
|
||||
return prBody;
|
||||
}
|
||||
|
||||
function bailIfIsBranchNameInvalid(branchName: string): void {
|
||||
const BRANCH_REGEX =
|
||||
/^(main|develop|(ci|chore|docs|feat|feature|fix|perf|refactor|revert|style)\/\d*(?:[-](?![-])\w*)*|Version-v\d+\.\d+\.\d+)$/;
|
||||
const isValidBranchName = new RegExp(BRANCH_REGEX).test(branchName);
|
||||
|
||||
if (!isValidBranchName) {
|
||||
console.log('This branch name does not follow the convention.');
|
||||
console.log(
|
||||
'Here are some example branch names that are accepted: "fix/123-description", "feat/123-longer-description", "feature/123", "main", "develop", "Version-v10.24.2".',
|
||||
);
|
||||
console.log(
|
||||
'No issue could be linked to this PR, so no labels were copied',
|
||||
);
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
function bailIfIsNotFeatureBranch(branchName: string): void {
|
||||
if (
|
||||
branchName === 'main' ||
|
||||
branchName === 'develop' ||
|
||||
branchName.startsWith('Version-v')
|
||||
) {
|
||||
console.log(`${branchName} is not a feature branch.`);
|
||||
console.log(
|
||||
'No issue could be linked to this PR, so no labels were copied',
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateLabels(octokit: InstanceType<typeof GitHub>, issueNumber: string): Promise<void> {
|
||||
interface ILabel {
|
||||
name: string;
|
||||
};
|
||||
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
|
||||
const issue = await octokit.rest.issues.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
issue_number: Number(issueNumber),
|
||||
});
|
||||
|
||||
const getNameFromLabel = (label: ILabel): string => label.name
|
||||
|
||||
const issueLabels = issue.data.labels.map(label => getNameFromLabel(label as ILabel));
|
||||
|
||||
const prNumber = context.payload.number;
|
||||
|
||||
const pr = await octokit.rest.issues.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
issue_number: prNumber,
|
||||
});
|
||||
|
||||
const startingPRLabels = pr.data.labels.map(label => getNameFromLabel(label as ILabel));
|
||||
|
||||
const dedupedFinalPRLabels = [
|
||||
...new Set([...startingPRLabels, ...issueLabels]),
|
||||
];
|
||||
|
||||
const hasIssueAdditionalLabels = !sortedArrayEqual(
|
||||
startingPRLabels,
|
||||
dedupedFinalPRLabels,
|
||||
);
|
||||
if (hasIssueAdditionalLabels) {
|
||||
await octokit.rest.issues.update({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: prNumber,
|
||||
labels: dedupedFinalPRLabels,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getIssueNumberFromBranchName(branchName: string): string {
|
||||
console.log('Checking if the branch name references an issue...');
|
||||
|
||||
let issueNumber: string;
|
||||
if (branchName.split('/').length > 1) {
|
||||
issueNumber = branchName.split('/')[1].split('-')[0];
|
||||
} else {
|
||||
issueNumber = branchName.split('-')[0];
|
||||
}
|
||||
|
||||
console.log(`Found issue number ${issueNumber} in branch name.`);
|
||||
|
||||
return issueNumber;
|
||||
}
|
||||
|
||||
function sortedArrayEqual(array1: string[], array2: string[]): boolean {
|
||||
const lengthsAreEqual = array1.length === array2.length;
|
||||
const everyElementMatchesByIndex = array1.every(
|
||||
(value: string, index: number): boolean => value === array2[index],
|
||||
);
|
||||
|
||||
return lengthsAreEqual && everyElementMatchesByIndex;
|
||||
}
|
1
.github/workflows/add-release-label.yml
vendored
1
.github/workflows/add-release-label.yml
vendored
@ -21,6 +21,7 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
1
.github/workflows/fitness-functions.yml
vendored
1
.github/workflows/fitness-functions.yml
vendored
@ -18,6 +18,7 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
27
.github/workflows/label-prs.yml
vendored
27
.github/workflows/label-prs.yml
vendored
@ -1,27 +0,0 @@
|
||||
name: Label PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [assigned, opened, edited, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
label-pr:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
@ -9,6 +9,9 @@ on:
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Remove labels
|
||||
|
50
.github/workflows/update-lavamoat-policies.yml
vendored
50
.github/workflows/update-lavamoat-policies.yml
vendored
@ -20,6 +20,28 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.issue.number }}
|
||||
|
||||
react-to-comment:
|
||||
name: React to the comment
|
||||
runs-on: ubuntu-latest
|
||||
needs: is-fork-pull-request
|
||||
# Early exit if this is a fork, since later steps are skipped for forks
|
||||
if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: React to the comment
|
||||
run: |
|
||||
gh api \
|
||||
--method POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"/repos/${REPO}/issues/comments/${COMMENT_ID}/reactions" \
|
||||
-f content='+1'
|
||||
env:
|
||||
COMMENT_ID: ${{ github.event.comment.id }}
|
||||
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
|
||||
prepare:
|
||||
name: Prepare dependencies
|
||||
runs-on: ubuntu-latest
|
||||
@ -27,7 +49,13 @@ jobs:
|
||||
# Early exit if this is a fork, since later steps are skipped for forks
|
||||
if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout pull request
|
||||
run: gh pr checkout "${PR_NUMBER}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.issue.number }}
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@ -44,6 +72,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout pull request
|
||||
run: gh pr checkout "${PR_NUMBER}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.issue.number }}
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@ -72,6 +105,11 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout pull request
|
||||
run: gh pr checkout "${PR_NUMBER}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.issue.number }}
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
@ -99,7 +137,8 @@ jobs:
|
||||
# Ensure forks don't get access to the LavaMoat update token
|
||||
if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Use PAT to ensure that the commit later can trigger status check workflows
|
||||
token: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
|
||||
@ -113,6 +152,7 @@ jobs:
|
||||
with:
|
||||
path: lavamoat/build-system
|
||||
key: cache-build-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
fail-on-cache-miss: true
|
||||
# One restore step per build type: [main, beta, flask, mmi, desktop]
|
||||
# Ensure this is synchronized with the list above in the "update-lavamoat-webapp-policy" job
|
||||
# and with the build type list in `builds.yml`
|
||||
@ -121,27 +161,31 @@ jobs:
|
||||
with:
|
||||
path: lavamoat/browserify/main
|
||||
key: cache-main-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
fail-on-cache-miss: true
|
||||
- name: Restore beta application policy
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: lavamoat/browserify/beta
|
||||
key: cache-beta-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
fail-on-cache-miss: true
|
||||
- name: Restore flask application policy
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: lavamoat/browserify/flask
|
||||
key: cache-flask-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
fail-on-cache-miss: true
|
||||
- name: Restore mmi application policy
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: lavamoat/browserify/mmi
|
||||
key: cache-mmi-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
fail-on-cache-miss: true
|
||||
- name: Restore desktop application policy
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: lavamoat/browserify/desktop
|
||||
key: cache-desktop-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
|
||||
fail-on-cache-miss: true
|
||||
- name: Check whether there are policy changes
|
||||
id: policy-changes
|
||||
run: |
|
||||
|
@ -158,7 +158,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Additional incoming transactions support ([#14219](https://github.com/MetaMask/metamask-extension/pull/14219))
|
||||
|
||||
### Changed
|
||||
- UX: Loaclize the avatar-favicon description text ([#18132](https://github.com/MetaMask/metamask-extension/pull/18132))
|
||||
- UX: Localize the avatar-favicon description text ([#18132](https://github.com/MetaMask/metamask-extension/pull/18132))
|
||||
- 17921 Update TransactionAlerts with BannerAlert ([#17940](https://github.com/MetaMask/metamask-extension/pull/17940))
|
||||
- Part of 17670: Replace Typography with Text confirm-approve-content.component.js and home.component.js ([#18049](https://github.com/MetaMask/metamask-extension/pull/18049))
|
||||
- UX: Icon: Update buy icon ([#18123](https://github.com/MetaMask/metamask-extension/pull/18123))
|
||||
|
3
app/_locales/am/messages.json
generated
3
app/_locales/am/messages.json
generated
@ -202,9 +202,6 @@
|
||||
"delete": {
|
||||
"message": "ሰርዝ"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "መለያን ሰርዝ"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "አውታረ መረብ ይሰረዝ?"
|
||||
},
|
||||
|
3
app/_locales/ar/messages.json
generated
3
app/_locales/ar/messages.json
generated
@ -215,9 +215,6 @@
|
||||
"delete": {
|
||||
"message": "حذف"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "حذف الحساب"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "هل تريد حذف الشبكة؟"
|
||||
},
|
||||
|
3
app/_locales/bg/messages.json
generated
3
app/_locales/bg/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Изтриване"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Изтриване на акаунт"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Да се изтрие ли мрежата?"
|
||||
},
|
||||
|
3
app/_locales/bn/messages.json
generated
3
app/_locales/bn/messages.json
generated
@ -208,9 +208,6 @@
|
||||
"delete": {
|
||||
"message": "মুছুন"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "অ্যাকাউন্ট মুছুন"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "নেটওয়ার্ক মুছবেন?"
|
||||
},
|
||||
|
3
app/_locales/ca/messages.json
generated
3
app/_locales/ca/messages.json
generated
@ -208,9 +208,6 @@
|
||||
"delete": {
|
||||
"message": "Suprimeix"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Elimina el compte"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Esborrar Xarxa?"
|
||||
},
|
||||
|
3
app/_locales/da/messages.json
generated
3
app/_locales/da/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Slet"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Slet konto"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Slet Netværk?"
|
||||
},
|
||||
|
12
app/_locales/de/messages.json
generated
12
app/_locales/de/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Löschen"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Konto löschen"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Netzwerk löschen?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "Die ID eines NFTs ist eine eindeutige Kennung, da keine zwei NFTs gleich sind. Auch diese Nummer finden Sie in OpenSea unter „Details“. Notieren Sie diese oder kopieren Sie sie in Ihre Zwischenablage."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "NFTs importieren"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Ausgewählte Token importieren?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Laut unseren Aufzeichnungen stimmt der angegebene RPC-URL-Wert nicht mit einem bekannten Provider für diese Chain-ID überein."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Sie sehen Ihr NFT nicht?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Sie können eine Einstellung nicht finden?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Kein Umrechnungskurs verfügbar"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Noch keine NFTs"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Keine Snaps installiert"
|
||||
},
|
||||
|
12
app/_locales/el/messages.json
generated
12
app/_locales/el/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Διαγραφή"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Διαγραφή Λογαριασμού"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Διαγραφή Δικτύου;"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "Ένα αναγνωριστικό του συλλεκτικού είναι ένα μοναδικό αναγνωριστικό δεδομένου ότι δεν υπάρχουν δύο ίδια NFT. Και πάλι, στο OpenSea αυτός ο αριθμός βρίσκεται στην ενότητα \"Λεπτομέρειες\". Σημειώστε τον ή αντιγράψτε τον στο πρόχειρο σας."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Εισαγωγή NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Εισαγωγή επιλεγμένων token;"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Σύμφωνα με τις καταχωρήσεις μας, η τιμή RPC URL που υποβλήθηκε δεν ταιριάζει με κάποιον γνωστό πάροχο για αυτό το αναγνωριστικό αλυσίδας."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Δεν βλέπετε το NFT σας;"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Δεν μπορείτε να βρείτε μια ρύθμιση;"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Δεν Υπάρχει Διαθέσιμη Ισοτιμία Μετατροπής"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Δεν υπάρχουν NFT ακόμα"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Δεν εγκαταστάθηκαν Snaps"
|
||||
},
|
||||
|
13
app/_locales/en/messages.json
generated
13
app/_locales/en/messages.json
generated
@ -1101,8 +1101,8 @@
|
||||
"delete": {
|
||||
"message": "Delete"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Delete account"
|
||||
"deleteContact": {
|
||||
"message": "Delete contact"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Delete network?"
|
||||
@ -1884,9 +1884,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "An NFT's ID is a unique identifier since no two NFTs are alike. Again, on OpenSea this number is under 'Details'. Make a note of it, or copy it onto your clipboard."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Import NFTs"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Import selected tokens?"
|
||||
},
|
||||
@ -2273,9 +2270,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "According to our records the submitted RPC URL value does not match a known provider for this chain ID."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Don't see your NFT?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Can't find a setting?"
|
||||
},
|
||||
@ -5162,6 +5156,9 @@
|
||||
"viewOnOpensea": {
|
||||
"message": "View on Opensea"
|
||||
},
|
||||
"viewPortfolioDashboard": {
|
||||
"message": "View Portfolio Dashboard"
|
||||
},
|
||||
"viewinCustodianApp": {
|
||||
"message": "View in custodian app"
|
||||
},
|
||||
|
12
app/_locales/es/messages.json
generated
12
app/_locales/es/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Eliminar"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Eliminar cuenta"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "¿Eliminar red?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "La ID de un NFT es un identificador único, ya que no hay dos NFT iguales. Nuevamente, en OpenSea, este número se encuentra en 'Detalles'. Tome nota de ello o cópielo en su portapapeles."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "AGREGAR NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "¿Agregar los tokens seleccionados?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Según nuestros registros, el valor de la URL de RPC enviado no coincide con un proveedor conocido para este ID de cadena."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "¿No ve su NFT?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "¿No puede encontrar un ajuste?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "No hay tasa de conversión disponible"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "No hay ningún NFT aún"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "No hay complementos instalados"
|
||||
},
|
||||
|
12
app/_locales/es_419/messages.json
generated
12
app/_locales/es_419/messages.json
generated
@ -581,9 +581,6 @@
|
||||
"delete": {
|
||||
"message": "Eliminar"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Eliminar cuenta"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "¿Eliminar red?"
|
||||
},
|
||||
@ -1073,9 +1070,6 @@
|
||||
"importMyWallet": {
|
||||
"message": "Importar Mi cartera"
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Importar NFT"
|
||||
},
|
||||
"importTokenQuestion": {
|
||||
"message": "¿Desea importar el token?"
|
||||
},
|
||||
@ -1333,9 +1327,6 @@
|
||||
"message": "verifique los detalles de la red",
|
||||
"description": "Serves as link text for the 'mismatchedChain' key. This text will be embedded inside the translation for that key."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "¿No ve su NFT?"
|
||||
},
|
||||
"mustSelectOne": {
|
||||
"message": "Debe seleccionar al menos 1 token."
|
||||
},
|
||||
@ -1468,9 +1459,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "No hay tasa de conversión disponible"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Aún no hay NFT"
|
||||
},
|
||||
"noTransactions": {
|
||||
"message": "No tiene transacciones"
|
||||
},
|
||||
|
3
app/_locales/et/messages.json
generated
3
app/_locales/et/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Kustuta"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Kustuta konto"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Võrk kustutada?"
|
||||
},
|
||||
|
3
app/_locales/fa/messages.json
generated
3
app/_locales/fa/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "حذف"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "حذف حساب"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "شبکه حذف شود؟"
|
||||
},
|
||||
|
3
app/_locales/fi/messages.json
generated
3
app/_locales/fi/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Poista"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Poista tili"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Poistetaanko verkko?"
|
||||
},
|
||||
|
3
app/_locales/fil/messages.json
generated
3
app/_locales/fil/messages.json
generated
@ -187,9 +187,6 @@
|
||||
"delete": {
|
||||
"message": "I-delete"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "I-delete ang Account"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "I-delete ang Network?"
|
||||
},
|
||||
|
12
app/_locales/fr/messages.json
generated
12
app/_locales/fr/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Supprimer"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Supprimer le compte"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Supprimer le réseau ?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "L’ID d’un NFT est un identifiant unique puisqu’il n’y a pas deux NFT identiques. Encore une fois, sur OpenSea, ce numéro se trouve dans la section « Détails ». Prenez-en note ou copiez-le dans votre presse-papiers."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Importer des NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Voulez-vous importer les jetons sélectionnés ?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Selon nos informations, la valeur de l’URL RPC soumise ne correspond pas à un fournisseur connu pour cet ID de chaîne."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Vous ne voyez pas votre NFT ?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Vous ne trouvez pas un paramètre ?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Aucun taux de conversion disponible"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Aucun NFT pour le moment"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Aucun Snap installé"
|
||||
},
|
||||
|
3
app/_locales/he/messages.json
generated
3
app/_locales/he/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "מחיקה"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "מחק חשבון"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "למחוק את הרשת?"
|
||||
},
|
||||
|
12
app/_locales/hi/messages.json
generated
12
app/_locales/hi/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "हटाएँ"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "अकाउंट हटाएं"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "नेटवर्क हटाएं?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "किसी एनएफटी की आईडी एक विशिष्ट पहचानकर्ता है क्योंकि कोई भी दो एनएफटी एक जैसे नहीं होते हैं। फिर से, OpenSea पर यह संख्या 'डिटेल्स' के नीचे होगी। इसे नोट कर लें या अपने क्लिपबोर्ड पर कॉपी कर लें।"
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "NFT आयात करें"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "चयनित टोकन आयात करें?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "हमारे रिकॉर्ड के अनुसार, सबमिट किया गया RPC-URL मान इस चेन आईडी के लिए किसी ज्ञात प्रदाता से मेल नहीं खाता।"
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "अपना NFT नहीं देख रहे हैं?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "सेटिंग नहीं मिल पाया?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "कोई भी रूपांतरण दर उपलब्ध नहीं है"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "अभी तक कोई NFT नहीं"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "कोई स्नैप इंस्टाल नहीं किया गया"
|
||||
},
|
||||
|
3
app/_locales/hr/messages.json
generated
3
app/_locales/hr/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Izbriši"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Izbriši račun"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Izbrisati mrežu?"
|
||||
},
|
||||
|
3
app/_locales/hu/messages.json
generated
3
app/_locales/hu/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Törlés"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Fiók törlése"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Törli a hálózatot?"
|
||||
},
|
||||
|
12
app/_locales/id/messages.json
generated
12
app/_locales/id/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Hapus"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Hapus akun"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Hapus jaringan?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "ID NFT merupakan pengenal unik karena tidak ada dua NFT yang sama. Sekali lagi, angka ini berada di bawah 'Detail' pada OpenSea. Catat atau salin ke papan klip."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Impor NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Impor token yang dipilih?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Menurut catatan kami, nilai URL RPC yang dikirimkan tidak sesuai dengan penyedia yang dikenal untuk ID rantai ini."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Tidak melihat NFT Anda?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Tidak dapat menemukan pengaturan?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Nilai konversi tidak tersedia"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Belum ada NFT"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Belum ada Snap yang diinstal"
|
||||
},
|
||||
|
3
app/_locales/it/messages.json
generated
3
app/_locales/it/messages.json
generated
@ -716,9 +716,6 @@
|
||||
"delete": {
|
||||
"message": "Elimina"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Cancella account"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Cancella la rete?"
|
||||
},
|
||||
|
12
app/_locales/ja/messages.json
generated
12
app/_locales/ja/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "削除"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "アカウントを削除"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "ネットワークを削除しますか?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "NFT の ID は一意の識別子で、同じ NFT は 2 つとして存在しません。前述の通り、OpenSea ではこの番号は「詳細」に表示されます。この ID を書き留めるか、クリップボードにコピーしてください。"
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "NFTをインポート"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "選択したトークンをインポートしますか?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "弊社の記録によると、送信された RPC URL の値がこのチェーン ID の既知のプロバイダーと一致しません。"
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "NFTが見当たりませんか?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "設定が見つかりませんか?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "利用可能な換算レートがありません"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "NFTはまだありません"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "スナップがインストールされていません"
|
||||
},
|
||||
|
3
app/_locales/kn/messages.json
generated
3
app/_locales/kn/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "ಅಳಿಸಿ"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "ಖಾತೆಯನ್ನು ಅಳಿಸಿ"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "ನೆಟ್ವರ್ಕ್ ಅಳಿಸುವುದೇ?"
|
||||
},
|
||||
|
12
app/_locales/ko/messages.json
generated
12
app/_locales/ko/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "삭제"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "계정 삭제"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "네트워크를 삭제할까요?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "NFT의 ID는 고유한 식별자이므로 동일한 NFT는 존재하지 않습니다. 다시 말하지만, OpenSea에서 이 번호는 '세부 정보(Details)'에서 찾아볼 수 있습니다. 이를 기록하거나 클립보드에 복사해 두세요."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "NFT 가져오기"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "선택한 토큰을 불러올까요?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "기록에 따르면 제출한 RPC URL 값이 이 체인 ID의 알려진 공급업체와 일치하지 않습니다."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "NFT가 보이지 않나요?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "설정을 찾으세요?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "사용 가능한 환율 없음"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "아직 NFT가 없음"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "설치된 스냅이 없습니다"
|
||||
},
|
||||
|
3
app/_locales/lt/messages.json
generated
3
app/_locales/lt/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Ištrinti"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Šalinti paskyrą"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Panaikinti tinklą?"
|
||||
},
|
||||
|
3
app/_locales/lv/messages.json
generated
3
app/_locales/lv/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Dzēst"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Dzēst kontu"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Dzēst tīklu?"
|
||||
},
|
||||
|
3
app/_locales/ms/messages.json
generated
3
app/_locales/ms/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Padam"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Hapus Akaun"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Padamkan Rangkaian?"
|
||||
},
|
||||
|
3
app/_locales/no/messages.json
generated
3
app/_locales/no/messages.json
generated
@ -208,9 +208,6 @@
|
||||
"delete": {
|
||||
"message": "Slett"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Slett konto "
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Slette nettverk? "
|
||||
},
|
||||
|
3
app/_locales/ph/messages.json
generated
3
app/_locales/ph/messages.json
generated
@ -406,9 +406,6 @@
|
||||
"delete": {
|
||||
"message": "I-delete"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "I-delete ang Account"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "I-delete ang Network?"
|
||||
},
|
||||
|
3
app/_locales/pl/messages.json
generated
3
app/_locales/pl/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Usuń"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Usuń konto"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Usunąć sieć?"
|
||||
},
|
||||
|
12
app/_locales/pt/messages.json
generated
12
app/_locales/pt/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Excluir"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Excluir conta"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Excluir rede?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "O ID de um NFT é um identificador único, pois não há dois NFTs iguais. Novamente, na OpenSea, esse número se encontra em \"Detalhes\". Anote-o ou copie-o para sua área de transferência."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Importar NFTs"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Importar tokens selecionados?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "De acordo com os nossos registros, o valor da URL da RPC enviado não corresponde a um provedor conhecido da ID desta cadeia."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Não está vendo o seu NFT?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Não consegue encontrar uma configuração?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Não há uma taxa de conversão disponível"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Nenhum NFT até agora"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Nenhum snap instalado"
|
||||
},
|
||||
|
12
app/_locales/pt_BR/messages.json
generated
12
app/_locales/pt_BR/messages.json
generated
@ -581,9 +581,6 @@
|
||||
"delete": {
|
||||
"message": "Excluir"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Excluir conta"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Excluir rede?"
|
||||
},
|
||||
@ -1073,9 +1070,6 @@
|
||||
"importMyWallet": {
|
||||
"message": "Importar minha carteira"
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Importar NFTs"
|
||||
},
|
||||
"importTokenQuestion": {
|
||||
"message": "Importar token?"
|
||||
},
|
||||
@ -1333,9 +1327,6 @@
|
||||
"message": "verifique os detalhes da rede",
|
||||
"description": "Serves as link text for the 'mismatchedChain' key. This text will be embedded inside the translation for that key."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Não está vendo o seu NFT?"
|
||||
},
|
||||
"mustSelectOne": {
|
||||
"message": "Selecione pelo menos 1 token."
|
||||
},
|
||||
@ -1468,9 +1459,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Não há uma taxa de conversão disponível"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Ainda não há nenhum NFT"
|
||||
},
|
||||
"noTransactions": {
|
||||
"message": "Você não tem transações"
|
||||
},
|
||||
|
3
app/_locales/ro/messages.json
generated
3
app/_locales/ro/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Șterge"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Ștergeți cont"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Ștergeți rețeaua?"
|
||||
},
|
||||
|
12
app/_locales/ru/messages.json
generated
12
app/_locales/ru/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Удалить"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Удалить счет"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Удалить сеть?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "Идентификатор коллекционного актива является уникальным идентификатором, поскольку нет двух одинаковых NFT. Опять же, в OpenSea этот номер находится в разделе «Подробности». Запишите его или скопируйте в буфер обмена."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Импорт NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Импортировать выбранные токены?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Согласно нашим записям, отправленное значение URL-адреса RPC не соответствует известному поставщику для этого идентификатора блокчейна."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Не видите свои NFT?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Не удается найти настройку?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Нет доступного обменного курса"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Пока нет NFT-токенов"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Снапы не установлены"
|
||||
},
|
||||
|
3
app/_locales/sk/messages.json
generated
3
app/_locales/sk/messages.json
generated
@ -205,9 +205,6 @@
|
||||
"delete": {
|
||||
"message": "Odstrániť"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Zmazať účet"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Odstrániť sieť?"
|
||||
},
|
||||
|
3
app/_locales/sl/messages.json
generated
3
app/_locales/sl/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Izbriši"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Izbriši račun"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Izbrišem to omrežje?"
|
||||
},
|
||||
|
3
app/_locales/sr/messages.json
generated
3
app/_locales/sr/messages.json
generated
@ -208,9 +208,6 @@
|
||||
"delete": {
|
||||
"message": "Избриши"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Obriši nalog"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Da li želite da obrišete mrežu?"
|
||||
},
|
||||
|
3
app/_locales/sv/messages.json
generated
3
app/_locales/sv/messages.json
generated
@ -205,9 +205,6 @@
|
||||
"delete": {
|
||||
"message": "Radera"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Radera konto"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Radera nätverk?"
|
||||
},
|
||||
|
3
app/_locales/sw/messages.json
generated
3
app/_locales/sw/messages.json
generated
@ -205,9 +205,6 @@
|
||||
"delete": {
|
||||
"message": "Futa"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Futa Akaunti"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Futa Mtandao?"
|
||||
},
|
||||
|
12
app/_locales/tl/messages.json
generated
12
app/_locales/tl/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "I-delete"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "I-delete ang Account"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "I-delete ang network?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "Ang ID ng NFT ay isang natatanging pagkakakilanlan dahil walang dalawang NFT ang magkatulad. Muli, sa OpenSea ang numerong ito ay nasa ilalim ng 'Mga Detalye'. Itala ito, o kopyahin ito sa iyong clipboard."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "I-import ang mga NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "I-import ang mga napiling token?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Ayon sa aming mga talaan, ang isinumiteng RPC URL value ay hindi tumutugma sa isang kilalang provider para sa chain ID na ito."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Hindi makita ang NFT mo?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Hindi makahanap ng setting?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Hindi available ang rate ng conversion"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Wala pang mga NFT"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Walang mga Snap na naka-install"
|
||||
},
|
||||
|
12
app/_locales/tr/messages.json
generated
12
app/_locales/tr/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Sil"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Hesabı Sil"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Ağı Sil?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "Hiçbir iki NFT kimliği birbiriyle aynı olmadığı için her NFT kimliği benzersiz bir tanımlayıcıdır. Yine, OpenSea'de bu sayı 'Detaylar' kısmının altında yer alır. Not alın veya panonuza kopyalayın."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "NFS'leri İçe Aktar"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Seçilen tokenleri içe aktar?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Kayıtlarımıza göre, sunulan RPC URL adresi değeri bu zincir kimliğinin bilinen bir sağlayıcısı ile uyumlu değil."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "NFT'nizi görmüyor musunuz?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Bir ayarı bulamıyor musun?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Dönüşüm oranı mevcut değil"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Henüz NFT yok"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Hiç Snap yüklü değil"
|
||||
},
|
||||
|
3
app/_locales/uk/messages.json
generated
3
app/_locales/uk/messages.json
generated
@ -211,9 +211,6 @@
|
||||
"delete": {
|
||||
"message": "Видалити"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Видалити обліковий запис"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Видалити мережу?"
|
||||
},
|
||||
|
12
app/_locales/vi/messages.json
generated
12
app/_locales/vi/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "Xóa"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "Xóa tài khoản"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "Xóa mạng?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "ID của NFT là một mã nhận dạng duy nhất vì không có hai NFT nào giống hệt nhau. Một lần nữa, trên OpenSea, mã số này nằm bên dưới mục 'Chi tiết'. Hãy ghi chú lại hoặc sao chép vào bộ nhớ đệm."
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "Nhập NFT"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "Nhập các token đã chọn?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "Theo hồ sơ của chúng tôi, giá trị RPC URL đã gửi không khớp với một nhà cung cấp đã biết cho ID chuỗi này."
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "Không thấy NFT của mình?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "Không tìm thấy thiết lập?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "Không có sẵn tỷ lệ quy đổi nào"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "Chưa có NFT"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "Chưa cài đặt Snap nào"
|
||||
},
|
||||
|
12
app/_locales/zh_CN/messages.json
generated
12
app/_locales/zh_CN/messages.json
generated
@ -911,9 +911,6 @@
|
||||
"delete": {
|
||||
"message": "删除"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "删除账户"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "删除网络?"
|
||||
},
|
||||
@ -1602,9 +1599,6 @@
|
||||
"importNFTTokenIdToolTip": {
|
||||
"message": "NFT的ID是唯一标识符,因为所有NFT都是独一无二的。同样,在OpenSea上,此数字位于“详情”下方。记下它,或将它复制到剪贴板上。"
|
||||
},
|
||||
"importNFTs": {
|
||||
"message": "添加收藏品"
|
||||
},
|
||||
"importSelectedTokens": {
|
||||
"message": "要导入所选代币吗?"
|
||||
},
|
||||
@ -1956,9 +1950,6 @@
|
||||
"mismatchedRpcUrl": {
|
||||
"message": "根据我们的记录,所提交的RPC URL值与此链ID的已知提供者不匹配。"
|
||||
},
|
||||
"missingNFT": {
|
||||
"message": "找不到您的 NFT?"
|
||||
},
|
||||
"missingSetting": {
|
||||
"message": "找不到设置吗?"
|
||||
},
|
||||
@ -2165,9 +2156,6 @@
|
||||
"noConversionRateAvailable": {
|
||||
"message": "无可用汇率"
|
||||
},
|
||||
"noNFTs": {
|
||||
"message": "尚无 NFT"
|
||||
},
|
||||
"noSnaps": {
|
||||
"message": "没有安装Snap"
|
||||
},
|
||||
|
3
app/_locales/zh_TW/messages.json
generated
3
app/_locales/zh_TW/messages.json
generated
@ -408,9 +408,6 @@
|
||||
"delete": {
|
||||
"message": "刪除"
|
||||
},
|
||||
"deleteAccount": {
|
||||
"message": "刪除帳戶"
|
||||
},
|
||||
"deleteNetwork": {
|
||||
"message": "刪除網路?"
|
||||
},
|
||||
|
@ -1,14 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_735_24127)">
|
||||
<path
|
||||
d="M3.99902 19C7.24796 17.5 8.87242 16.75 10.4969 16.75M16.9948 19C13.7458 17.5 12.1214 16.75 10.4969 16.75M10.4969 16.75V11.5M10.4969 11.5L10 10.4091M10.4969 11.5V9.5L10.9967 8.5M10 10.4091C10 10.4091 5.00889 11.0985 2.99935 9.5C1.29118 8.14126 1 4.5 1 4.5C1 4.5 5.55008 3.95155 7.54545 5.90909C8.91802 7.25563 10 10.4091 10 10.4091ZM10.9967 8.5C10.9967 8.5 11.5374 4.11404 13.4959 2.5C15.2137 1.08439 18.9941 1 18.9941 1C18.9941 1 19.1777 5.2683 17.4946 7C15.6792 8.86783 10.9967 8.5 10.9967 8.5Z"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_735_24127">
|
||||
<rect width="20" height="20" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.59902 17.1C6.52306 15.75 7.98508 15.075 9.44711 15.075M15.2952 17.1C12.3711 15.75 10.9091 15.075 9.44711 15.075M9.44711 15.075V10.35M9.44711 10.35L8.9999 9.36821M9.44711 10.35V8.55002L9.89696 7.65002M8.9999 9.36821C8.9999 9.36821 4.5079 9.98865 2.69931 8.55002C1.16197 7.32715 0.899902 4.05002 0.899902 4.05002C0.899902 4.05002 4.99497 3.55642 6.79081 5.31821C8.02612 6.53009 8.9999 9.36821 8.9999 9.36821ZM9.89696 7.65002C9.89696 7.65002 10.3835 3.70266 12.1462 2.25002C13.6922 0.975978 17.0946 0.900024 17.0946 0.900024C17.0946 0.900024 17.2598 4.74149 15.745 6.30002C14.1112 7.98107 9.89696 7.65002 9.89696 7.65002Z" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 794 B |
@ -485,9 +485,11 @@ const onMessageSetUpExtensionStreams = (msg) => {
|
||||
/**
|
||||
* This listener destroys the extension streams when the extension port is disconnected,
|
||||
* so that streams may be re-established later when the extension port is reconnected.
|
||||
*
|
||||
* @param {Error} [err] - Stream connection error
|
||||
*/
|
||||
const onDisconnectDestroyStreams = () => {
|
||||
const err = checkForLastError();
|
||||
const onDisconnectDestroyStreams = (err) => {
|
||||
const lastErr = err || checkForLastError();
|
||||
|
||||
extensionPort.onDisconnect.removeListener(onDisconnectDestroyStreams);
|
||||
|
||||
@ -501,8 +503,8 @@ const onDisconnectDestroyStreams = () => {
|
||||
* may cause issues. We suspect that this is a chromium bug as this event should only be called
|
||||
* once the port and connections are ready. Delay time is arbitrary.
|
||||
*/
|
||||
if (err) {
|
||||
console.warn(`${err} Resetting the streams.`);
|
||||
if (lastErr) {
|
||||
console.warn(`${lastErr} Resetting the streams.`);
|
||||
setTimeout(setupExtensionStreams, 1000);
|
||||
}
|
||||
};
|
||||
@ -630,6 +632,18 @@ const start = () => {
|
||||
injectScript(inpageBundle);
|
||||
}
|
||||
initStreams();
|
||||
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1457040
|
||||
// Temporary workaround for chromium bug that breaks the content script <=> background connection
|
||||
// for prerendered pages. This resets potentially broken extension streams if a page transitions
|
||||
// from the prerendered state to the active state.
|
||||
if (document.prerendering) {
|
||||
document.addEventListener('prerenderingchange', () => {
|
||||
onDisconnectDestroyStreams(
|
||||
new Error('Prerendered page has become active.'),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import EventEmitter from 'events';
|
||||
import log from 'loglevel';
|
||||
import { captureException } from '@sentry/browser';
|
||||
import { isEqual } from 'lodash';
|
||||
import {
|
||||
PersonalMessageManager,
|
||||
TypedMessageManager,
|
||||
@ -14,11 +15,17 @@ import {
|
||||
REFRESH_TOKEN_CHANGE_EVENT,
|
||||
INTERACTIVE_REPLACEMENT_TOKEN_CHANGE_EVENT,
|
||||
} from '@metamask-institutional/sdk';
|
||||
import {
|
||||
handleMmiPortfolio,
|
||||
setDashboardCookie,
|
||||
} from '@metamask-institutional/portfolio-dashboard';
|
||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||
import { CHAIN_IDS } from '../../../shared/constants/network';
|
||||
import {
|
||||
BUILD_QUOTE_ROUTE,
|
||||
CONNECT_HARDWARE_ROUTE,
|
||||
} from '../../../ui/helpers/constants/routes';
|
||||
import { previousValueComparator } from '../lib/util';
|
||||
import { getPermissionBackgroundApiMethods } from './permissions';
|
||||
|
||||
export default class MMIController extends EventEmitter {
|
||||
@ -69,6 +76,17 @@ export default class MMIController extends EventEmitter {
|
||||
this.transactionUpdateController.subscribeToEvents();
|
||||
});
|
||||
}
|
||||
|
||||
this.preferencesController.store.subscribe(
|
||||
previousValueComparator(async (prevState, currState) => {
|
||||
const { identities: prevIdentities } = prevState;
|
||||
const { identities: currIdentities } = currState;
|
||||
if (isEqual(prevIdentities, currIdentities)) {
|
||||
return;
|
||||
}
|
||||
await this.prepareMmiPortfolio();
|
||||
}, this.preferencesController.store.getState()),
|
||||
);
|
||||
} // End of constructor
|
||||
|
||||
async persistKeyringsAfterRefreshTokenChange() {
|
||||
@ -542,6 +560,44 @@ export default class MMIController extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
async handleMmiDashboardData() {
|
||||
await this.appStateController.getUnlockPromise(true);
|
||||
const keyringAccounts = await this.keyringController.getAccounts();
|
||||
const { identities } = this.preferencesController.store.getState();
|
||||
const { metaMetricsId } = this.metaMetricsController.store.getState();
|
||||
const getAccountDetails = (address) =>
|
||||
this.custodyController.getAccountDetails(address);
|
||||
const extensionId = this.extension.runtime.id;
|
||||
const networks = [
|
||||
...this.preferencesController.getRpcMethodPreferences(),
|
||||
{ chainId: CHAIN_IDS.MAINNET },
|
||||
{ chainId: CHAIN_IDS.GOERLI },
|
||||
];
|
||||
|
||||
return handleMmiPortfolio({
|
||||
keyringAccounts,
|
||||
identities,
|
||||
metaMetricsId,
|
||||
networks,
|
||||
getAccountDetails,
|
||||
extensionId,
|
||||
});
|
||||
}
|
||||
|
||||
async prepareMmiPortfolio() {
|
||||
if (!process.env.IN_TEST) {
|
||||
try {
|
||||
const mmiDashboardData = await this.handleMmiDashboardData();
|
||||
const cookieSetUrls =
|
||||
this.mmiConfigurationController.store.mmiConfiguration?.portfolio
|
||||
?.cookieSetUrls;
|
||||
setDashboardCookie(mmiDashboardData, cookieSetUrls);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async setAccountAndNetwork(origin, address, chainId) {
|
||||
await this.appStateController.getUnlockPromise(true);
|
||||
const selectedAddress = this.preferencesController.getSelectedAddress();
|
||||
|
@ -8,14 +8,6 @@ import {
|
||||
buildSnapRestrictedMethodSpecifications,
|
||||
} from './snap-permissions';
|
||||
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
jest.mock('@metamask/snaps-controllers', () =>
|
||||
jest.requireActual('@metamask/snaps-controllers-flask'),
|
||||
);
|
||||
jest.mock('@metamask/rpc-methods', () =>
|
||||
jest.requireActual('@metamask/rpc-methods-flask'),
|
||||
);
|
||||
|
||||
describe('buildSnapRestrictedMethodSpecifications', () => {
|
||||
it('creates valid permission specification objects', () => {
|
||||
const hooks = {
|
||||
|
@ -1,8 +1,5 @@
|
||||
import { ObservableStore } from '@metamask/obs-store';
|
||||
import { normalize as normalizeAddress } from 'eth-sig-util';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import { setDashboardCookie } from '@metamask-institutional/portfolio-dashboard';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { IPFS_DEFAULT_GATEWAY_URL } from '../../../shared/constants/network';
|
||||
import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets';
|
||||
import { ThemeType } from '../../../shared/constants/preferences';
|
||||
@ -81,14 +78,6 @@ export default class PreferencesController {
|
||||
this.store.setMaxListeners(13);
|
||||
this.tokenListController = opts.tokenListController;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
this.handleMmiDashboardData = opts.handleMmiDashboardData;
|
||||
|
||||
if (!process.env.IN_TEST) {
|
||||
this.mmiConfigurationStore = opts.mmiConfigurationStore.getState();
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
this._subscribeToInfuraAvailability();
|
||||
|
||||
global.setPreference = (key, value) => {
|
||||
@ -261,10 +250,6 @@ export default class PreferencesController {
|
||||
return ids;
|
||||
}, {});
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
this.prepareMmiPortfolio();
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
this.store.updateState({ identities });
|
||||
}
|
||||
|
||||
@ -290,10 +275,6 @@ export default class PreferencesController {
|
||||
this.setSelectedAddress(selected);
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
this.prepareMmiPortfolio();
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
@ -350,10 +331,6 @@ export default class PreferencesController {
|
||||
this.store.updateState({ identities, lostIdentities });
|
||||
this.addAddresses(addresses);
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
this.prepareMmiPortfolio();
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
// If the selected account is no longer valid,
|
||||
// select an arbitrary other account:
|
||||
let selected = this.getSelectedAddress();
|
||||
@ -534,21 +511,6 @@ export default class PreferencesController {
|
||||
return this.store.getState().disabledRpcMethodPreferences;
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
async prepareMmiPortfolio() {
|
||||
if (!process.env.IN_TEST) {
|
||||
try {
|
||||
const mmiDashboardData = await this.handleMmiDashboardData();
|
||||
const cookieSetUrls =
|
||||
this.mmiConfigurationStore.mmiConfiguration?.portfolio?.cookieSetUrls;
|
||||
setDashboardCookie(mmiDashboardData, cookieSetUrls);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
@ -6,6 +6,7 @@ if (
|
||||
) {
|
||||
console.log = noop;
|
||||
console.info = noop;
|
||||
console.warn = noop;
|
||||
}
|
||||
|
||||
function noop() {
|
||||
|
@ -1,8 +1,10 @@
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
import { permittedMethods as permittedSnapMethods } from '@metamask/rpc-methods';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { permissionRpcMethods } from '@metamask/permission-controller';
|
||||
import { selectHooks } from '@metamask/rpc-methods/dist/utils';
|
||||
import {
|
||||
selectHooks,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
permittedMethods as permittedSnapMethods,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '@metamask/rpc-methods';
|
||||
import { ethErrors } from 'eth-rpc-errors';
|
||||
import { flatten } from 'lodash';
|
||||
import { UNSUPPORTED_RPC_METHODS } from '../../../../shared/constants/network';
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ERC1155, ERC721 } from '@metamask/controller-utils';
|
||||
import { ethErrors } from 'eth-rpc-errors';
|
||||
import { MESSAGE_TYPE } from '../../../../../shared/constants/app';
|
||||
|
||||
const watchAsset = {
|
||||
@ -39,6 +41,21 @@ async function watchAssetHandler(
|
||||
params: { options: asset, type },
|
||||
origin,
|
||||
} = req;
|
||||
|
||||
const { tokenId } = asset;
|
||||
|
||||
if (
|
||||
[ERC721, ERC1155].includes(type) &&
|
||||
tokenId !== undefined &&
|
||||
typeof tokenId !== 'string'
|
||||
) {
|
||||
return end(
|
||||
ethErrors.rpc.invalidParams({
|
||||
message: `Expected parameter 'tokenId' to be type 'string'. Received type '${typeof tokenId}'`,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await handleWatchAssetRequest(asset, type, origin);
|
||||
res.result = true;
|
||||
return end();
|
||||
|
@ -0,0 +1,99 @@
|
||||
import { ERC20, ERC721 } from '@metamask/controller-utils';
|
||||
import { ethErrors } from 'eth-rpc-errors';
|
||||
import watchAssetHandler from './watch-asset';
|
||||
|
||||
describe('watchAssetHandler', () => {
|
||||
let mockEnd;
|
||||
let mockHandleWatchAssetRequest;
|
||||
|
||||
beforeEach(() => {
|
||||
mockEnd = jest.fn();
|
||||
mockHandleWatchAssetRequest = jest.fn();
|
||||
});
|
||||
|
||||
it('should handle valid input for type ERC721 correctly', async () => {
|
||||
const req = {
|
||||
params: {
|
||||
options: {
|
||||
address: '0x1234',
|
||||
tokenId: 'testTokenId',
|
||||
},
|
||||
type: ERC721,
|
||||
},
|
||||
origin: 'testOrigin',
|
||||
};
|
||||
|
||||
const res = {
|
||||
result: false,
|
||||
};
|
||||
|
||||
await watchAssetHandler.implementation(req, res, null, mockEnd, {
|
||||
handleWatchAssetRequest: mockHandleWatchAssetRequest,
|
||||
});
|
||||
|
||||
expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith(
|
||||
req.params.options,
|
||||
req.params.type,
|
||||
req.origin,
|
||||
);
|
||||
expect(res.result).toStrictEqual(true);
|
||||
expect(mockEnd).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should handle valid input for type ERC20 correctly', async () => {
|
||||
const req = {
|
||||
params: {
|
||||
options: {
|
||||
address: '0x1234',
|
||||
symbol: 'TEST',
|
||||
decimals: 18,
|
||||
},
|
||||
type: ERC20,
|
||||
},
|
||||
origin: 'testOrigin',
|
||||
};
|
||||
|
||||
const res = {
|
||||
result: false,
|
||||
};
|
||||
|
||||
await watchAssetHandler.implementation(req, res, null, mockEnd, {
|
||||
handleWatchAssetRequest: mockHandleWatchAssetRequest,
|
||||
});
|
||||
|
||||
expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith(
|
||||
req.params.options,
|
||||
req.params.type,
|
||||
req.origin,
|
||||
);
|
||||
expect(res.result).toStrictEqual(true);
|
||||
expect(mockEnd).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should throw when type is ERC721 and tokenId type is invalid', async () => {
|
||||
const req = {
|
||||
params: {
|
||||
options: {
|
||||
address: '0x1234',
|
||||
tokenId: 222,
|
||||
},
|
||||
type: ERC721,
|
||||
},
|
||||
origin: 'testOrigin',
|
||||
};
|
||||
|
||||
const res = {
|
||||
result: false,
|
||||
};
|
||||
|
||||
await watchAssetHandler.implementation(req, res, null, mockEnd, {
|
||||
handleWatchAssetRequest: mockHandleWatchAssetRequest,
|
||||
});
|
||||
|
||||
expect(mockEnd).toHaveBeenCalledWith(
|
||||
ethErrors.rpc.invalidParams({
|
||||
message: `Expected parameter 'tokenId' to be type 'string'. Received type 'number'`,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
@ -42,26 +42,11 @@ const createLoggerMiddlewareMock = () => (req, res, next) => {
|
||||
next();
|
||||
};
|
||||
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
const proxyPermissions = proxyquire('./controllers/permissions', {
|
||||
'./snaps/snap-permissions': proxyquire(
|
||||
'./controllers/permissions/snaps/snap-permissions',
|
||||
{
|
||||
// eslint-disable-next-line node/global-require
|
||||
'@metamask/snaps-controllers': require('@metamask/snaps-controllers-flask'),
|
||||
// eslint-disable-next-line node/global-require
|
||||
'@metamask/rpc-methods': require('@metamask/rpc-methods-flask'),
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
const TEST_SEED =
|
||||
'debris dizzy just program just float decrease vacant alarm reduce speak stadium';
|
||||
|
||||
const MetaMaskController = proxyquire('./metamask-controller', {
|
||||
'./lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock },
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
'./controllers/permissions': proxyPermissions,
|
||||
}).default;
|
||||
|
||||
describe('MetaMaskController', function () {
|
||||
|
@ -71,7 +71,6 @@ import {
|
||||
} from '@metamask-institutional/custody-keyring';
|
||||
import { InstitutionalFeaturesController } from '@metamask-institutional/institutional-features';
|
||||
import { CustodyController } from '@metamask-institutional/custody-controller';
|
||||
import { handleMmiPortfolio } from '@metamask-institutional/portfolio-dashboard';
|
||||
import { TransactionUpdateController } from '@metamask-institutional/transaction-update';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { SignatureController } from '@metamask/signature-controller';
|
||||
@ -121,6 +120,9 @@ import {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../shared/constants/permissions';
|
||||
import { UI_NOTIFICATIONS } from '../../shared/notifications';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import { UI_INSTITUTIONAL_NOTIFICATIONS } from '../../shared/notifications/institutional';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { MILLISECOND, SECOND } from '../../shared/constants/time';
|
||||
import {
|
||||
ORIGIN_METAMASK,
|
||||
@ -379,10 +381,6 @@ export default class MetamaskController extends EventEmitter {
|
||||
),
|
||||
tokenListController: this.tokenListController,
|
||||
provider: this.provider,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
handleMmiDashboardData: this.handleMmiDashboardData.bind(this),
|
||||
mmiConfigurationStore: this.mmiConfigurationController.store,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
});
|
||||
|
||||
this.preferencesController.store.subscribe(async ({ currentLocale }) => {
|
||||
@ -568,12 +566,8 @@ export default class MetamaskController extends EventEmitter {
|
||||
),
|
||||
getCurrentAccountEIP1559Compatibility:
|
||||
this.getCurrentAccountEIP1559Compatibility.bind(this),
|
||||
legacyAPIEndpoint: `${gasApiBaseUrl}/networks/<chain_id>/gasPrices`,
|
||||
EIP1559APIEndpoint: `${gasApiBaseUrl}/networks/<chain_id>/suggestedGasFees`,
|
||||
getCurrentNetworkLegacyGasAPICompatibility: () => {
|
||||
const { chainId } = this.networkController.state.providerConfig;
|
||||
return process.env.IN_TEST || chainId === CHAIN_IDS.MAINNET;
|
||||
},
|
||||
getCurrentNetworkLegacyGasAPICompatibility: () => false,
|
||||
getChainId: () => this.networkController.state.providerConfig.chainId,
|
||||
});
|
||||
|
||||
@ -622,9 +616,16 @@ export default class MetamaskController extends EventEmitter {
|
||||
const announcementMessenger = this.controllerMessenger.getRestricted({
|
||||
name: 'AnnouncementController',
|
||||
});
|
||||
|
||||
let allAnnouncements = UI_NOTIFICATIONS;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
allAnnouncements = UI_INSTITUTIONAL_NOTIFICATIONS;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
this.announcementController = new AnnouncementController({
|
||||
messenger: announcementMessenger,
|
||||
allAnnouncements: UI_NOTIFICATIONS,
|
||||
allAnnouncements,
|
||||
state: initState.AnnouncementController,
|
||||
});
|
||||
|
||||
@ -3912,7 +3913,8 @@ export default class MetamaskController extends EventEmitter {
|
||||
),
|
||||
handleMmiCheckIfTokenIsPresent:
|
||||
this.mmiController.handleMmiCheckIfTokenIsPresent.bind(this),
|
||||
handleMmiDashboardData: this.handleMmiDashboardData.bind(this),
|
||||
handleMmiDashboardData:
|
||||
this.mmiController.handleMmiDashboardData.bind(this),
|
||||
handleMmiOpenSwaps: this.mmiController.handleMmiOpenSwaps.bind(this),
|
||||
handleMmiSetAccountAndNetwork:
|
||||
this.mmiController.setAccountAndNetwork.bind(this),
|
||||
@ -3971,37 +3973,6 @@ export default class MetamaskController extends EventEmitter {
|
||||
return engine;
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
/**
|
||||
* This method is needed in preferences controller
|
||||
* so it needs to be here and not in our controller because
|
||||
* preferences controllers is initiated first
|
||||
*/
|
||||
async handleMmiDashboardData() {
|
||||
await this.appStateController.getUnlockPromise(true);
|
||||
const keyringAccounts = await this.keyringController.getAccounts();
|
||||
const { identities } = this.preferencesController.store.getState();
|
||||
const { metaMetricsId } = this.metaMetricsController.store.getState();
|
||||
const getAccountDetails = (address) =>
|
||||
this.custodyController.getAccountDetails(address);
|
||||
const extensionId = this.extension.runtime.id;
|
||||
const networks = [
|
||||
...this.preferencesController.getRpcMethodPreferences(),
|
||||
{ chainId: CHAIN_IDS.MAINNET },
|
||||
{ chainId: CHAIN_IDS.GOERLI },
|
||||
];
|
||||
|
||||
return handleMmiPortfolio({
|
||||
keyringAccounts,
|
||||
identities,
|
||||
metaMetricsId,
|
||||
networks,
|
||||
getAccountDetails,
|
||||
extensionId,
|
||||
});
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
/**
|
||||
* TODO:LegacyProvider: Delete
|
||||
* A method for providing our public config info over a stream.
|
||||
|
@ -74,19 +74,6 @@ function MockEthContract() {
|
||||
};
|
||||
}
|
||||
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
const proxyPermissions = proxyquire('./controllers/permissions', {
|
||||
'./snaps/snap-permissions': proxyquire(
|
||||
'./controllers/permissions/snaps/snap-permissions',
|
||||
{
|
||||
// eslint-disable-next-line node/global-require
|
||||
'@metamask/snaps-controllers': require('@metamask/snaps-controllers-flask'),
|
||||
// eslint-disable-next-line node/global-require
|
||||
'@metamask/rpc-methods': require('@metamask/rpc-methods-flask'),
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
// TODO, Feb 24, 2023:
|
||||
// ethjs-contract is being added to proxyquire, but we might want to discontinue proxyquire
|
||||
// this is for expediency as we resolve a bug for v10.26.0. The proper solution here would have
|
||||
@ -95,14 +82,10 @@ const proxyPermissions = proxyquire('./controllers/permissions', {
|
||||
const MetaMaskController = proxyquire('./metamask-controller', {
|
||||
'./lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock },
|
||||
'ethjs-contract': MockEthContract,
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
'./controllers/permissions': proxyPermissions,
|
||||
}).default;
|
||||
|
||||
const MetaMaskControllerMV3 = proxyquire('./metamask-controller', {
|
||||
'../../shared/modules/mv3.utils': { isManifestV3: true },
|
||||
// Temporarily replace the snaps packages with the Flask versions.
|
||||
'./controllers/permissions': proxyPermissions,
|
||||
}).default;
|
||||
|
||||
const currentNetworkId = '5';
|
||||
|
@ -1,8 +1,21 @@
|
||||
/*
|
||||
NOTICE:
|
||||
This Snow + LavaMoat scuttling integration is currently being used
|
||||
with an experimental API (https://github.com/LavaMoat/LavaMoat/pull/462).
|
||||
Changing this code must be done cautiously to avoid breaking the app!
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line import/unambiguous
|
||||
(function () {
|
||||
const log = console.log.bind(console);
|
||||
const msg = 'SNOW INTERCEPTED NEW WINDOW CREATION IN METAMASK APP: ';
|
||||
window.top.SNOW((win) => {
|
||||
log(msg, win, win?.frameElement);
|
||||
const msg =
|
||||
'Snow detected a new realm creation attempt in MetaMask. Performing scuttling on new realm.';
|
||||
Object.defineProperty(window.top, 'SCUTTLER', {
|
||||
value: (realm, scuttle) => {
|
||||
window.top.SNOW((win) => {
|
||||
log(msg, win);
|
||||
scuttle(win);
|
||||
}, realm);
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
@ -51,7 +51,7 @@ buildTypes:
|
||||
- SEGMENT_FLASK_WRITE_KEY
|
||||
- ALLOW_LOCAL_SNAPS: true
|
||||
- REQUIRE_SNAPS_ALLOWLIST: false
|
||||
- IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.16.1-flask.1/index.html
|
||||
- IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.35.2-flask.1/index.html
|
||||
- SUPPORT_LINK: https://metamask-flask.zendesk.com/hc
|
||||
- SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new
|
||||
- INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID
|
||||
@ -69,7 +69,7 @@ buildTypes:
|
||||
- SEGMENT_FLASK_WRITE_KEY
|
||||
- ALLOW_LOCAL_SNAPS: true
|
||||
- REQUIRE_SNAPS_ALLOWLIST: false
|
||||
- IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.16.1-flask.1/index.html
|
||||
- IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.metamask.io/0.35.2-flask.1/index.html
|
||||
- SUPPORT_LINK: https://metamask-flask.zendesk.com/hc
|
||||
- SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new
|
||||
- INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID
|
||||
|
@ -147,8 +147,11 @@ async function defineAndRunBuildTasks() {
|
||||
|
||||
// build lavamoat runtime file
|
||||
await lavapack.buildRuntime({
|
||||
scuttleGlobalThis: applyLavaMoat && shouldScuttle,
|
||||
scuttleGlobalThisExceptions,
|
||||
scuttleGlobalThis: {
|
||||
enabled: applyLavaMoat && shouldScuttle,
|
||||
scuttlerName: 'SCUTTLER',
|
||||
exceptions: scuttleGlobalThisExceptions,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,12 @@ function createManifestTasks({
|
||||
.trim()
|
||||
.substring(0, 8);
|
||||
|
||||
manifest.name = `MetaMask ${capitalize(
|
||||
buildType,
|
||||
)}${mv3Str}${lavamoatStr}${snowStr}`;
|
||||
const buildName =
|
||||
buildType === 'mmi'
|
||||
? `MetaMask Institutional ${mv3Str}${lavamoatStr}${snowStr}`
|
||||
: `MetaMask ${capitalize(buildType)}${mv3Str}${lavamoatStr}${snowStr}`;
|
||||
|
||||
manifest.name = buildName;
|
||||
|
||||
manifest.description = `${environment} build from git id: ${gitRevisionStr}`;
|
||||
}
|
||||
|
@ -186,8 +186,14 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": true,
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>micro-ftch": {
|
||||
@ -214,7 +220,7 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
|
||||
@ -222,7 +228,19 @@
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethersproject/abi": {
|
||||
@ -1712,9 +1730,15 @@
|
||||
},
|
||||
"@metamask/rpc-methods": {
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/utils": true,
|
||||
"@metamask/permission-controller": true,
|
||||
"@metamask/rpc-methods>@metamask/utils": true,
|
||||
"@metamask/rpc-methods>nanoid": true,
|
||||
"@metamask/snaps-ui": true,
|
||||
"@metamask/snaps-utils": true,
|
||||
"eth-rpc-errors": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
@ -1723,6 +1747,18 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>nanoid": {
|
||||
"globals": {
|
||||
"crypto.getRandomValues": true
|
||||
@ -1847,6 +1883,81 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui": {
|
||||
"packages": {
|
||||
"@metamask/snaps-ui>@metamask/utils": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"URL": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"console.warn": true,
|
||||
"document.body.appendChild": true,
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-utils>@metamask/utils": true,
|
||||
"@metamask/snaps-utils>cron-parser": true,
|
||||
"@metamask/snaps-utils>fast-json-stable-stringify": true,
|
||||
"@metamask/snaps-utils>rfdc": true,
|
||||
"@metamask/snaps-utils>validate-npm-package-name": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>cron-parser": {
|
||||
"packages": {
|
||||
"browserify>browser-resolve": true,
|
||||
"luxon": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>rfdc": {
|
||||
"packages": {
|
||||
"browserify>buffer": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name": {
|
||||
"packages": {
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": {
|
||||
"packages": {
|
||||
"browserify>process": true,
|
||||
"semver": true
|
||||
}
|
||||
},
|
||||
"@metamask/subject-metadata-controller": {
|
||||
"packages": {
|
||||
"@metamask/subject-metadata-controller>@metamask/base-controller": true
|
||||
@ -1948,85 +2059,110 @@
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true,
|
||||
"XMLHttpRequest": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_RELEASE__": true,
|
||||
"indexedDB.open": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry-internal/tracing": true,
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>@sentry/replay": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry-internal/tracing": {
|
||||
"globals": {
|
||||
"Headers": true,
|
||||
"PerformanceObserver": true,
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"addEventListener": true,
|
||||
"performance.getEntriesByType": true,
|
||||
"removeEventListener": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core": {
|
||||
"globals": {
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_TRACING__": true,
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"clearTimeout": true,
|
||||
"console.warn": true,
|
||||
"setInterval": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": true,
|
||||
"@sentry/browser>@sentry/core>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": {
|
||||
"@sentry/browser>@sentry/replay": {
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"Blob": true,
|
||||
"CSSConditionRule": true,
|
||||
"CSSGroupingRule": true,
|
||||
"CSSMediaRule": true,
|
||||
"CSSSupportsRule": true,
|
||||
"DragEvent": true,
|
||||
"Element": true,
|
||||
"FormData": true,
|
||||
"HTMLCanvasElement": true,
|
||||
"HTMLElement.prototype": true,
|
||||
"HTMLFormElement": true,
|
||||
"HTMLImageElement": true,
|
||||
"HTMLInputElement.prototype": true,
|
||||
"HTMLOptionElement.prototype": true,
|
||||
"HTMLSelectElement.prototype": true,
|
||||
"HTMLTextAreaElement.prototype": true,
|
||||
"Headers": true,
|
||||
"ImageData": true,
|
||||
"MouseEvent": true,
|
||||
"MutationObserver": true,
|
||||
"Node.prototype.contains": true,
|
||||
"PerformanceObserver": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"URLSearchParams": true,
|
||||
"Worker": true,
|
||||
"Zone": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__rrMutationObserver": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"document": true,
|
||||
"innerHeight": true,
|
||||
"innerWidth": true,
|
||||
"location.href": true,
|
||||
"pageXOffset": true,
|
||||
"pageYOffset": true,
|
||||
"requestAnimationFrame": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": {
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/utils": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations": {
|
||||
"globals": {
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"setTimeout": true
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"console.log": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/integrations>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true,
|
||||
"localforage": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"globals": {
|
||||
"CustomEvent": true,
|
||||
@ -2038,22 +2174,22 @@
|
||||
"Headers": true,
|
||||
"Request": true,
|
||||
"Response": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"XMLHttpRequest.prototype": true,
|
||||
"__SENTRY_BROWSER_BUNDLE__": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"document": true,
|
||||
"setTimeout": true
|
||||
"new": true,
|
||||
"setTimeout": true,
|
||||
"target": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/utils>tslib": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@truffle/codec": {
|
||||
"packages": {
|
||||
"@truffle/codec>@truffle/abi-utils": true,
|
||||
@ -4490,6 +4626,12 @@
|
||||
"string.prototype.matchall>regexp.prototype.flags>functions-have-names": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"globals": {
|
||||
"crypto": true,
|
||||
|
@ -186,8 +186,14 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": true,
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>micro-ftch": {
|
||||
@ -214,7 +220,7 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
|
||||
@ -222,7 +228,19 @@
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethersproject/abi": {
|
||||
@ -1883,6 +1901,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/rpc-methods-flask>@metamask/utils": true,
|
||||
@ -2082,6 +2101,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-controllers-flask>@metamask/utils": true,
|
||||
@ -2293,6 +2313,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-utils-flask>@metamask/utils": true,
|
||||
@ -2474,85 +2495,110 @@
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true,
|
||||
"XMLHttpRequest": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_RELEASE__": true,
|
||||
"indexedDB.open": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry-internal/tracing": true,
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>@sentry/replay": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry-internal/tracing": {
|
||||
"globals": {
|
||||
"Headers": true,
|
||||
"PerformanceObserver": true,
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"addEventListener": true,
|
||||
"performance.getEntriesByType": true,
|
||||
"removeEventListener": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core": {
|
||||
"globals": {
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_TRACING__": true,
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"clearTimeout": true,
|
||||
"console.warn": true,
|
||||
"setInterval": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": true,
|
||||
"@sentry/browser>@sentry/core>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": {
|
||||
"@sentry/browser>@sentry/replay": {
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"Blob": true,
|
||||
"CSSConditionRule": true,
|
||||
"CSSGroupingRule": true,
|
||||
"CSSMediaRule": true,
|
||||
"CSSSupportsRule": true,
|
||||
"DragEvent": true,
|
||||
"Element": true,
|
||||
"FormData": true,
|
||||
"HTMLCanvasElement": true,
|
||||
"HTMLElement.prototype": true,
|
||||
"HTMLFormElement": true,
|
||||
"HTMLImageElement": true,
|
||||
"HTMLInputElement.prototype": true,
|
||||
"HTMLOptionElement.prototype": true,
|
||||
"HTMLSelectElement.prototype": true,
|
||||
"HTMLTextAreaElement.prototype": true,
|
||||
"Headers": true,
|
||||
"ImageData": true,
|
||||
"MouseEvent": true,
|
||||
"MutationObserver": true,
|
||||
"Node.prototype.contains": true,
|
||||
"PerformanceObserver": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"URLSearchParams": true,
|
||||
"Worker": true,
|
||||
"Zone": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__rrMutationObserver": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"document": true,
|
||||
"innerHeight": true,
|
||||
"innerWidth": true,
|
||||
"location.href": true,
|
||||
"pageXOffset": true,
|
||||
"pageYOffset": true,
|
||||
"requestAnimationFrame": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": {
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/utils": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations": {
|
||||
"globals": {
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"setTimeout": true
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"console.log": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/integrations>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true,
|
||||
"localforage": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"globals": {
|
||||
"CustomEvent": true,
|
||||
@ -2564,22 +2610,22 @@
|
||||
"Headers": true,
|
||||
"Request": true,
|
||||
"Response": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"XMLHttpRequest.prototype": true,
|
||||
"__SENTRY_BROWSER_BUNDLE__": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"document": true,
|
||||
"setTimeout": true
|
||||
"new": true,
|
||||
"setTimeout": true,
|
||||
"target": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/utils>tslib": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@truffle/codec": {
|
||||
"packages": {
|
||||
"@truffle/codec>@truffle/abi-utils": true,
|
||||
@ -5148,6 +5194,12 @@
|
||||
"string.prototype.matchall>regexp.prototype.flags>functions-have-names": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"terser>source-map-support>buffer-from": {
|
||||
"packages": {
|
||||
"browserify>buffer": true
|
||||
|
@ -186,8 +186,14 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": true,
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>micro-ftch": {
|
||||
@ -214,7 +220,7 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
|
||||
@ -222,7 +228,19 @@
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethersproject/abi": {
|
||||
@ -1883,6 +1901,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/rpc-methods-flask>@metamask/utils": true,
|
||||
@ -2082,6 +2101,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-controllers-flask>@metamask/utils": true,
|
||||
@ -2293,6 +2313,7 @@
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-utils-flask>@metamask/utils": true,
|
||||
@ -2474,85 +2495,110 @@
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true,
|
||||
"XMLHttpRequest": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_RELEASE__": true,
|
||||
"indexedDB.open": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry-internal/tracing": true,
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>@sentry/replay": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry-internal/tracing": {
|
||||
"globals": {
|
||||
"Headers": true,
|
||||
"PerformanceObserver": true,
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"addEventListener": true,
|
||||
"performance.getEntriesByType": true,
|
||||
"removeEventListener": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core": {
|
||||
"globals": {
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_TRACING__": true,
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"clearTimeout": true,
|
||||
"console.warn": true,
|
||||
"setInterval": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": true,
|
||||
"@sentry/browser>@sentry/core>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": {
|
||||
"@sentry/browser>@sentry/replay": {
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"Blob": true,
|
||||
"CSSConditionRule": true,
|
||||
"CSSGroupingRule": true,
|
||||
"CSSMediaRule": true,
|
||||
"CSSSupportsRule": true,
|
||||
"DragEvent": true,
|
||||
"Element": true,
|
||||
"FormData": true,
|
||||
"HTMLCanvasElement": true,
|
||||
"HTMLElement.prototype": true,
|
||||
"HTMLFormElement": true,
|
||||
"HTMLImageElement": true,
|
||||
"HTMLInputElement.prototype": true,
|
||||
"HTMLOptionElement.prototype": true,
|
||||
"HTMLSelectElement.prototype": true,
|
||||
"HTMLTextAreaElement.prototype": true,
|
||||
"Headers": true,
|
||||
"ImageData": true,
|
||||
"MouseEvent": true,
|
||||
"MutationObserver": true,
|
||||
"Node.prototype.contains": true,
|
||||
"PerformanceObserver": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"URLSearchParams": true,
|
||||
"Worker": true,
|
||||
"Zone": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__rrMutationObserver": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"document": true,
|
||||
"innerHeight": true,
|
||||
"innerWidth": true,
|
||||
"location.href": true,
|
||||
"pageXOffset": true,
|
||||
"pageYOffset": true,
|
||||
"requestAnimationFrame": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": {
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/utils": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations": {
|
||||
"globals": {
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"setTimeout": true
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"console.log": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/integrations>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true,
|
||||
"localforage": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"globals": {
|
||||
"CustomEvent": true,
|
||||
@ -2564,22 +2610,22 @@
|
||||
"Headers": true,
|
||||
"Request": true,
|
||||
"Response": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"XMLHttpRequest.prototype": true,
|
||||
"__SENTRY_BROWSER_BUNDLE__": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"document": true,
|
||||
"setTimeout": true
|
||||
"new": true,
|
||||
"setTimeout": true,
|
||||
"target": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/utils>tslib": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@truffle/codec": {
|
||||
"packages": {
|
||||
"@truffle/codec>@truffle/abi-utils": true,
|
||||
@ -5148,6 +5194,12 @@
|
||||
"string.prototype.matchall>regexp.prototype.flags>functions-have-names": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"terser>source-map-support>buffer-from": {
|
||||
"packages": {
|
||||
"browserify>buffer": true
|
||||
|
@ -186,8 +186,14 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": true,
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>micro-ftch": {
|
||||
@ -214,7 +220,7 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
|
||||
@ -222,7 +228,19 @@
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethersproject/abi": {
|
||||
@ -1712,9 +1730,15 @@
|
||||
},
|
||||
"@metamask/rpc-methods": {
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/utils": true,
|
||||
"@metamask/permission-controller": true,
|
||||
"@metamask/rpc-methods>@metamask/utils": true,
|
||||
"@metamask/rpc-methods>nanoid": true,
|
||||
"@metamask/snaps-ui": true,
|
||||
"@metamask/snaps-utils": true,
|
||||
"eth-rpc-errors": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
@ -1723,6 +1747,18 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>nanoid": {
|
||||
"globals": {
|
||||
"crypto.getRandomValues": true
|
||||
@ -1847,6 +1883,81 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui": {
|
||||
"packages": {
|
||||
"@metamask/snaps-ui>@metamask/utils": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"URL": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"console.warn": true,
|
||||
"document.body.appendChild": true,
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-utils>@metamask/utils": true,
|
||||
"@metamask/snaps-utils>cron-parser": true,
|
||||
"@metamask/snaps-utils>fast-json-stable-stringify": true,
|
||||
"@metamask/snaps-utils>rfdc": true,
|
||||
"@metamask/snaps-utils>validate-npm-package-name": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>cron-parser": {
|
||||
"packages": {
|
||||
"browserify>browser-resolve": true,
|
||||
"luxon": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>rfdc": {
|
||||
"packages": {
|
||||
"browserify>buffer": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name": {
|
||||
"packages": {
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": {
|
||||
"packages": {
|
||||
"browserify>process": true,
|
||||
"semver": true
|
||||
}
|
||||
},
|
||||
"@metamask/subject-metadata-controller": {
|
||||
"packages": {
|
||||
"@metamask/subject-metadata-controller>@metamask/base-controller": true
|
||||
@ -1948,85 +2059,110 @@
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true,
|
||||
"XMLHttpRequest": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_RELEASE__": true,
|
||||
"indexedDB.open": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry-internal/tracing": true,
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>@sentry/replay": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry-internal/tracing": {
|
||||
"globals": {
|
||||
"Headers": true,
|
||||
"PerformanceObserver": true,
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"addEventListener": true,
|
||||
"performance.getEntriesByType": true,
|
||||
"removeEventListener": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core": {
|
||||
"globals": {
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_TRACING__": true,
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"clearTimeout": true,
|
||||
"console.warn": true,
|
||||
"setInterval": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": true,
|
||||
"@sentry/browser>@sentry/core>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": {
|
||||
"@sentry/browser>@sentry/replay": {
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"Blob": true,
|
||||
"CSSConditionRule": true,
|
||||
"CSSGroupingRule": true,
|
||||
"CSSMediaRule": true,
|
||||
"CSSSupportsRule": true,
|
||||
"DragEvent": true,
|
||||
"Element": true,
|
||||
"FormData": true,
|
||||
"HTMLCanvasElement": true,
|
||||
"HTMLElement.prototype": true,
|
||||
"HTMLFormElement": true,
|
||||
"HTMLImageElement": true,
|
||||
"HTMLInputElement.prototype": true,
|
||||
"HTMLOptionElement.prototype": true,
|
||||
"HTMLSelectElement.prototype": true,
|
||||
"HTMLTextAreaElement.prototype": true,
|
||||
"Headers": true,
|
||||
"ImageData": true,
|
||||
"MouseEvent": true,
|
||||
"MutationObserver": true,
|
||||
"Node.prototype.contains": true,
|
||||
"PerformanceObserver": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"URLSearchParams": true,
|
||||
"Worker": true,
|
||||
"Zone": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__rrMutationObserver": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"document": true,
|
||||
"innerHeight": true,
|
||||
"innerWidth": true,
|
||||
"location.href": true,
|
||||
"pageXOffset": true,
|
||||
"pageYOffset": true,
|
||||
"requestAnimationFrame": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": {
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/utils": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations": {
|
||||
"globals": {
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"setTimeout": true
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"console.log": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/integrations>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true,
|
||||
"localforage": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"globals": {
|
||||
"CustomEvent": true,
|
||||
@ -2038,22 +2174,22 @@
|
||||
"Headers": true,
|
||||
"Request": true,
|
||||
"Response": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"XMLHttpRequest.prototype": true,
|
||||
"__SENTRY_BROWSER_BUNDLE__": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"document": true,
|
||||
"setTimeout": true
|
||||
"new": true,
|
||||
"setTimeout": true,
|
||||
"target": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/utils>tslib": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@truffle/codec": {
|
||||
"packages": {
|
||||
"@truffle/codec>@truffle/abi-utils": true,
|
||||
@ -4490,6 +4626,12 @@
|
||||
"string.prototype.matchall>regexp.prototype.flags>functions-have-names": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"globals": {
|
||||
"crypto": true,
|
||||
|
@ -186,8 +186,14 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": true,
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>@ethereumjs/util>micro-ftch": {
|
||||
@ -214,7 +220,7 @@
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
|
||||
@ -222,7 +228,19 @@
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree>@noble/hashes": true
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/curves>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@ethersproject/abi": {
|
||||
@ -1933,9 +1951,15 @@
|
||||
},
|
||||
"@metamask/rpc-methods": {
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/utils": true,
|
||||
"@metamask/permission-controller": true,
|
||||
"@metamask/rpc-methods>@metamask/utils": true,
|
||||
"@metamask/rpc-methods>nanoid": true,
|
||||
"@metamask/snaps-ui": true,
|
||||
"@metamask/snaps-utils": true,
|
||||
"eth-rpc-errors": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
@ -1944,6 +1968,18 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/rpc-methods>nanoid": {
|
||||
"globals": {
|
||||
"crypto.getRandomValues": true
|
||||
@ -2068,6 +2104,81 @@
|
||||
"crypto.getRandomValues": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui": {
|
||||
"packages": {
|
||||
"@metamask/snaps-ui>@metamask/utils": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-ui>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"URL": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"console.warn": true,
|
||||
"document.body.appendChild": true,
|
||||
"document.createElement": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/key-tree": true,
|
||||
"@metamask/key-tree>@noble/hashes": true,
|
||||
"@metamask/key-tree>@scure/base": true,
|
||||
"@metamask/snaps-utils>@metamask/utils": true,
|
||||
"@metamask/snaps-utils>cron-parser": true,
|
||||
"@metamask/snaps-utils>fast-json-stable-stringify": true,
|
||||
"@metamask/snaps-utils>rfdc": true,
|
||||
"@metamask/snaps-utils>validate-npm-package-name": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>cron-parser": {
|
||||
"packages": {
|
||||
"browserify>browser-resolve": true,
|
||||
"luxon": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>rfdc": {
|
||||
"packages": {
|
||||
"browserify>buffer": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name": {
|
||||
"packages": {
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": true
|
||||
}
|
||||
},
|
||||
"@metamask/snaps-utils>validate-npm-package-name>builtins": {
|
||||
"packages": {
|
||||
"browserify>process": true,
|
||||
"semver": true
|
||||
}
|
||||
},
|
||||
"@metamask/subject-metadata-controller": {
|
||||
"packages": {
|
||||
"@metamask/subject-metadata-controller>@metamask/base-controller": true
|
||||
@ -2169,85 +2280,110 @@
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true,
|
||||
"XMLHttpRequest": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_RELEASE__": true,
|
||||
"indexedDB.open": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry-internal/tracing": true,
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>@sentry/replay": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry-internal/tracing": {
|
||||
"globals": {
|
||||
"Headers": true,
|
||||
"PerformanceObserver": true,
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"addEventListener": true,
|
||||
"performance.getEntriesByType": true,
|
||||
"removeEventListener": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/browser>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core": {
|
||||
"globals": {
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__SENTRY_TRACING__": true,
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"clearTimeout": true,
|
||||
"console.warn": true,
|
||||
"setInterval": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": true,
|
||||
"@sentry/browser>@sentry/core>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": {
|
||||
"@sentry/browser>@sentry/replay": {
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"setInterval": true
|
||||
"Blob": true,
|
||||
"CSSConditionRule": true,
|
||||
"CSSGroupingRule": true,
|
||||
"CSSMediaRule": true,
|
||||
"CSSSupportsRule": true,
|
||||
"DragEvent": true,
|
||||
"Element": true,
|
||||
"FormData": true,
|
||||
"HTMLCanvasElement": true,
|
||||
"HTMLElement.prototype": true,
|
||||
"HTMLFormElement": true,
|
||||
"HTMLImageElement": true,
|
||||
"HTMLInputElement.prototype": true,
|
||||
"HTMLOptionElement.prototype": true,
|
||||
"HTMLSelectElement.prototype": true,
|
||||
"HTMLTextAreaElement.prototype": true,
|
||||
"Headers": true,
|
||||
"ImageData": true,
|
||||
"MouseEvent": true,
|
||||
"MutationObserver": true,
|
||||
"Node.prototype.contains": true,
|
||||
"PerformanceObserver": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"URLSearchParams": true,
|
||||
"Worker": true,
|
||||
"Zone": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"__rrMutationObserver": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"document": true,
|
||||
"innerHeight": true,
|
||||
"innerWidth": true,
|
||||
"location.href": true,
|
||||
"pageXOffset": true,
|
||||
"pageYOffset": true,
|
||||
"requestAnimationFrame": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/hub>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal": {
|
||||
"packages": {
|
||||
"@sentry/browser>@sentry/core>@sentry/hub": true,
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>@sentry/minimal>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>@sentry/core>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/browser>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
"@sentry/browser>@sentry/core": true,
|
||||
"@sentry/utils": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations": {
|
||||
"globals": {
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"console.log": true,
|
||||
"setTimeout": true
|
||||
"Request": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"console.log": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/integrations>tslib": true,
|
||||
"@sentry/types": true,
|
||||
"@sentry/utils": true,
|
||||
"localforage": true
|
||||
}
|
||||
},
|
||||
"@sentry/integrations>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"globals": {
|
||||
"CustomEvent": true,
|
||||
@ -2259,22 +2395,22 @@
|
||||
"Headers": true,
|
||||
"Request": true,
|
||||
"Response": true,
|
||||
"TextEncoder": true,
|
||||
"URL": true,
|
||||
"XMLHttpRequest.prototype": true,
|
||||
"__SENTRY_BROWSER_BUNDLE__": true,
|
||||
"__SENTRY_DEBUG__": true,
|
||||
"clearTimeout": true,
|
||||
"console.error": true,
|
||||
"document": true,
|
||||
"setTimeout": true
|
||||
"new": true,
|
||||
"setTimeout": true,
|
||||
"target": true
|
||||
},
|
||||
"packages": {
|
||||
"@sentry/utils>tslib": true,
|
||||
"browserify>process": true
|
||||
}
|
||||
},
|
||||
"@sentry/utils>tslib": {
|
||||
"globals": {
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"@truffle/codec": {
|
||||
"packages": {
|
||||
"@truffle/codec>@truffle/abi-utils": true,
|
||||
@ -4711,6 +4847,12 @@
|
||||
"string.prototype.matchall>regexp.prototype.flags>functions-have-names": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"globals": {
|
||||
"crypto": true,
|
||||
|
@ -168,9 +168,13 @@
|
||||
},
|
||||
"@babel/eslint-parser": {
|
||||
"builtin": {
|
||||
"path": true
|
||||
"module": true,
|
||||
"path": true,
|
||||
"worker_threads": true
|
||||
},
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"process.cwd": true,
|
||||
"process.versions": true
|
||||
},
|
||||
"packages": {
|
||||
@ -980,7 +984,6 @@
|
||||
"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/addon-mdx-gfm>@storybook/node-logger>npmlog>console-control-strings": true,
|
||||
"@storybook/react>@storybook/node-logger>npmlog>console-control-strings": true,
|
||||
"nyc>yargs>set-blocking": true
|
||||
}
|
||||
@ -1009,9 +1012,6 @@
|
||||
"@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/addon-mdx-gfm>@storybook/node-logger>npmlog>console-control-strings": true,
|
||||
"@storybook/addon-mdx-gfm>@storybook/node-logger>npmlog>gauge>has-unicode": true,
|
||||
"@storybook/addon-mdx-gfm>@storybook/node-logger>npmlog>gauge>wide-align": 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,
|
||||
@ -1049,17 +1049,18 @@
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"__filename.slice": true,
|
||||
"console.warn": true,
|
||||
"process.cwd": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@lavamoat/lavapack>combine-source-map": true,
|
||||
"@lavamoat/lavapack>lavamoat-core": true,
|
||||
"@lavamoat/lavapack>convert-source-map": true,
|
||||
"@lavamoat/lavapack>readable-stream": true,
|
||||
"@lavamoat/lavapack>umd": true,
|
||||
"browserify>JSONStream": true,
|
||||
"lavamoat>json-stable-stringify": true,
|
||||
"nyc>convert-source-map": true,
|
||||
"lavamoat>lavamoat-core": true,
|
||||
"through2": true
|
||||
}
|
||||
},
|
||||
@ -1086,26 +1087,12 @@
|
||||
"@lavamoat/lavapack>combine-source-map>inline-source-map>source-map": true
|
||||
}
|
||||
},
|
||||
"@lavamoat/lavapack>lavamoat-core": {
|
||||
"builtin": {
|
||||
"events": true,
|
||||
"fs.existsSync": true,
|
||||
"fs.readFileSync": true,
|
||||
"fs.writeFileSync": true,
|
||||
"path.extname": true,
|
||||
"path.join": true
|
||||
},
|
||||
"@lavamoat/lavapack>convert-source-map": {
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"console.error": true,
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
},
|
||||
"packages": {
|
||||
"lavamoat>json-stable-stringify": true,
|
||||
"lavamoat>lavamoat-core>merge-deep": true,
|
||||
"lavamoat>lavamoat-tofu": true,
|
||||
"nyc>process-on-spawn>fromentries": true
|
||||
"Buffer": true,
|
||||
"atob": true,
|
||||
"btoa": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"@lavamoat/lavapack>readable-stream": {
|
||||
@ -1149,21 +1136,6 @@
|
||||
"string.prototype.matchall>side-channel": true
|
||||
}
|
||||
},
|
||||
"@storybook/addon-mdx-gfm>@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
|
||||
}
|
||||
},
|
||||
"@storybook/addon-mdx-gfm>@storybook/node-logger>npmlog>gauge>wide-align": {
|
||||
"packages": {
|
||||
"yargs>string-width": true
|
||||
}
|
||||
},
|
||||
"@storybook/core>@storybook/core-server>x-default-browser>default-browser-id>untildify>os-homedir": {
|
||||
"builtin": {
|
||||
"os.homedir": true
|
||||
@ -2884,12 +2856,12 @@
|
||||
"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,
|
||||
"lavamoat>object.fromentries": true,
|
||||
"prop-types": true,
|
||||
"string.prototype.matchall": true
|
||||
}
|
||||
@ -2949,6 +2921,13 @@
|
||||
"string.prototype.matchall>es-abstract": true
|
||||
}
|
||||
},
|
||||
"eslint-plugin-react>object.fromentries": {
|
||||
"packages": {
|
||||
"globalthis>define-properties": true,
|
||||
"string.prototype.matchall>call-bind": true,
|
||||
"string.prototype.matchall>es-abstract": true
|
||||
}
|
||||
},
|
||||
"eslint-plugin-react>object.hasown": {
|
||||
"packages": {
|
||||
"string.prototype.matchall>es-abstract": true
|
||||
@ -3010,6 +2989,9 @@
|
||||
"util": true
|
||||
},
|
||||
"globals": {
|
||||
"__filename": true,
|
||||
"process.cwd": true,
|
||||
"process.emitWarning": true,
|
||||
"process.platform": true
|
||||
},
|
||||
"packages": {
|
||||
@ -4895,20 +4877,9 @@
|
||||
},
|
||||
"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-homedir": true,
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true
|
||||
}
|
||||
},
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": {
|
||||
"builtin": {
|
||||
"os.homedir": true
|
||||
},
|
||||
"globals": {
|
||||
"process.env": true,
|
||||
"process.getuid": true,
|
||||
"process.platform": true
|
||||
}
|
||||
},
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": {
|
||||
"globals": {
|
||||
"process.env.SystemRoot": true,
|
||||
@ -4930,34 +4901,9 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob": true,
|
||||
"nyc>glob": true
|
||||
}
|
||||
},
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>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": {
|
||||
"eslint>minimatch": true,
|
||||
"gulp-watch>path-is-absolute": true,
|
||||
"nyc>glob>fs.realpath": true,
|
||||
"nyc>glob>inflight": true,
|
||||
"pump>once": true,
|
||||
"pumpify>inherits": true
|
||||
}
|
||||
},
|
||||
"gulp-watch>chokidar>fsevents>node-pre-gyp>semver": {
|
||||
"globals": {
|
||||
"console": true,
|
||||
@ -6203,8 +6149,8 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@lavamoat/lavapack": true,
|
||||
"duplexify": true,
|
||||
"lavamoat-browserify>@lavamoat/lavapack": true,
|
||||
"lavamoat-browserify>browser-resolve": true,
|
||||
"lavamoat-browserify>concat-stream": true,
|
||||
"lavamoat-browserify>readable-stream": true,
|
||||
@ -6214,37 +6160,6 @@
|
||||
"lavamoat>lavamoat-core": true
|
||||
}
|
||||
},
|
||||
"lavamoat-browserify>@lavamoat/lavapack": {
|
||||
"builtin": {
|
||||
"assert": true,
|
||||
"buffer.Buffer.from": true,
|
||||
"fs.promises.readFile": true,
|
||||
"fs.promises.writeFile": true,
|
||||
"fs.readFileSync": true,
|
||||
"path.join": true,
|
||||
"path.relative": true
|
||||
},
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"process.cwd": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@lavamoat/lavapack>combine-source-map": true,
|
||||
"@lavamoat/lavapack>umd": true,
|
||||
"browserify>JSONStream": true,
|
||||
"lavamoat-browserify>@lavamoat/lavapack>through2": true,
|
||||
"lavamoat-browserify>readable-stream": true,
|
||||
"lavamoat>json-stable-stringify": true,
|
||||
"lavamoat>lavamoat-core": true,
|
||||
"nyc>convert-source-map": true
|
||||
}
|
||||
},
|
||||
"lavamoat-browserify>@lavamoat/lavapack>through2": {
|
||||
"packages": {
|
||||
"lavamoat-browserify>readable-stream": true
|
||||
}
|
||||
},
|
||||
"lavamoat-browserify>browser-resolve": {
|
||||
"builtin": {
|
||||
"fs.readFile": true,
|
||||
@ -6381,8 +6296,7 @@
|
||||
"packages": {
|
||||
"lavamoat>json-stable-stringify": true,
|
||||
"lavamoat>lavamoat-core>merge-deep": true,
|
||||
"lavamoat>lavamoat-tofu": true,
|
||||
"nyc>process-on-spawn>fromentries": true
|
||||
"lavamoat>lavamoat-tofu": true
|
||||
}
|
||||
},
|
||||
"lavamoat>lavamoat-core>merge-deep": {
|
||||
@ -6458,13 +6372,6 @@
|
||||
"depcheck>@babel/traverse": true
|
||||
}
|
||||
},
|
||||
"lavamoat>object.fromentries": {
|
||||
"packages": {
|
||||
"globalthis>define-properties": true,
|
||||
"string.prototype.matchall>call-bind": true,
|
||||
"string.prototype.matchall>es-abstract": true
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"globals": {
|
||||
"define": true
|
||||
@ -8678,6 +8585,12 @@
|
||||
"jsdom>request>is-typedarray": true
|
||||
}
|
||||
},
|
||||
"superstruct": {
|
||||
"globals": {
|
||||
"console.warn": true,
|
||||
"define": true
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"globals": {
|
||||
"Buffer": true,
|
||||
@ -9036,6 +8949,7 @@
|
||||
},
|
||||
"globals": {
|
||||
"Error": true,
|
||||
"__dirname": true,
|
||||
"console": true,
|
||||
"process": true
|
||||
},
|
||||
@ -9050,6 +8964,9 @@
|
||||
}
|
||||
},
|
||||
"yargs>cliui": {
|
||||
"globals": {
|
||||
"process": true
|
||||
},
|
||||
"packages": {
|
||||
"eslint>strip-ansi": true,
|
||||
"yargs>cliui>wrap-ansi": true,
|
||||
|
41
package.json
41
package.json
@ -95,7 +95,6 @@
|
||||
"fitness-functions": "ts-node development/fitness-functions/index.ts",
|
||||
"generate-beta-commit": "node ./development/generate-beta-commit.js",
|
||||
"validate-branch-name": "validate-branch-name",
|
||||
"label-prs": "ts-node ./.github/scripts/label-prs.ts",
|
||||
"add-release-label-to-pr-and-linked-issues": "ts-node ./.github/scripts/add-release-label-to-pr-and-linked-issues.ts"
|
||||
},
|
||||
"resolutions": {
|
||||
@ -226,11 +225,11 @@
|
||||
"@metamask/address-book-controller": "^3.0.0",
|
||||
"@metamask/announcement-controller": "^4.0.0",
|
||||
"@metamask/approval-controller": "^3.1.0",
|
||||
"@metamask/assets-controllers": "^9.1.0",
|
||||
"@metamask/assets-controllers": "^9.2.0",
|
||||
"@metamask/base-controller": "^3.0.0",
|
||||
"@metamask/browser-passworder": "^4.1.0",
|
||||
"@metamask/contract-metadata": "^2.3.1",
|
||||
"@metamask/controller-utils": "^4.0.0",
|
||||
"@metamask/controller-utils": "^4.0.1",
|
||||
"@metamask/design-tokens": "^1.9.0",
|
||||
"@metamask/desktop": "^0.3.0",
|
||||
"@metamask/eth-json-rpc-middleware": "^11.0.0",
|
||||
@ -251,31 +250,31 @@
|
||||
"@metamask/permission-controller": "^4.0.0",
|
||||
"@metamask/phishing-controller": "^3.0.0",
|
||||
"@metamask/post-message-stream": "^6.0.0",
|
||||
"@metamask/providers": "^10.2.1",
|
||||
"@metamask/providers": "^11.1.0",
|
||||
"@metamask/rate-limit-controller": "^3.0.0",
|
||||
"@metamask/rpc-methods": "^0.32.2",
|
||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1",
|
||||
"@metamask/rpc-methods": "^1.0.0-prerelease.1",
|
||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.35.2-flask.1",
|
||||
"@metamask/safe-event-emitter": "^2.0.0",
|
||||
"@metamask/scure-bip39": "^2.0.3",
|
||||
"@metamask/signature-controller": "^4.0.1",
|
||||
"@metamask/slip44": "^3.0.0",
|
||||
"@metamask/smart-transactions-controller": "^3.1.0",
|
||||
"@metamask/snaps-controllers": "^0.32.2",
|
||||
"@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.34.0-flask.1",
|
||||
"@metamask/snaps-ui": "^0.32.2",
|
||||
"@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.34.0-flask.1",
|
||||
"@metamask/snaps-utils": "^0.32.2",
|
||||
"@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.34.0-flask.1",
|
||||
"@metamask/snaps-controllers": "^1.0.0-prerelease.1",
|
||||
"@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.35.2-flask.1",
|
||||
"@metamask/snaps-ui": "^1.0.0-prerelease.1",
|
||||
"@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.35.2-flask.1",
|
||||
"@metamask/snaps-utils": "^1.0.0-prerelease.1",
|
||||
"@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.35.2-flask.1",
|
||||
"@metamask/subject-metadata-controller": "^2.0.0",
|
||||
"@metamask/utils": "^5.0.0",
|
||||
"@ngraveio/bc-ur": "^1.1.6",
|
||||
"@popperjs/core": "^2.4.0",
|
||||
"@reduxjs/toolkit": "^1.6.2",
|
||||
"@segment/loosely-validate-event": "^2.0.0",
|
||||
"@sentry/browser": "^6.0.0",
|
||||
"@sentry/integrations": "^6.0.0",
|
||||
"@sentry/types": "^6.0.1",
|
||||
"@sentry/utils": "^6.0.1",
|
||||
"@sentry/browser": "^7.53.0",
|
||||
"@sentry/integrations": "^7.53.0",
|
||||
"@sentry/types": "^7.53.0",
|
||||
"@sentry/utils": "^7.53.0",
|
||||
"@truffle/codec": "^0.14.12",
|
||||
"@truffle/decoder": "^5.3.5",
|
||||
"@zxing/browser": "^0.0.10",
|
||||
@ -371,7 +370,7 @@
|
||||
"@babel/register": "^7.5.5",
|
||||
"@ethersproject/bignumber": "^5.7.0",
|
||||
"@lavamoat/allow-scripts": "^2.0.3",
|
||||
"@lavamoat/lavapack": "^5.0.0",
|
||||
"@lavamoat/lavapack": "^5.2.0",
|
||||
"@metamask/auto-changelog": "^2.1.0",
|
||||
"@metamask/eslint-config": "^9.0.0",
|
||||
"@metamask/eslint-config-jest": "^9.0.0",
|
||||
@ -380,7 +379,7 @@
|
||||
"@metamask/eslint-config-typescript": "^9.0.1",
|
||||
"@metamask/forwarder": "^1.1.0",
|
||||
"@metamask/phishing-warning": "^2.1.0",
|
||||
"@metamask/test-dapp": "^7.0.0",
|
||||
"@metamask/test-dapp": "^7.0.1",
|
||||
"@sentry/cli": "^1.58.0",
|
||||
"@storybook/addon-a11y": "^7.0.11",
|
||||
"@storybook/addon-actions": "^7.0.11",
|
||||
@ -466,7 +465,7 @@
|
||||
"fast-glob": "^3.2.2",
|
||||
"fs-extra": "^8.1.0",
|
||||
"ganache": "^v7.0.4",
|
||||
"geckodriver": "^3.2.0",
|
||||
"geckodriver": "^4.0.4",
|
||||
"gh-pages": "^5.0.0",
|
||||
"globby": "^11.0.4",
|
||||
"gulp": "^4.0.2",
|
||||
@ -494,8 +493,8 @@
|
||||
"jsdom": "^11.2.0",
|
||||
"junit-report-merger": "^4.0.0",
|
||||
"koa": "^2.7.0",
|
||||
"lavamoat": "^6.3.0",
|
||||
"lavamoat-browserify": "^15.5.0",
|
||||
"lavamoat": "^7.1.0",
|
||||
"lavamoat-browserify": "^15.7.0",
|
||||
"lavamoat-viz": "^6.0.9",
|
||||
"lockfile-lint": "^4.9.6",
|
||||
"loose-envify": "^1.4.0",
|
||||
|
13
shared/constants/security-provider.ts
Normal file
13
shared/constants/security-provider.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @typedef {object} SecurityProviderMessageSeverity
|
||||
* @property {0} NOT_MALICIOUS - Indicates message is not malicious
|
||||
* @property {1} MALICIOUS - Indicates message is malicious
|
||||
* @property {2} NOT_SAFE - Indicates message is not safe
|
||||
*/
|
||||
|
||||
/** @type {SecurityProviderMessageSeverity} */
|
||||
export const SECURITY_PROVIDER_MESSAGE_SEVERITY = {
|
||||
NOT_MALICIOUS: 0,
|
||||
MALICIOUS: 1,
|
||||
NOT_SAFE: 2,
|
||||
};
|
@ -12,14 +12,19 @@ export const EndowmentPermissions = Object.freeze({
|
||||
|
||||
// Methods / permissions in external packages that we are temporarily excluding.
|
||||
export const ExcludedSnapPermissions = Object.freeze({
|
||||
// TODO: Enable in Flask
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-flask)
|
||||
snap_manageAccounts:
|
||||
'This permission is still in development and therefore not available.',
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
eth_accounts:
|
||||
'eth_accounts is disabled. For more information please see https://github.com/MetaMask/snaps-monorepo/issues/990.',
|
||||
});
|
||||
|
||||
export const ExcludedSnapEndowments = Object.freeze({
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main)
|
||||
'endowment:keyring':
|
||||
'This endowment is still in development therefore not available.',
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main)
|
||||
'endowment:long-running':
|
||||
'endowment:long-running is deprecated. For more information please see https://github.com/MetaMask/snaps-monorepo/issues/945.',
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
30
shared/modules/security-provider.utils.test.ts
Normal file
30
shared/modules/security-provider.utils.test.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITY } from '../constants/security-provider';
|
||||
import { isSuspiciousResponse } from './security-provider.utils';
|
||||
|
||||
describe('security-provider util', () => {
|
||||
describe('isSuspiciousResponse', () => {
|
||||
it('should return false if the response does not exist', () => {
|
||||
const result = isSuspiciousResponse(undefined);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return false when flagAsDangerous exists and is not malicious', () => {
|
||||
const result = isSuspiciousResponse({
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITY.NOT_MALICIOUS,
|
||||
});
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true when flagAsDangerous exists and is malicious or not safe', () => {
|
||||
const result = isSuspiciousResponse({
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITY.NOT_SAFE,
|
||||
});
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return true if the response exists but is empty', () => {
|
||||
const result = isSuspiciousResponse({});
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
19
shared/modules/security-provider.utils.ts
Normal file
19
shared/modules/security-provider.utils.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Json } from '@metamask/utils';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITY } from '../constants/security-provider';
|
||||
|
||||
export function isSuspiciousResponse(
|
||||
securityProviderResponse: Record<string, Json> | undefined,
|
||||
): boolean {
|
||||
if (!securityProviderResponse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isFlagged =
|
||||
securityProviderResponse.flagAsDangerous !== undefined &&
|
||||
securityProviderResponse.flagAsDangerous !==
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITY.NOT_MALICIOUS;
|
||||
|
||||
const isNotVerified = Object.keys(securityProviderResponse).length === 0;
|
||||
|
||||
return isFlagged || isNotVerified;
|
||||
}
|
35
shared/notifications/institutional/index.js
Normal file
35
shared/notifications/institutional/index.js
Normal file
@ -0,0 +1,35 @@
|
||||
export const UI_INSTITUTIONAL_NOTIFICATIONS = {
|
||||
1: {
|
||||
id: 11,
|
||||
date: '2022-08-28',
|
||||
image: {
|
||||
src: 'images/portfolio.svg',
|
||||
},
|
||||
hideDate: true,
|
||||
descriptionInBullets: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const getTranslatedInstitutionalUINotifications = (t, locale) => {
|
||||
const formattedLocale = locale.replace('_', '-');
|
||||
return {
|
||||
1: {
|
||||
...UI_INSTITUTIONAL_NOTIFICATIONS[11],
|
||||
title: 'Portfolio dashboard',
|
||||
description: [
|
||||
'Portfolio snapshots',
|
||||
'Filtering by account and network',
|
||||
'Sector and protocol allocation',
|
||||
'Improved navigation',
|
||||
],
|
||||
date: new Intl.DateTimeFormat(formattedLocale).format(
|
||||
new Date(UI_INSTITUTIONAL_NOTIFICATIONS[11].date),
|
||||
),
|
||||
customButton: {
|
||||
name: 'mmi-portfolio',
|
||||
text: t('viewPortfolioDashboard'),
|
||||
logo: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
@ -674,6 +674,19 @@ async function terminateServiceWorker(driver) {
|
||||
await driver.closeWindowHandle(serviceWorkerTab);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method assumes the extension is open, the dapp is open and waits for a
|
||||
* third window handle to open (the notification window). Once it does it
|
||||
* switches to the new window.
|
||||
*
|
||||
* @param {WebDriver} driver
|
||||
*/
|
||||
async function switchToNotificationWindow(driver) {
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('MetaMask Notification', windowHandles);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
DAPP_URL,
|
||||
DAPP_ONE_URL,
|
||||
@ -720,4 +733,5 @@ module.exports = {
|
||||
switchToWindow,
|
||||
sleepSeconds,
|
||||
terminateServiceWorker,
|
||||
switchToNotificationWindow,
|
||||
};
|
||||
|
121
test/e2e/metrics/permissions-approved.spec.js
Normal file
121
test/e2e/metrics/permissions-approved.spec.js
Normal file
@ -0,0 +1,121 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const {
|
||||
defaultGanacheOptions,
|
||||
switchToNotificationWindow,
|
||||
withFixtures,
|
||||
openDapp,
|
||||
unlockWallet,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
/**
|
||||
* mocks the segment api multiple times for specific payloads that we expect to
|
||||
* see when these tests are run. In this case we are looking for
|
||||
* 'Permissions Requested' and 'Permissions Received'. Do not use the constants
|
||||
* from the metrics constants files, because if these change we want a strong
|
||||
* indicator to our data team that the shape of data will change.
|
||||
*
|
||||
* @param {import('mockttp').Mockttp} mockServer
|
||||
* @returns {Promise<import('mockttp/dist/pluggable-admin').MockttpClientResponse>[]}
|
||||
*/
|
||||
async function mockSegment(mockServer) {
|
||||
return [
|
||||
await mockServer
|
||||
.forPost('https://api.segment.io/v1/batch')
|
||||
.withJsonBodyIncluding({
|
||||
batch: [{ type: 'track', event: 'Permissions Requested' }],
|
||||
})
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
}),
|
||||
await mockServer
|
||||
.forPost('https://api.segment.io/v1/batch')
|
||||
.withJsonBodyIncluding({
|
||||
batch: [{ type: 'track', event: 'Permissions Approved' }],
|
||||
})
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles getting the mocked requests to the segment server
|
||||
*
|
||||
* @param {WebDriver} driver
|
||||
* @param {import('mockttp').Mockttp} mockedEndpoints
|
||||
* @returns {import('mockttp/dist/pluggable-admin').MockttpClientResponse[]}
|
||||
*/
|
||||
async function getEventPayloads(driver, mockedEndpoints) {
|
||||
await driver.wait(async () => {
|
||||
let isPending = true;
|
||||
for (const mockedEndpoint of mockedEndpoints) {
|
||||
isPending = await mockedEndpoint.isPending();
|
||||
}
|
||||
return isPending === false;
|
||||
}, 10000);
|
||||
const mockedRequests = [];
|
||||
for (const mockedEndpoint of mockedEndpoints) {
|
||||
mockedRequests.push(...(await mockedEndpoint.getSeenRequests()));
|
||||
}
|
||||
return mockedRequests.map((req) => req.body.json.batch).flat();
|
||||
}
|
||||
|
||||
describe('Permissions Approved Event', function () {
|
||||
it('Successfully tracked when connecting to dapp', async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withMetaMetricsController({
|
||||
metaMetricsId: 'fake-metrics-id',
|
||||
participateInMetaMetrics: true,
|
||||
})
|
||||
.build(),
|
||||
defaultGanacheOptions,
|
||||
title: this.test.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
await driver.clickElement({
|
||||
text: 'Connect',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
await switchToNotificationWindow(driver);
|
||||
await driver.clickElement({
|
||||
text: 'Next',
|
||||
tag: 'button',
|
||||
});
|
||||
await driver.clickElement({
|
||||
text: 'Connect',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
method: 'eth_requestAccounts',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
method: 'eth_requestAccounts',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
323
test/e2e/metrics/signature-approved.spec.js
Normal file
323
test/e2e/metrics/signature-approved.spec.js
Normal file
@ -0,0 +1,323 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const {
|
||||
defaultGanacheOptions,
|
||||
switchToNotificationWindow,
|
||||
withFixtures,
|
||||
regularDelayMs,
|
||||
openDapp,
|
||||
unlockWallet,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
/**
|
||||
* mocks the segment api multiple times for specific payloads that we expect to
|
||||
* see when these tests are run. In this case we are looking for
|
||||
* 'Signature Requested' and 'Signature Received'. Do not use the constants
|
||||
* from the metrics constants files, because if these change we want a strong
|
||||
* indicator to our data team that the shape of data will change.
|
||||
*
|
||||
* @param {import('mockttp').Mockttp} mockServer
|
||||
* @returns {Promise<import('mockttp/dist/pluggable-admin').MockttpClientResponse>[]}
|
||||
*/
|
||||
async function mockSegment(mockServer) {
|
||||
return [
|
||||
await mockServer
|
||||
.forPost('https://api.segment.io/v1/batch')
|
||||
.withJsonBodyIncluding({
|
||||
batch: [{ type: 'track', event: 'Signature Requested' }],
|
||||
})
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
}),
|
||||
await mockServer
|
||||
.forPost('https://api.segment.io/v1/batch')
|
||||
.withJsonBodyIncluding({
|
||||
batch: [{ type: 'track', event: 'Signature Approved' }],
|
||||
})
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some signing methods have extra security that requires the user to click a
|
||||
* button to validate that they have verified the details. This method handles
|
||||
* performing the necessary steps to click that button.
|
||||
*
|
||||
* @param {WebDriver} driver
|
||||
*/
|
||||
async function validateContractDetails(driver) {
|
||||
const verifyContractDetailsButton = await driver.findElement(
|
||||
'.signature-request-content__verify-contract-details',
|
||||
);
|
||||
|
||||
verifyContractDetailsButton.click();
|
||||
await driver.clickElement({ text: 'Got it', tag: 'button' });
|
||||
|
||||
// Approve signing typed data
|
||||
await driver.clickElement('[data-testid="signature-request-scroll-button"]');
|
||||
await driver.delay(regularDelayMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles clicking the sign button on signature confrimation
|
||||
* screen.
|
||||
*
|
||||
* @param {WebDriver} driver
|
||||
*/
|
||||
async function clickSignOnSignatureConfirmation(driver) {
|
||||
await driver.clickElement({ text: 'Sign', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
await driver.getAllWindowHandles();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles getting the mocked requests to the segment server
|
||||
*
|
||||
* @param {WebDriver} driver
|
||||
* @param {import('mockttp').Mockttp} mockedEndpoints
|
||||
* @returns {import('mockttp/dist/pluggable-admin').MockttpClientResponse[]}
|
||||
*/
|
||||
async function getEventPayloads(driver, mockedEndpoints) {
|
||||
await driver.wait(async () => {
|
||||
let isPending = true;
|
||||
for (const mockedEndpoint of mockedEndpoints) {
|
||||
isPending = await mockedEndpoint.isPending();
|
||||
}
|
||||
return isPending === false;
|
||||
}, 10000);
|
||||
const mockedRequests = [];
|
||||
for (const mockedEndpoint of mockedEndpoints) {
|
||||
mockedRequests.push(...(await mockedEndpoint.getSeenRequests()));
|
||||
}
|
||||
return mockedRequests.map((req) => req.body.json.batch).flat();
|
||||
}
|
||||
|
||||
describe('Signature Approved Event', 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.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedDataV4');
|
||||
await switchToNotificationWindow(driver);
|
||||
await validateContractDetails(driver);
|
||||
await clickSignOnSignatureConfirmation(driver);
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
signature_type: 'eth_signTypedData_v4',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
signature_type: 'eth_signTypedData_v4',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
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.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedDataV3');
|
||||
await switchToNotificationWindow(driver);
|
||||
await validateContractDetails(driver);
|
||||
await clickSignOnSignatureConfirmation(driver);
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
signature_type: 'eth_signTypedData_v3',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
signature_type: 'eth_signTypedData_v3',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
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.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedData');
|
||||
await switchToNotificationWindow(driver);
|
||||
await clickSignOnSignatureConfirmation(driver);
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
signature_type: 'eth_signTypedData',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
signature_type: 'eth_signTypedData',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
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.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#personalSign');
|
||||
await switchToNotificationWindow(driver);
|
||||
await clickSignOnSignatureConfirmation(driver);
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
signature_type: 'personal_sign',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
signature_type: 'personal_sign',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
it('Successfully tracked for eth_sign', async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.withPreferencesController({
|
||||
disabledRpcMethodPreferences: {
|
||||
eth_sign: true,
|
||||
},
|
||||
})
|
||||
.withMetaMetricsController({
|
||||
metaMetricsId: 'fake-metrics-id',
|
||||
participateInMetaMetrics: true,
|
||||
})
|
||||
.build(),
|
||||
defaultGanacheOptions,
|
||||
title: this.test.title,
|
||||
testSpecificMock: mockSegment,
|
||||
},
|
||||
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
|
||||
await driver.navigate();
|
||||
await unlockWallet(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#ethSign');
|
||||
await switchToNotificationWindow(driver);
|
||||
await driver.delay(regularDelayMs);
|
||||
await driver.clickElement('[data-testid="page-container-footer-next"]');
|
||||
await driver.clickElement(
|
||||
'.signature-request-warning__footer__sign-button',
|
||||
);
|
||||
const events = await getEventPayloads(driver, mockedEndpoints);
|
||||
assert.deepStrictEqual(events[0].properties, {
|
||||
signature_type: 'eth_sign',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
assert.deepStrictEqual(events[1].properties, {
|
||||
signature_type: 'eth_sign',
|
||||
category: 'inpage_provider',
|
||||
locale: 'en',
|
||||
chain_id: '0x539',
|
||||
environment_type: 'background',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
@ -35,7 +35,7 @@ describe('Import ERC1155 NFT', function () {
|
||||
|
||||
// After login, go to NFTs tab, open the import NFT/ERC1155 form
|
||||
await driver.clickElement('[data-testid="home__nfts-tab"]');
|
||||
await driver.clickElement({ text: 'Import NFTs', tag: 'a' });
|
||||
await driver.clickElement({ text: 'Import NFT', tag: 'button' });
|
||||
|
||||
// Enter a valid NFT that belongs to user and check success message appears
|
||||
await driver.fill('[data-testid="address"]', contractAddress);
|
||||
@ -83,7 +83,7 @@ describe('Import ERC1155 NFT', function () {
|
||||
|
||||
// After login, go to NFTs tab, open the import NFT form
|
||||
await driver.clickElement('[data-testid="home__nfts-tab"]');
|
||||
await driver.clickElement({ text: 'Import NFTs', tag: 'a' });
|
||||
await driver.clickElement({ text: 'Import NFT', tag: 'button' });
|
||||
|
||||
// Enter an NFT that not belongs to user with a valid address and an invalid token id
|
||||
await driver.fill('[data-testid="address"]', contractAddress);
|
||||
|
@ -35,7 +35,7 @@ describe('Import NFT', function () {
|
||||
|
||||
// After login, go to NFTs tab, open the import NFT form
|
||||
await driver.clickElement('[data-testid="home__nfts-tab"]');
|
||||
await driver.clickElement({ text: 'Import NFTs', tag: 'a' });
|
||||
await driver.clickElement({ text: 'Import NFT', tag: 'button' });
|
||||
|
||||
// Enter a valid NFT that belongs to user and check success message appears
|
||||
await driver.fill('[data-testid="address"]', contractAddress);
|
||||
@ -82,7 +82,7 @@ describe('Import NFT', function () {
|
||||
|
||||
// After login, go to NFTs tab, open the import NFT form
|
||||
await driver.clickElement('[data-testid="home__nfts-tab"]');
|
||||
await driver.clickElement({ text: 'Import NFTs', tag: 'a' });
|
||||
await driver.clickElement({ text: 'Import NFT', tag: 'button' });
|
||||
|
||||
// Enter an NFT that not belongs to user with a valid address and an invalid token id
|
||||
await driver.fill('[data-testid="address"]', contractAddress);
|
||||
|
@ -72,6 +72,7 @@ async function main() {
|
||||
...(await getTestPathsForTestDir(testDir)),
|
||||
...(await getTestPathsForTestDir(path.join(__dirname, 'swaps'))),
|
||||
...(await getTestPathsForTestDir(path.join(__dirname, 'nft'))),
|
||||
...(await getTestPathsForTestDir(path.join(__dirname, 'metrics'))),
|
||||
path.join(__dirname, 'metamask-ui.spec.js'),
|
||||
];
|
||||
|
||||
|
@ -171,7 +171,7 @@ describe('Address Book', function () {
|
||||
|
||||
await driver.clickElement({ text: 'Test Name 1', tag: 'p' });
|
||||
await driver.clickElement({ text: 'Edit', tag: 'button' });
|
||||
await driver.clickElement({ text: 'Delete account', tag: 'a' });
|
||||
await driver.clickElement({ text: 'Delete contact', tag: 'a' });
|
||||
// it checks if account is deleted
|
||||
const contact = await driver.findElement(
|
||||
'.send__select-recipient-wrapper__group-item',
|
||||
|
@ -2,6 +2,59 @@ const { strict: assert } = require('assert');
|
||||
const { convertToHexValue, withFixtures, openDapp } = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
async function getEncryptionKey(driver) {
|
||||
await driver.clickElement('#getEncryptionKeyButton');
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('MetaMask Notification', windowHandles);
|
||||
await driver.waitForSelector({
|
||||
css: '.request-encryption-public-key__header__text',
|
||||
text: 'Request encryption public key',
|
||||
});
|
||||
await driver.clickElement({ text: 'Provide', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
return await driver.findElement('#encryptionKeyDisplay');
|
||||
}
|
||||
|
||||
async function encryptMessage(driver, message) {
|
||||
await driver.fill('#encryptMessageInput', message);
|
||||
await driver.clickElement('#encryptButton');
|
||||
await driver.waitForSelector({
|
||||
css: '#ciphertextDisplay',
|
||||
text: '0x',
|
||||
});
|
||||
}
|
||||
|
||||
async function decryptMessage(driver) {
|
||||
await driver.clickElement('#decryptButton');
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('MetaMask Notification', windowHandles);
|
||||
await driver.waitForSelector({
|
||||
css: '.request-decrypt-message__header__text',
|
||||
text: 'Decrypt request',
|
||||
});
|
||||
}
|
||||
|
||||
async function verifyDecryptedMessageMM(driver, message) {
|
||||
await driver.clickElement({ text: 'Decrypt message', tag: 'div' });
|
||||
const notificationMessage = await driver.isElementPresent({
|
||||
text: message,
|
||||
tag: 'div',
|
||||
});
|
||||
assert.equal(notificationMessage, true);
|
||||
await driver.clickElement({ text: 'Decrypt', tag: 'button' });
|
||||
}
|
||||
|
||||
async function verifyDecryptedMessageDapp(driver, message) {
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
const clearTextLabel = await driver.findElement('#cleartextDisplay');
|
||||
assert.equal(await clearTextLabel.getText(), message);
|
||||
}
|
||||
|
||||
describe('Encrypt Decrypt', function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
@ -31,66 +84,85 @@ describe('Encrypt Decrypt', function () {
|
||||
await openDapp(driver);
|
||||
|
||||
// ------ Get Encryption key ------
|
||||
await driver.clickElement('#getEncryptionKeyButton');
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
await driver.waitForSelector({
|
||||
css: '.request-encryption-public-key__header__text',
|
||||
text: 'Request encryption public key',
|
||||
});
|
||||
await driver.clickElement({ text: 'Provide', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
const encryptionKeyLabel = await driver.findElement(
|
||||
'#encryptionKeyDisplay',
|
||||
);
|
||||
const encryptionKeyLabel = await getEncryptionKey(driver);
|
||||
assert.equal(await encryptionKeyLabel.getText(), encryptionKey);
|
||||
|
||||
// ------ Encrypt ------
|
||||
await driver.fill('#encryptMessageInput', message);
|
||||
await driver.clickElement('#encryptButton');
|
||||
await driver.waitForSelector({
|
||||
css: '#ciphertextDisplay',
|
||||
text: '0x',
|
||||
});
|
||||
await encryptMessage(driver, message);
|
||||
|
||||
// ------ Decrypt ------
|
||||
await driver.clickElement('#decryptButton');
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
await driver.waitForSelector({
|
||||
css: '.request-decrypt-message__header__text',
|
||||
text: 'Decrypt request',
|
||||
});
|
||||
await decryptMessage(driver);
|
||||
|
||||
// Account balance is converted properly
|
||||
const decryptAccountBalanceLabel = await driver.findElement(
|
||||
'.request-decrypt-message__balance-value',
|
||||
);
|
||||
assert.equal(await decryptAccountBalanceLabel.getText(), '25 ETH');
|
||||
// Verify message in MetaMask Notification
|
||||
await driver.clickElement({ text: 'Decrypt message', tag: 'div' });
|
||||
const notificationMessage = await driver.isElementPresent({
|
||||
text: message,
|
||||
tag: 'div',
|
||||
});
|
||||
assert.equal(notificationMessage, true);
|
||||
await driver.clickElement({ text: 'Decrypt', tag: 'button' });
|
||||
await verifyDecryptedMessageMM(driver, message);
|
||||
|
||||
// Verify message in Test Dapp
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await verifyDecryptedMessageDapp(driver, message);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should encrypt and decrypt multiple messages', async function () {
|
||||
const message2 = 'Hello, Alice!';
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver }) => {
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
await openDapp(driver);
|
||||
|
||||
// ------ Get Encryption key ------
|
||||
const encryptionKeyLabel = await getEncryptionKey(driver);
|
||||
assert.equal(await encryptionKeyLabel.getText(), encryptionKey);
|
||||
|
||||
// ------ Encrypt Message 1------
|
||||
await encryptMessage(driver, message);
|
||||
|
||||
// ------ Decrypt Message 1 ------
|
||||
await decryptMessage(driver);
|
||||
|
||||
// ------ Switch to Dapp ------
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
const clearTextLabel = await driver.findElement('#cleartextDisplay');
|
||||
assert.equal(await clearTextLabel.getText(), message);
|
||||
|
||||
// ------ Encrypt Message 2------
|
||||
await encryptMessage(driver, message2);
|
||||
|
||||
// ------ Decrypt Message 2 ------
|
||||
await decryptMessage(driver);
|
||||
|
||||
// Verify message 1 in MetaMask Notification
|
||||
await verifyDecryptedMessageMM(driver, message);
|
||||
|
||||
// Verify message 1 in Test Dapp
|
||||
await verifyDecryptedMessageDapp(driver, message);
|
||||
|
||||
// ------ Switch to Dapp ------
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
// Verify message 2 in MetaMask Notification
|
||||
await verifyDecryptedMessageMM(driver, message2);
|
||||
|
||||
// Verify message 2 in Test Dapp
|
||||
await verifyDecryptedMessageDapp(driver, message2);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -5,7 +5,8 @@ const FixtureBuilder = require('../fixture-builder');
|
||||
describe('Sentry errors', function () {
|
||||
async function mockSentry(mockServer) {
|
||||
return await mockServer
|
||||
.forPost('https://sentry.io/api/0000000/store/')
|
||||
.forPost('https://sentry.io/api/0000000/envelope/')
|
||||
.withBodyIncluding('Test Error')
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
@ -48,7 +49,8 @@ describe('Sentry errors', function () {
|
||||
return isPending === false;
|
||||
}, 10000);
|
||||
const [mockedRequest] = await mockedEndpoint.getSeenRequests();
|
||||
const mockJsonBody = mockedRequest.body.json;
|
||||
const mockTextBody = mockedRequest.body.text.split('\n');
|
||||
const mockJsonBody = JSON.parse(mockTextBody[2]);
|
||||
const { level, extra } = mockJsonBody;
|
||||
const [{ type, value }] = mockJsonBody.exception.values;
|
||||
const { participateInMetaMetrics } = extra.appState.store.metamask;
|
||||
|
@ -5,6 +5,7 @@ const {
|
||||
DAPP_URL,
|
||||
defaultGanacheOptions,
|
||||
unlockWallet,
|
||||
regularDelayMs,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
@ -36,7 +37,7 @@ describe('Eth sign', function () {
|
||||
});
|
||||
|
||||
it('can initiate and confirm a eth sign', async function () {
|
||||
const expectedPersonalMessage =
|
||||
const expectedEthSignMessage =
|
||||
'0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0';
|
||||
const expectedEthSignResult =
|
||||
'"0x816ab6c5d5356548cc4e004ef35a37fdfab916742a2bbeda756cd064c3d3789a6557d41d49549be1de249e1937a8d048996dfcc70d0552111605dc7cc471e8531b"';
|
||||
@ -69,23 +70,11 @@ describe('Eth sign', function () {
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
await driver.findElement({
|
||||
css: '.request-signature__content__title',
|
||||
text: 'Signature request',
|
||||
});
|
||||
await verifyAndAssertEthSign(driver, DAPP_URL, expectedEthSignMessage);
|
||||
|
||||
await driver.findElement({
|
||||
css: '.request-signature__origin',
|
||||
text: DAPP_URL,
|
||||
});
|
||||
|
||||
await driver.findElement({
|
||||
css: '.request-signature__row-value',
|
||||
text: expectedPersonalMessage,
|
||||
});
|
||||
|
||||
await driver.clickElement('[data-testid="page-container-footer-next"]');
|
||||
await driver.clickElement(
|
||||
await approveEthSign(
|
||||
driver,
|
||||
'[data-testid="page-container-footer-next"]',
|
||||
'.signature-request-warning__footer__sign-button',
|
||||
);
|
||||
// Switch to the Dapp
|
||||
@ -101,4 +90,103 @@ describe('Eth sign', function () {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('can queue multiple eth sign and confirm', async function () {
|
||||
const expectedEthSignMessage =
|
||||
'0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0';
|
||||
const expectedEthSignResult =
|
||||
'"0x816ab6c5d5356548cc4e004ef35a37fdfab916742a2bbeda756cd064c3d3789a6557d41d49549be1de249e1937a8d048996dfcc70d0552111605dc7cc471e8531b"';
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPreferencesController({
|
||||
disabledRpcMethodPreferences: {
|
||||
eth_sign: true,
|
||||
},
|
||||
})
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions: defaultGanacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver }) => {
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
// Create eth sign
|
||||
await driver.clickElement('#ethSign');
|
||||
|
||||
// Wait for Signature request popup
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
|
||||
// Switch to Dapp
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
|
||||
// Create second eth sign
|
||||
await driver.clickElement('#ethSign');
|
||||
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
await driver.waitForSelector({
|
||||
text: 'Reject 2 requests',
|
||||
tag: 'a',
|
||||
});
|
||||
|
||||
await verifyAndAssertEthSign(driver, DAPP_URL, expectedEthSignMessage);
|
||||
|
||||
// Confirm first eth sign
|
||||
await approveEthSign(
|
||||
driver,
|
||||
'[data-testid="page-container-footer-next"]',
|
||||
'.signature-request-warning__footer__sign-button',
|
||||
);
|
||||
|
||||
// Confirm second eth sign
|
||||
await approveEthSign(
|
||||
driver,
|
||||
'[data-testid="page-container-footer-next"]',
|
||||
'.signature-request-warning__footer__sign-button',
|
||||
);
|
||||
|
||||
// Switch to the Dapp
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
|
||||
// Verify last confirmed request
|
||||
const result = await driver.findElement('#ethSignResult');
|
||||
assert.equal(await result.getText(), expectedEthSignResult);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
async function verifyAndAssertEthSign(driver, dappUrl, expectedMessage) {
|
||||
await driver.findElement({
|
||||
css: '.request-signature__content__title',
|
||||
text: 'Signature request',
|
||||
});
|
||||
|
||||
await driver.findElement({
|
||||
css: '.request-signature__origin',
|
||||
text: dappUrl,
|
||||
});
|
||||
|
||||
await driver.findElement({
|
||||
css: '.request-signature__row-value',
|
||||
text: expectedMessage,
|
||||
});
|
||||
}
|
||||
|
||||
async function approveEthSign(driver, buttonTestId, signButtonClass) {
|
||||
await driver.clickElement(buttonTestId);
|
||||
await driver.clickElement(signButtonClass);
|
||||
await driver.delay(regularDelayMs);
|
||||
}
|
||||
|
171
test/e2e/tests/gas-estimates.spec.js
Normal file
171
test/e2e/tests/gas-estimates.spec.js
Normal file
@ -0,0 +1,171 @@
|
||||
const {
|
||||
convertToHexValue,
|
||||
withFixtures,
|
||||
logInWithBalanceValidation,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
describe('Gas estimates generated by MetaMask', function () {
|
||||
const baseGanacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
const preLondonGanacheOptions = {
|
||||
...baseGanacheOptions,
|
||||
hardfork: 'berlin',
|
||||
};
|
||||
const postLondonGanacheOptions = {
|
||||
...baseGanacheOptions,
|
||||
hardfork: 'london',
|
||||
};
|
||||
|
||||
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.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
await driver.navigate();
|
||||
await logInWithBalanceValidation(driver, ganacheServer);
|
||||
|
||||
await driver.clickElement('[data-testid="eth-overview-send"]');
|
||||
|
||||
await driver.fill(
|
||||
'input[placeholder="Enter public address (0x) or ENS name"]',
|
||||
'0x2f318C334780961FB129D2a6c30D0763d9a5C970',
|
||||
);
|
||||
|
||||
await driver.fill('.unit-input__input', '1');
|
||||
|
||||
// Check that the gas estimation is what we expect
|
||||
await driver.findElement({
|
||||
cass: '[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(
|
||||
'https://gas-api.metaswap.codefi.network/networks/1337/suggestedGasFees',
|
||||
)
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
json: {
|
||||
error: 'cannot get gas prices for chain id 1337',
|
||||
},
|
||||
statusCode: 503,
|
||||
};
|
||||
});
|
||||
},
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
await driver.navigate();
|
||||
await logInWithBalanceValidation(driver, ganacheServer);
|
||||
|
||||
await driver.clickElement('[data-testid="eth-overview-send"]');
|
||||
|
||||
await driver.fill(
|
||||
'input[placeholder="Enter public address (0x) or ENS name"]',
|
||||
'0x2f318C334780961FB129D2a6c30D0763d9a5C970',
|
||||
);
|
||||
|
||||
await driver.fill('.unit-input__input', '1');
|
||||
|
||||
// Check that the gas estimation is what we expect
|
||||
await driver.findElement({
|
||||
cass: '[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(
|
||||
'https://gas-api.metaswap.codefi.network/networks/1337/suggestedGasFees',
|
||||
)
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 422,
|
||||
};
|
||||
});
|
||||
},
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
await driver.navigate();
|
||||
await logInWithBalanceValidation(driver, ganacheServer);
|
||||
|
||||
await driver.clickElement('[data-testid="eth-overview-send"]');
|
||||
|
||||
await driver.fill(
|
||||
'input[placeholder="Enter public address (0x) or ENS name"]',
|
||||
'0x2f318C334780961FB129D2a6c30D0763d9a5C970',
|
||||
);
|
||||
|
||||
await driver.fill('.unit-input__input', '1');
|
||||
|
||||
// Check that the gas estimation is what we expect
|
||||
await driver.findElement({
|
||||
cass: '[data-testid="confirm-gas-display"]',
|
||||
text: '0.00043983',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Send on a network that is not EIP-1559 compatible', function () {
|
||||
it('show expected gas defaults', async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
fixtures: new FixtureBuilder().build(),
|
||||
ganacheOptions: preLondonGanacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
await driver.navigate();
|
||||
await logInWithBalanceValidation(driver, ganacheServer);
|
||||
|
||||
await driver.clickElement('[data-testid="eth-overview-send"]');
|
||||
|
||||
await driver.fill(
|
||||
'input[placeholder="Enter public address (0x) or ENS name"]',
|
||||
'0x2f318C334780961FB129D2a6c30D0763d9a5C970',
|
||||
);
|
||||
|
||||
await driver.fill('.unit-input__input', '1');
|
||||
|
||||
// Check that the gas estimation is what we expect
|
||||
await driver.findElement({
|
||||
cass: '[data-testid="confirm-gas-display"]',
|
||||
text: '0.000042',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,5 +1,10 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const { convertToHexValue, withFixtures, openDapp } = require('../helpers');
|
||||
const {
|
||||
convertToHexValue,
|
||||
withFixtures,
|
||||
openDapp,
|
||||
regularDelayMs,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
describe('Personal sign', function () {
|
||||
@ -33,7 +38,7 @@ describe('Personal sign', function () {
|
||||
await driver.clickElement('#personalSign');
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
@ -47,23 +52,92 @@ describe('Personal sign', function () {
|
||||
|
||||
await driver.clickElement('[data-testid="page-container-footer-next"]');
|
||||
|
||||
// Switch to the Dapp
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
await verifyAndAssertPersonalMessage(driver, publicAddress);
|
||||
},
|
||||
);
|
||||
});
|
||||
it('can queue multiple personal signs and confirm', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
// Create personal sign
|
||||
await driver.clickElement('#personalSign');
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
|
||||
// Switch to Dapp
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
|
||||
// Verify
|
||||
await driver.clickElement('#personalSignVerify');
|
||||
const verifySigUtil = await driver.findElement(
|
||||
'#personalSignVerifySigUtilResult',
|
||||
// Create second personal sign
|
||||
await driver.clickElement('#personalSign');
|
||||
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
const verifyECRecover = await driver.waitForSelector({
|
||||
css: '#personalSignVerifyECRecoverResult',
|
||||
text: publicAddress,
|
||||
|
||||
await driver.waitForSelector({
|
||||
text: 'Reject 2 requests',
|
||||
tag: 'a',
|
||||
});
|
||||
assert.equal(await verifySigUtil.getText(), publicAddress);
|
||||
assert.equal(await verifyECRecover.getText(), publicAddress);
|
||||
|
||||
const personalMessageRow = await driver.findElement(
|
||||
'.request-signature__row-value',
|
||||
);
|
||||
const personalMessage = await personalMessageRow.getText();
|
||||
assert.equal(personalMessage, 'Example `personal_sign` message');
|
||||
|
||||
// Confirm first personal sign
|
||||
await driver.clickElement('[data-testid="page-container-footer-next"]');
|
||||
await driver.delay(regularDelayMs);
|
||||
// Confirm second personal sign
|
||||
await driver.clickElement('[data-testid="page-container-footer-next"]');
|
||||
|
||||
await verifyAndAssertPersonalMessage(driver, publicAddress);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
async function verifyAndAssertPersonalMessage(driver, publicAddress) {
|
||||
// Switch to the Dapp
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
|
||||
// Verify last confirmed personal sign
|
||||
await driver.clickElement('#personalSignVerify');
|
||||
const verifySigUtil = await driver.findElement(
|
||||
'#personalSignVerifySigUtilResult',
|
||||
);
|
||||
const verifyECRecover = await driver.waitForSelector({
|
||||
css: '#personalSignVerifyECRecoverResult',
|
||||
text: publicAddress,
|
||||
});
|
||||
assert.equal(await verifySigUtil.getText(), publicAddress);
|
||||
assert.equal(await verifyECRecover.getText(), publicAddress);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ describe('Portfolio site', function () {
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
// Click Portfolio site
|
||||
await driver.clickElement('[data-testid="home__portfolio-site"]');
|
||||
await driver.clickElement('[data-testid="eth-overview-portfolio"]');
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
@ -34,7 +34,7 @@ describe('Portfolio site', function () {
|
||||
// Verify site
|
||||
assert.equal(
|
||||
await driver.getCurrentUrl(),
|
||||
'http://127.0.0.1:8080/?metamaskEntry=ext&metametricsId=null',
|
||||
'http://127.0.0.1:8080/?metamaskEntry=ext_portfolio_button&metametricsId=null',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -1,240 +1,238 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const {
|
||||
convertToHexValue,
|
||||
withFixtures,
|
||||
regularDelayMs,
|
||||
openDapp,
|
||||
DAPP_URL,
|
||||
convertToHexValue,
|
||||
} = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
|
||||
describe('Sign Typed Data V4 Signature Request', function () {
|
||||
it('can initiate and confirm a Signature Request', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedDataV4');
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
const title = await driver.findElement(
|
||||
'.signature-request__content__title',
|
||||
);
|
||||
const origin = await driver.findElement('.signature-request__origin');
|
||||
const verifyContractDetailsButton = await driver.findElement(
|
||||
'.signature-request-content__verify-contract-details',
|
||||
);
|
||||
const message = await driver.findElement(
|
||||
'.signature-request-data__node__value',
|
||||
);
|
||||
|
||||
assert.equal(await title.getText(), 'Signature request');
|
||||
assert.equal(await origin.getText(), DAPP_URL);
|
||||
|
||||
verifyContractDetailsButton.click();
|
||||
await driver.findElement({ text: 'Third-party details', tag: 'h5' });
|
||||
await driver.findElement('[data-testid="recipient"]');
|
||||
await driver.clickElement({ text: 'Got it', tag: 'button' });
|
||||
|
||||
assert.equal(await message.getText(), 'Hello, Bob!');
|
||||
// Approve signing typed data
|
||||
await driver.clickElement(
|
||||
'[data-testid="signature-request-scroll-button"]',
|
||||
);
|
||||
await driver.delay(regularDelayMs);
|
||||
await driver.clickElement({ text: 'Sign', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
|
||||
// switch to the Dapp and verify the signed addressed
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
await driver.clickElement('#signTypedDataV4Verify');
|
||||
const recoveredAddress = await driver.findElement(
|
||||
'#signTypedDataV4VerifyResult',
|
||||
);
|
||||
assert.equal(await recoveredAddress.getText(), publicAddress);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
/* eslint-disable-next-line mocha/max-top-level-suites */
|
||||
describe('Sign Typed Data V3 Signature Request', function () {
|
||||
it('can initiate and confirm a Signature Request', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedDataV3');
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
const title = await driver.findElement(
|
||||
'.signature-request__content__title',
|
||||
);
|
||||
const origin = await driver.findElement('.signature-request__origin');
|
||||
const verifyContractDetailsButton = await driver.findElement(
|
||||
'.signature-request-content__verify-contract-details',
|
||||
);
|
||||
|
||||
const messages = await driver.findElements(
|
||||
'.signature-request-data__node__value',
|
||||
);
|
||||
|
||||
assert.equal(await title.getText(), 'Signature request');
|
||||
assert.equal(await origin.getText(), DAPP_URL);
|
||||
|
||||
verifyContractDetailsButton.click();
|
||||
await driver.findElement({ text: 'Third-party details', tag: 'h5' });
|
||||
await driver.findElement('[data-testid="recipient"]');
|
||||
await driver.clickElement({ text: 'Got it', tag: 'button' });
|
||||
|
||||
assert.equal(await messages[4].getText(), 'Hello, Bob!');
|
||||
|
||||
// Approve signing typed data
|
||||
await driver.clickElement(
|
||||
'[data-testid="signature-request-scroll-button"]',
|
||||
);
|
||||
await driver.delay(regularDelayMs);
|
||||
await driver.clickElement({ text: 'Sign', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
|
||||
// switch to the Dapp and verify the signed addressed
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
await driver.clickElement('#signTypedDataV3Verify');
|
||||
const recoveredAddress = await driver.findElement(
|
||||
'#signTypedDataV3VerifyResult',
|
||||
);
|
||||
assert.equal(await recoveredAddress.getText(), publicAddress);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
const signatureRequestType = {
|
||||
signTypedData: 'Sign Typed Data',
|
||||
signTypedDataV3: 'Sign Typed Data V3',
|
||||
signTypedDataV4: 'Sign Typed Data V4',
|
||||
};
|
||||
|
||||
const testData = [
|
||||
{
|
||||
type: signatureRequestType.signTypedData,
|
||||
buttonId: '#signTypedData',
|
||||
verifyId: '#signTypedDataVerify',
|
||||
verifyResultId: '#signTypedDataVerifyResult',
|
||||
expectedMessage: 'Hi, Alice!',
|
||||
verifyAndAssertMessage: {
|
||||
titleClass: '.request-signature__content__title',
|
||||
originClass: '.request-signature__origin',
|
||||
messageClass: '.request-signature__row-value',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: signatureRequestType.signTypedDataV3,
|
||||
buttonId: '#signTypedDataV3',
|
||||
verifyId: '#signTypedDataV3Verify',
|
||||
verifyResultId: '#signTypedDataV3VerifyResult',
|
||||
expectedMessage: 'Hello, Bob!',
|
||||
verifyAndAssertMessage: {
|
||||
titleClass: '.signature-request__content__title',
|
||||
originClass: '.signature-request__origin',
|
||||
messageClass: '.signature-request-data__node__value',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: signatureRequestType.signTypedDataV4,
|
||||
buttonId: '#signTypedDataV4',
|
||||
verifyId: '#signTypedDataV4Verify',
|
||||
verifyResultId: '#signTypedDataV4VerifyResult',
|
||||
expectedMessage: 'Hello, Bob!',
|
||||
verifyAndAssertMessage: {
|
||||
titleClass: '.signature-request__content__title',
|
||||
originClass: '.signature-request__origin',
|
||||
messageClass: '.signature-request-data__node__value',
|
||||
},
|
||||
},
|
||||
];
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
describe('Sign Typed Data Signature Request', function () {
|
||||
it('can initiate and confirm a Signature Request', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
testData.forEach((data) => {
|
||||
it(`can initiate and confirm a Signature Request of ${data.type}`, async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
await openDapp(driver);
|
||||
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement('#signTypedData');
|
||||
// creates a sign typed data signature request
|
||||
await driver.clickElement(data.buttonId);
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
let windowHandles = await driver.getAllWindowHandles();
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
const title = await driver.findElement(
|
||||
'.request-signature__content__title',
|
||||
);
|
||||
const origin = await driver.findElement('.request-signature__origin');
|
||||
const message = await driver.findElements(
|
||||
'.request-signature__row-value',
|
||||
);
|
||||
assert.equal(await title.getText(), 'Signature request');
|
||||
assert.equal(await origin.getText(), DAPP_URL);
|
||||
assert.equal(await message[0].getText(), 'Hi, Alice!');
|
||||
assert.equal(await message[1].getText(), '1337');
|
||||
await verifyAndAssertSignTypedData(
|
||||
driver,
|
||||
data.type,
|
||||
data.verifyAndAssertMessage.titleClass,
|
||||
data.verifyAndAssertMessage.originClass,
|
||||
data.verifyAndAssertMessage.messageClass,
|
||||
data.expectedMessage,
|
||||
);
|
||||
|
||||
// Approve signing typed data
|
||||
await driver.clickElement({ text: 'Sign', tag: 'button' });
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
// Approve signing typed data
|
||||
await approveSignatureRequest(
|
||||
driver,
|
||||
data.type,
|
||||
'[data-testid="signature-request-scroll-button"]',
|
||||
);
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
windowHandles = await driver.getAllWindowHandles();
|
||||
|
||||
// switch to the Dapp and verify the signed addressed
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
await driver.clickElement('#signTypedDataVerify');
|
||||
const recoveredAddress = await driver.findElement(
|
||||
'#signTypedDataVerifyResult',
|
||||
);
|
||||
assert.equal(await recoveredAddress.getText(), publicAddress);
|
||||
},
|
||||
);
|
||||
// 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(
|
||||
{
|
||||
dapp: true,
|
||||
fixtures: new FixtureBuilder()
|
||||
.withPermissionControllerConnectedToTestDapp()
|
||||
.build(),
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, ganacheServer }) => {
|
||||
const addresses = await ganacheServer.getAccounts();
|
||||
const publicAddress = addresses[0];
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await openDapp(driver);
|
||||
|
||||
// creates multiple sign typed data signature requests
|
||||
await driver.clickElement(data.buttonId);
|
||||
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
const windowHandles = await driver.getAllWindowHandles();
|
||||
// switches to Dapp
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
|
||||
// creates second sign typed data signature request
|
||||
await driver.clickElement(data.buttonId);
|
||||
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
await driver.waitForSelector({
|
||||
text: 'Reject 2 requests',
|
||||
tag: 'a',
|
||||
});
|
||||
|
||||
await verifyAndAssertSignTypedData(
|
||||
driver,
|
||||
data.type,
|
||||
data.verifyAndAssertMessage.titleClass,
|
||||
data.verifyAndAssertMessage.originClass,
|
||||
data.verifyAndAssertMessage.messageClass,
|
||||
data.expectedMessage,
|
||||
);
|
||||
|
||||
// approve first signature request
|
||||
await approveSignatureRequest(
|
||||
driver,
|
||||
data.type,
|
||||
'[data-testid="signature-request-scroll-button"]',
|
||||
);
|
||||
await driver.waitUntilXWindowHandles(3);
|
||||
|
||||
// approve second signature request
|
||||
await approveSignatureRequest(
|
||||
driver,
|
||||
data.type,
|
||||
'[data-testid="signature-request-scroll-button"]',
|
||||
);
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
|
||||
// switch to the Dapp and verify the signed address for each request
|
||||
await driver.switchToWindowWithTitle('E2E Test Dapp');
|
||||
await driver.clickElement(data.verifyId);
|
||||
const recoveredAddress = await driver.findElement(
|
||||
data.verifyResultId,
|
||||
);
|
||||
assert.equal(await recoveredAddress.getText(), publicAddress);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function verifyAndAssertSignTypedData(
|
||||
driver,
|
||||
type,
|
||||
titleClass,
|
||||
originClass,
|
||||
messageClass,
|
||||
expectedMessage,
|
||||
) {
|
||||
const title = await driver.findElement(titleClass);
|
||||
const origin = await driver.findElement(originClass);
|
||||
|
||||
assert.equal(await title.getText(), 'Signature request');
|
||||
assert.equal(await origin.getText(), DAPP_URL);
|
||||
|
||||
const messages = await driver.findElements(messageClass);
|
||||
if (type !== signatureRequestType.signTypedData) {
|
||||
const verifyContractDetailsButton = await driver.findElement(
|
||||
'.signature-request-content__verify-contract-details',
|
||||
);
|
||||
verifyContractDetailsButton.click();
|
||||
await driver.findElement({ text: 'Third-party details', tag: 'h5' });
|
||||
await driver.findElement('[data-testid="recipient"]');
|
||||
await driver.clickElement({ text: 'Got it', tag: 'button' });
|
||||
}
|
||||
const messageNumber = type === signatureRequestType.signTypedDataV3 ? 4 : 0;
|
||||
assert.equal(await messages[messageNumber].getText(), expectedMessage);
|
||||
}
|
||||
|
||||
async function approveSignatureRequest(driver, type, buttonElementId) {
|
||||
if (type !== signatureRequestType.signTypedData) {
|
||||
await driver.clickElement(buttonElementId);
|
||||
}
|
||||
await driver.delay(regularDelayMs);
|
||||
await driver.clickElement({ text: 'Sign', tag: 'button' });
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
process.env.METAMASK_ENVIRONMENT = 'test';
|
||||
process.env.SUPPORT_LINK = 'https://support.metamask.io';
|
||||
process.env.IFRAME_EXECUTION_ENVIRONMENT_URL =
|
||||
'https://execution.metamask.io/0.16.0-flask.1/index.html';
|
||||
'https://execution.metamask.io/0.35.2-flask.1/index.html';
|
||||
|
@ -10,7 +10,6 @@ import {
|
||||
getNativeCurrencyImage,
|
||||
getDetectedTokensInCurrentNetwork,
|
||||
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
|
||||
getTokenList,
|
||||
} from '../../../selectors';
|
||||
import { getNativeCurrency } from '../../../ducks/metamask/metamask';
|
||||
import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay';
|
||||
@ -56,19 +55,15 @@ const AssetList = ({ onClickAsset }) => {
|
||||
|
||||
const primaryTokenImage = useSelector(getNativeCurrencyImage);
|
||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork) || [];
|
||||
const istokenDetectionInactiveOnNonMainnetSupportedNetwork = useSelector(
|
||||
const isTokenDetectionInactiveOnNonMainnetSupportedNetwork = useSelector(
|
||||
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
|
||||
);
|
||||
const tokenList = useSelector(getTokenList);
|
||||
const tokenData = Object.values(tokenList).find(
|
||||
(token) => token.symbol === primaryCurrencyProperties.suffix,
|
||||
);
|
||||
const title = tokenData?.name || primaryCurrencyProperties.suffix;
|
||||
|
||||
return (
|
||||
<>
|
||||
<TokenListItem
|
||||
onClick={() => onClickAsset(nativeCurrency)}
|
||||
title={title}
|
||||
title={nativeCurrency}
|
||||
primary={
|
||||
primaryCurrencyProperties.value ?? secondaryCurrencyProperties.value
|
||||
}
|
||||
@ -82,14 +77,14 @@ const AssetList = ({ onClickAsset }) => {
|
||||
}}
|
||||
/>
|
||||
{detectedTokens.length > 0 &&
|
||||
!istokenDetectionInactiveOnNonMainnetSupportedNetwork ? (
|
||||
!isTokenDetectionInactiveOnNonMainnetSupportedNetwork ? (
|
||||
<DetectedTokensBanner
|
||||
actionButtonOnClick={() => setShowDetectedTokens(true)}
|
||||
margin={4}
|
||||
/>
|
||||
) : null}
|
||||
<Box marginTop={detectedTokens.length > 0 ? 0 : 4}>
|
||||
<ImportTokenLink margin={4} />
|
||||
<ImportTokenLink margin={4} marginBottom={2} />
|
||||
</Box>
|
||||
{showDetectedTokens && (
|
||||
<DetectedToken setShowDetectedTokens={setShowDetectedTokens} />
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Text } from '../../component-library';
|
||||
import { EditGasModes, PriorityLevels } from '../../../../shared/constants/gas';
|
||||
import {
|
||||
AlignItems,
|
||||
DISPLAY,
|
||||
FLEX_DIRECTION,
|
||||
Display,
|
||||
FlexDirection,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { getAppIsLoading } from '../../../selectors';
|
||||
@ -16,10 +15,10 @@ import { useTransactionModalContext } from '../../../contexts/transaction-modal'
|
||||
import EditGasFeeButton from '../edit-gas-fee-button';
|
||||
import GasDetailsItem from '../gas-details-item';
|
||||
import Box from '../../ui/box';
|
||||
import Button from '../../ui/button';
|
||||
import InfoTooltip from '../../ui/info-tooltip';
|
||||
import Popover from '../../ui/popover';
|
||||
import AppLoadingSpinner from '../app-loading-spinner';
|
||||
import { Text, Button, ButtonLink } from '../../component-library';
|
||||
|
||||
const CancelSpeedupPopover = () => {
|
||||
const {
|
||||
@ -98,11 +97,11 @@ const CancelSpeedupPopover = () => {
|
||||
<div className="cancel-speedup-popover__wrapper">
|
||||
<Text
|
||||
alignItems={AlignItems.center}
|
||||
display={DISPLAY.FLEX}
|
||||
display={Display.Flex}
|
||||
variant={TextVariant.bodySm}
|
||||
as="h6"
|
||||
marginTop={0}
|
||||
marginBottom={2}
|
||||
paddingBottom={2}
|
||||
className="cancel-speedup-popover__description"
|
||||
>
|
||||
{t('cancelSpeedUpLabel', [
|
||||
<strong key="cancelSpeedupReplace">{t('replace')}</strong>,
|
||||
@ -110,42 +109,39 @@ const CancelSpeedupPopover = () => {
|
||||
<InfoTooltip
|
||||
position="top"
|
||||
contentText={
|
||||
<Box>
|
||||
{t('cancelSpeedUpTransactionTooltip', [
|
||||
editGasMode === EditGasModes.cancel
|
||||
? t('cancel')
|
||||
: t('speedUp'),
|
||||
])}
|
||||
<div>
|
||||
<a
|
||||
href="https://community.metamask.io/t/how-to-speed-up-or-cancel-transactions-on-metamask/3296"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('learnMoreUpperCase')}
|
||||
</a>
|
||||
</div>
|
||||
</Box>
|
||||
<>
|
||||
<Text variant={TextVariant.bodySm}>
|
||||
{t('cancelSpeedUpTransactionTooltip', [
|
||||
editGasMode === EditGasModes.cancel
|
||||
? t('cancel')
|
||||
: t('speedUp'),
|
||||
])}
|
||||
</Text>
|
||||
<ButtonLink
|
||||
variant={TextVariant.bodySm}
|
||||
href="https://community.metamask.io/t/how-to-speed-up-or-cancel-transactions-on-metamask/3296"
|
||||
target="_blank"
|
||||
>
|
||||
{t('learnMoreUpperCase')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Text>
|
||||
<div className="cancel-speedup-popover__separator" />
|
||||
<Box
|
||||
display={DISPLAY.FLEX}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||
marginTop={4}
|
||||
flexDirection={FlexDirection.Column}
|
||||
marginTop={2}
|
||||
>
|
||||
<Box className="cancel-speedup-popover__edit-gas-button">
|
||||
<div className="cancel-speedup-popover__edit-gas-button">
|
||||
{!appIsLoading && <EditGasFeeButton />}
|
||||
</Box>
|
||||
<Box className="cancel-speedup-popover__gas-details">
|
||||
</div>
|
||||
<div className="cancel-speedup-popover__gas-details">
|
||||
<GasDetailsItem />
|
||||
</Box>
|
||||
</div>
|
||||
</Box>
|
||||
<Button type="primary" onClick={submitTransactionChange}>
|
||||
{t('submit')}
|
||||
</Button>
|
||||
<Button onClick={submitTransactionChange}>{t('submit')}</Button>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
|
@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import configureStore from '../../../store/store';
|
||||
import { TransactionModalContext } from '../../../contexts/transaction-modal';
|
||||
import mockEstimates from '../../../../test/data/mock-estimates.json';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import {
|
||||
EditGasModes,
|
||||
GasEstimateTypes,
|
||||
} from '../../../../shared/constants/gas';
|
||||
import { decGWEIToHexWEI } from '../../../../shared/modules/conversion.utils';
|
||||
import { GasFeeContextProvider } from '../../../contexts/gasFee';
|
||||
import CancelSpeedupPopover from './cancel-speedup-popover';
|
||||
|
||||
const store = configureStore({
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
accounts: {
|
||||
[mockState.metamask.selectedAddress]: {
|
||||
address: mockState.metamask.selectedAddress,
|
||||
balance: '0x1F4',
|
||||
},
|
||||
},
|
||||
gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
|
||||
},
|
||||
});
|
||||
|
||||
const MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_DEC_GWEI =
|
||||
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates.medium
|
||||
.suggestedMaxFeePerGas;
|
||||
|
||||
const MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_BN_WEI = new BigNumber(
|
||||
decGWEIToHexWEI(MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_DEC_GWEI),
|
||||
16,
|
||||
);
|
||||
|
||||
const MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_HEX_WEI =
|
||||
MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_BN_WEI.toString(16);
|
||||
|
||||
export default {
|
||||
title: 'Components/App/CancelSpeedupPopover',
|
||||
component: CancelSpeedupPopover,
|
||||
decorators: [
|
||||
(story) => (
|
||||
<Provider store={store}>
|
||||
<GasFeeContextProvider
|
||||
transaction={{
|
||||
userFeeLevel: 'tenPercentIncreased',
|
||||
txParams: {
|
||||
gas: '0x5208',
|
||||
maxFeePerGas: MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_HEX_WEI,
|
||||
maxPriorityFeePerGas: '0x59682f00',
|
||||
},
|
||||
}}
|
||||
editGasMode={EditGasModes.cancel}
|
||||
>
|
||||
<TransactionModalContext.Provider
|
||||
value={{
|
||||
closeModal: () => undefined,
|
||||
currentModal: 'cancelSpeedUpTransaction',
|
||||
}}
|
||||
>
|
||||
{story()}
|
||||
</TransactionModalContext.Provider>
|
||||
</GasFeeContextProvider>
|
||||
</Provider>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const DefaultStory = (args) => {
|
||||
return (
|
||||
<div style={{ width: '600px' }}>
|
||||
<CancelSpeedupPopover {...args} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user