mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Merge remote-tracking branch 'origin/develop' into master-sync
* origin/develop: (131 commits) Update `protobufjs` and remove obsolete advisory exclusion (#14841) Include snap version in pill (#14803) Update PULL_REQUEST_TEMPLATE.md (#14790) fix: keystone transaction qrcode has no white spacing (#14798) Snap notifications integration (#14605) Upgrade @metamask/eth-ledger-bridge-keyring (#14799) snaps-skunkworks@0.15.0 (#14772) Fix proptype errors in network dropdown, tx list item details, and account details modal tests (#14747) Ensure transaction type is correctly updated on edit (#14721) Add fiat onboarding for AVAX and MATIC through Wyre (#14683) Bump @metamask/contract-metadata from 1.33.0 to 1.35.0 (#14791) Slight cleanup of constants/transactions, useTransactionDisplayData, and TransactionIcon (#14784) Migrate the "estimateGas" API call to "getFees" for STX (#14767) Ignore advisory GHSA-wm7h-9275-46v2 (#14789) Adding flag for MV3 (#14762) Add types to send state (#14740) Remove site origin on snap install (#14752) Update design tokens library from 1.5 to 1.6 WIP (#14732) Enables the "Safe Transaction From" copy for safeTransferFrom transactions (#14769) remove draft transaction (#14701) ...
This commit is contained in:
commit
e6d5af5f9a
@ -670,6 +670,13 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: test:coverage:jest
|
name: test:coverage:jest
|
||||||
command: yarn test:coverage:jest
|
command: yarn test:coverage:jest
|
||||||
|
- run:
|
||||||
|
name: Validate coverage thresholds
|
||||||
|
command: |
|
||||||
|
if ! git diff --exit-code jest.config.js development/jest.config.js; then
|
||||||
|
echo "Detected changes in coverage thresholds"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: .
|
root: .
|
||||||
paths:
|
paths:
|
||||||
|
@ -5,12 +5,12 @@ set -u
|
|||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# To get the latest version, see <https://www.ubuntuupdates.org/ppa/google_chrome?dist=stable>
|
# To get the latest version, see <https://www.ubuntuupdates.org/ppa/google_chrome?dist=stable>
|
||||||
CHROME_VERSION='100.0.4896.60-1'
|
CHROME_VERSION='101.0.4951.54-1'
|
||||||
CHROME_BINARY="google-chrome-stable_${CHROME_VERSION}_amd64.deb"
|
CHROME_BINARY="google-chrome-stable_${CHROME_VERSION}_amd64.deb"
|
||||||
CHROME_BINARY_URL="https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/${CHROME_BINARY}"
|
CHROME_BINARY_URL="https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/${CHROME_BINARY}"
|
||||||
|
|
||||||
# To retrieve this checksum, run the `wget` and `shasum` commands below
|
# To retrieve this checksum, run the `wget` and `shasum` commands below
|
||||||
CHROME_BINARY_SHA512SUM='d7a98777650e8218fef4acc8466d4ddf5e234b97fbc16c33f38f69f9ebfe7b6bb6827a90aad15ea729d7c1bacfa78488c5d5194b531f00f454302dd9c0957e4e'
|
CHROME_BINARY_SHA512SUM='46ebc53c806f179a5f9ab570c1097c2d35fc437dd4f5bd3fb34e758dc4f306771ceb05f8df7d450584355abf35bae34c0e70903e4f0312e2d3caa34491c8f622'
|
||||||
|
|
||||||
wget -O "${CHROME_BINARY}" -t 5 "${CHROME_BINARY_URL}"
|
wget -O "${CHROME_BINARY}" -t 5 "${CHROME_BINARY_URL}"
|
||||||
|
|
||||||
|
@ -6,13 +6,13 @@ set -x
|
|||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
# use `improved-yarn-audit` since that allows for exclude
|
# use `improved-yarn-audit` since that allows for exclude
|
||||||
# exclude 1002401 until we remove use of 3Box, 1002581 until we can find a better solution
|
# exclusions are in .iyarc now
|
||||||
yarn run improved-yarn-audit --ignore-dev-deps --min-severity moderate --exclude GHSA-93q8-gq69-wqmw,GHSA-257v-vj4p-3w2h,GHSA-fwr7-v2mv-hh25
|
yarn run improved-yarn-audit \
|
||||||
audit_status="$?"
|
--ignore-dev-deps \
|
||||||
|
--min-severity moderate \
|
||||||
|
--fail-on-missing-exclusions
|
||||||
|
|
||||||
# Use a bitmask to ignore INFO and LOW severity audit results
|
audit_status="$?"
|
||||||
# See here: https://yarnpkg.com/lang/en/docs/cli/audit/
|
|
||||||
audit_status="$(( audit_status & 11100 ))"
|
|
||||||
|
|
||||||
if [[ "$audit_status" != 0 ]]
|
if [[ "$audit_status" != 0 ]]
|
||||||
then
|
then
|
||||||
|
@ -44,14 +44,6 @@ module.exports = {
|
|||||||
path.resolve(__dirname, '.eslintrc.babel.js'),
|
path.resolve(__dirname, '.eslintrc.babel.js'),
|
||||||
path.resolve(__dirname, '.eslintrc.typescript-compat.js'),
|
path.resolve(__dirname, '.eslintrc.typescript-compat.js'),
|
||||||
],
|
],
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
// This rule does not work with CommonJS modules. We will just have to
|
|
||||||
// trust that all of the files specified above are indeed modules.
|
|
||||||
'import/unambiguous': 'off',
|
|
||||||
},
|
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
// When determining the location of a `require()` call, use Node's
|
// When determining the location of a `require()` call, use Node's
|
||||||
|
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -1,7 +1,7 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: Using MetaMask, but it's not working as you expect?
|
description: Using MetaMask, but it's not working as you expect?
|
||||||
title: "[Bug]: "
|
title: "[Bug]: "
|
||||||
labels: ["bug"]
|
labels: ["type-bug"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -15,7 +15,7 @@ This is a problem because ...
|
|||||||
In order to solve this problem, this pull request ...
|
In order to solve this problem, this pull request ...
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## More information
|
## More Information
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Are there any issues, Slack conversations, Zendesk issues, user stories, etc. reviewers should consult to understand this pull request better? For instance:
|
Are there any issues, Slack conversations, Zendesk issues, user stories, etc. reviewers should consult to understand this pull request better? For instance:
|
||||||
@ -36,7 +36,7 @@ Are there any issues, Slack conversations, Zendesk issues, user stories, etc. re
|
|||||||
|
|
||||||
<!-- How does it look now? Drag your file(s) below this line: -->
|
<!-- How does it look now? Drag your file(s) below this line: -->
|
||||||
|
|
||||||
## Manual testing steps
|
## Manual Testing Steps
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
How should reviewers and QA manually test your changes? For instance:
|
How should reviewers and QA manually test your changes? For instance:
|
||||||
@ -45,3 +45,15 @@ How should reviewers and QA manually test your changes? For instance:
|
|||||||
- Do this
|
- Do this
|
||||||
- Then do this
|
- Then do this
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## Pre-Merge Checklist
|
||||||
|
|
||||||
|
- [ ] PR template is filled out
|
||||||
|
- [ ] **IF** this PR fixes a bug, a test that _would have_ caught the bug has been added
|
||||||
|
- [ ] PR is linked to the appropriate GitHub issue
|
||||||
|
- [ ] PR has been added to the appropriate release Milestone
|
||||||
|
|
||||||
|
### + If there are functional changes:
|
||||||
|
|
||||||
|
- [ ] Manual testing complete & passed
|
||||||
|
- [ ] "Extension QA Board" label has been applied
|
||||||
|
2
.github/workflows/crowdin_action.yml
vendored
2
.github/workflows/crowdin_action.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: crowdin action
|
- name: crowdin action
|
||||||
uses: crowdin/github-action@9237b4cb361788dfce63feb2e2f15c09e2fe7415
|
uses: crowdin/github-action@a3160b9e5a9e00739392c23da5e580c6cabe526d
|
||||||
with:
|
with:
|
||||||
upload_translations: true
|
upload_translations: true
|
||||||
download_translations: true
|
download_translations: true
|
||||||
|
4
.iyarc
Normal file
4
.iyarc
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# improved-yarn-audit advisory exclusions
|
||||||
|
GHSA-93q8-gq69-wqmw
|
||||||
|
GHSA-257v-vj4p-3w2h
|
||||||
|
GHSA-wm7h-9275-46v2
|
@ -67,6 +67,7 @@ var(--color-text-muted)
|
|||||||
|
|
||||||
/** Icons */
|
/** Icons */
|
||||||
var(--color-icon-default)
|
var(--color-icon-default)
|
||||||
|
var(--color-icon-alternative)
|
||||||
var(--color-icon-muted)
|
var(--color-icon-muted)
|
||||||
|
|
||||||
/** Borders */
|
/** Borders */
|
||||||
@ -75,20 +76,20 @@ var(--color-border-muted)
|
|||||||
|
|
||||||
/** Overlays */
|
/** Overlays */
|
||||||
var(--color-overlay-default)
|
var(--color-overlay-default)
|
||||||
var(--color-overlay-inverse)
|
var(--color-overlay-inverse) [DEPRECATED]
|
||||||
|
|
||||||
/** User Actions */
|
/** User Actions */
|
||||||
var(--color-primary-default)
|
var(--color-primary-default)
|
||||||
var(--color-primary-alternative)
|
var(--color-primary-alternative)
|
||||||
var(--color-primary-muted)
|
var(--color-primary-muted)
|
||||||
var(--color-primary-inverse)
|
var(--color-primary-inverse)
|
||||||
var(--color-primary-disabled)
|
var(--color-primary-disabled) [DEPRECATED]
|
||||||
|
|
||||||
var(--color-secondary-default)
|
var(--color-secondary-default) [DEPRECATED]
|
||||||
var(--color-secondary-alternative)
|
var(--color-secondary-alternative) [DEPRECATED]
|
||||||
var(--color-secondary-muted)
|
var(--color-secondary-muted) [DEPRECATED]
|
||||||
var(--color-secondary-inverse)
|
var(--color-secondary-inverse) [DEPRECATED]
|
||||||
var(--color-secondary-disabled)
|
var(--color-secondary-disabled) [DEPRECATED]
|
||||||
|
|
||||||
/** States */
|
/** States */
|
||||||
/** Error */
|
/** Error */
|
||||||
@ -96,28 +97,28 @@ var(--color-error-default)
|
|||||||
var(--color-error-alternative)
|
var(--color-error-alternative)
|
||||||
var(--color-error-muted)
|
var(--color-error-muted)
|
||||||
var(--color-error-inverse)
|
var(--color-error-inverse)
|
||||||
var(--color-error-disabled)
|
var(--color-error-disabled) [DEPRECATED]
|
||||||
|
|
||||||
/** Warning */
|
/** Warning */
|
||||||
var(--color-warning-default)
|
var(--color-warning-default)
|
||||||
var(--color-warning-alternative)
|
var(--color-warning-alternative) [DEPRECATED]
|
||||||
var(--color-warning-muted)
|
var(--color-warning-muted)
|
||||||
var(--color-warning-inverse)
|
var(--color-warning-inverse)
|
||||||
var(--color-warning-disabled)
|
var(--color-warning-disabled) [DEPRECATED]
|
||||||
|
|
||||||
/** Success */
|
/** Success */
|
||||||
var(--color-success-default)
|
var(--color-success-default)
|
||||||
var(--color-success-alternative)
|
var(--color-success-alternative) [DEPRECATED]
|
||||||
var(--color-success-muted)
|
var(--color-success-muted)
|
||||||
var(--color-success-inverse)
|
var(--color-success-inverse)
|
||||||
var(--color-success-disabled)
|
var(--color-success-disabled) [DEPRECATED]
|
||||||
|
|
||||||
/** Info */
|
/** Info */
|
||||||
var(--color-info-default)
|
var(--color-info-default)
|
||||||
var(--color-info-alternative)
|
var(--color-info-alternative) [DEPRECATED]
|
||||||
var(--color-info-muted)
|
var(--color-info-muted)
|
||||||
var(--color-info-inverse)
|
var(--color-info-inverse)
|
||||||
var(--color-info-disabled)
|
var(--color-info-disabled) [DEPRECATED]
|
||||||
```
|
```
|
||||||
|
|
||||||
### **Component colors** (tier 3)
|
### **Component colors** (tier 3)
|
||||||
|
@ -112,6 +112,65 @@ const state = {
|
|||||||
],
|
],
|
||||||
metamask: {
|
metamask: {
|
||||||
tokenList: {
|
tokenList: {
|
||||||
|
'0x514910771af9ca656af840dff83e8264ecf986ca': {
|
||||||
|
address: '0x514910771af9ca656af840dff83e8264ecf986ca',
|
||||||
|
symbol: 'LINK',
|
||||||
|
decimals: 18,
|
||||||
|
name: 'ChainLink Token',
|
||||||
|
iconUrl: 'https://crypto.com/price/coin-data/icon/LINK/color_icon.png',
|
||||||
|
aggregators: [
|
||||||
|
'Aave',
|
||||||
|
'Bancor',
|
||||||
|
'CMC',
|
||||||
|
'Crypto.com',
|
||||||
|
'CoinGecko',
|
||||||
|
'1inch',
|
||||||
|
'Paraswap',
|
||||||
|
'PMM',
|
||||||
|
'Zapper',
|
||||||
|
'Zerion',
|
||||||
|
'0x',
|
||||||
|
],
|
||||||
|
occurrences: 12,
|
||||||
|
unlisted: false
|
||||||
|
},
|
||||||
|
'0xc00e94cb662c3520282e6f5717214004a7f26888': {
|
||||||
|
address: '0xc00e94cb662c3520282e6f5717214004a7f26888',
|
||||||
|
symbol: 'COMP',
|
||||||
|
decimals: 18,
|
||||||
|
name: 'Compound',
|
||||||
|
iconUrl: 'https://crypto.com/price/coin-data/icon/COMP/color_icon.png',
|
||||||
|
aggregators: [
|
||||||
|
'Bancor',
|
||||||
|
'CMC',
|
||||||
|
'Crypto.com',
|
||||||
|
'CoinGecko',
|
||||||
|
'1inch',
|
||||||
|
'Paraswap',
|
||||||
|
'PMM',
|
||||||
|
'Zapper',
|
||||||
|
'Zerion',
|
||||||
|
'0x',
|
||||||
|
],
|
||||||
|
occurrences: 12,
|
||||||
|
unlisted: false
|
||||||
|
},
|
||||||
|
'0xfffffffff15abf397da76f1dcc1a1604f45126db': {
|
||||||
|
address: '0xfffffffff15abf397da76f1dcc1a1604f45126db',
|
||||||
|
symbol: 'FSW',
|
||||||
|
decimals: 18,
|
||||||
|
name: 'Falconswap',
|
||||||
|
iconUrl: 'https://assets.coingecko.com/coins/images/12256/thumb/falconswap.png?1598534184',
|
||||||
|
aggregators: [
|
||||||
|
'CoinGecko',
|
||||||
|
'1inch',
|
||||||
|
'Paraswap',
|
||||||
|
'Zapper',
|
||||||
|
'Zerion',
|
||||||
|
],
|
||||||
|
occurrences: 12,
|
||||||
|
unlisted: false
|
||||||
|
},
|
||||||
'0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f': {
|
'0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f': {
|
||||||
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
|
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
|
||||||
symbol: 'SNX',
|
symbol: 'SNX',
|
||||||
@ -425,6 +484,35 @@ const state = {
|
|||||||
decimals: 18,
|
decimals: 18,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
detectedTokens: [
|
||||||
|
{
|
||||||
|
address: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
|
||||||
|
decimals: 18,
|
||||||
|
symbol: "LINK",
|
||||||
|
image: "https://crypto.com/price/coin-data/icon/LINK/color_icon.png",
|
||||||
|
aggregators:[
|
||||||
|
"coinGecko","oneInch","paraswap","zapper","zerion"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: "0xc00e94Cb662C3520282E6f5717214004A7f26888",
|
||||||
|
decimals: 18,
|
||||||
|
symbol: "COMP",
|
||||||
|
image: "https://crypto.com/price/coin-data/icon/COMP/color_icon.png",
|
||||||
|
aggregators:[
|
||||||
|
"bancor","cmc","cryptocom","coinGecko","oneInch","paraswap","pmm","zapper","zerion","zeroEx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: "0xfffffffFf15AbF397dA76f1dcc1A1604F45126DB",
|
||||||
|
decimals: 18,
|
||||||
|
symbol: "FSW",
|
||||||
|
image: "https://assets.coingecko.com/coins/images/12256/thumb/falconswap.png?1598534184",
|
||||||
|
aggregators:[
|
||||||
|
"aave", "cmc","coinGecko","oneInch","paraswap","zapper","zerion"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
pendingTokens: {},
|
pendingTokens: {},
|
||||||
customNonceValue: '',
|
customNonceValue: '',
|
||||||
send: {
|
send: {
|
||||||
@ -1248,20 +1336,7 @@ const state = {
|
|||||||
method: 'eth_accounts',
|
method: 'eth_accounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://metamask.io',
|
origin: 'https://metamask.io',
|
||||||
request: {
|
|
||||||
method: 'eth_accounts',
|
|
||||||
params: [],
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 522690215,
|
|
||||||
origin: 'https://metamask.io',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1602643170686,
|
requestTime: 1602643170686,
|
||||||
response: {
|
|
||||||
id: 522690215,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: [],
|
|
||||||
},
|
|
||||||
responseTime: 1602643170688,
|
responseTime: 1602643170688,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
@ -1270,20 +1345,7 @@ const state = {
|
|||||||
method: 'eth_accounts',
|
method: 'eth_accounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://widget.getacute.io',
|
origin: 'https://widget.getacute.io',
|
||||||
request: {
|
|
||||||
method: 'eth_accounts',
|
|
||||||
params: [],
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 1620464600,
|
|
||||||
origin: 'https://widget.getacute.io',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1602643172935,
|
requestTime: 1602643172935,
|
||||||
response: {
|
|
||||||
id: 1620464600,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: [],
|
|
||||||
},
|
|
||||||
responseTime: 1602643172935,
|
responseTime: 1602643172935,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
@ -1292,19 +1354,7 @@ const state = {
|
|||||||
method: 'eth_accounts',
|
method: 'eth_accounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://app.uniswap.org',
|
origin: 'https://app.uniswap.org',
|
||||||
request: {
|
|
||||||
method: 'eth_accounts',
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 4279100021,
|
|
||||||
origin: 'https://app.uniswap.org',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1620710669962,
|
requestTime: 1620710669962,
|
||||||
response: {
|
|
||||||
id: 4279100021,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: [],
|
|
||||||
},
|
|
||||||
responseTime: 1620710669963,
|
responseTime: 1620710669963,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
@ -1313,19 +1363,7 @@ const state = {
|
|||||||
method: 'eth_requestAccounts',
|
method: 'eth_requestAccounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://app.uniswap.org',
|
origin: 'https://app.uniswap.org',
|
||||||
request: {
|
|
||||||
method: 'eth_requestAccounts',
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 4279100022,
|
|
||||||
origin: 'https://app.uniswap.org',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1620710686872,
|
requestTime: 1620710686872,
|
||||||
response: {
|
|
||||||
id: 4279100022,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: ['0x64a845a5b02460acf8a3d84503b0d68d028b4bb4'],
|
|
||||||
},
|
|
||||||
responseTime: 1620710693187,
|
responseTime: 1620710693187,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
@ -1334,19 +1372,7 @@ const state = {
|
|||||||
method: 'eth_requestAccounts',
|
method: 'eth_requestAccounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://app.uniswap.org',
|
origin: 'https://app.uniswap.org',
|
||||||
request: {
|
|
||||||
method: 'eth_requestAccounts',
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 4279100023,
|
|
||||||
origin: 'https://app.uniswap.org',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1620710693204,
|
requestTime: 1620710693204,
|
||||||
response: {
|
|
||||||
id: 4279100023,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: ['0x64a845a5b02460acf8a3d84503b0d68d028b4bb4'],
|
|
||||||
},
|
|
||||||
responseTime: 1620710693213,
|
responseTime: 1620710693213,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
@ -1355,20 +1381,7 @@ const state = {
|
|||||||
method: 'eth_accounts',
|
method: 'eth_accounts',
|
||||||
methodType: 'restricted',
|
methodType: 'restricted',
|
||||||
origin: 'https://app.uniswap.org',
|
origin: 'https://app.uniswap.org',
|
||||||
request: {
|
|
||||||
method: 'eth_accounts',
|
|
||||||
params: [],
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 4279100034,
|
|
||||||
origin: 'https://app.uniswap.org',
|
|
||||||
tabId: 5,
|
|
||||||
},
|
|
||||||
requestTime: 1620710712072,
|
requestTime: 1620710712072,
|
||||||
response: {
|
|
||||||
id: 4279100034,
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
result: ['0x64a845a5b02460acf8a3d84503b0d68d028b4bb4'],
|
|
||||||
},
|
|
||||||
responseTime: 1620710712075,
|
responseTime: 1620710712075,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
18
README.md
18
README.md
@ -60,9 +60,23 @@ You can run the linter by itself with `yarn lint`, and you can automatically fix
|
|||||||
|
|
||||||
Our e2e test suite can be run on either Firefox or Chrome. In either case, start by creating a test build by running `yarn build:test`.
|
Our e2e test suite can be run on either Firefox or Chrome. In either case, start by creating a test build by running `yarn build:test`.
|
||||||
|
|
||||||
Firefox e2e tests can be run with `yarn test:e2e:firefox`.
|
- Firefox e2e tests can be run with `yarn test:e2e:firefox`.
|
||||||
|
|
||||||
Chrome e2e tests can be run with `yarn test:e2e:chrome`, but they will only work if you have Chrome v79 installed. Update the `chromedriver` package to a version matching your local Chrome installation to run e2e tests on newer Chrome versions.
|
- Chrome e2e tests can be run with `yarn test:e2e:chrome`. The `chromedriver` package major version must match the major version of your local Chrome installation. If they don't match, update whichever is behind before running Chrome e2e tests.
|
||||||
|
|
||||||
|
- Single e2e tests can be run with `yarn test:e2e:single test/e2e/tests/TEST_NAME.spec.js` along with the options below.
|
||||||
|
|
||||||
|
```console
|
||||||
|
--browser Set the browser used; either 'chrome' or 'firefox'.
|
||||||
|
|
||||||
|
--leave-running Leaves the browser running after a test fails, along with anything else
|
||||||
|
that the test used (ganache, the test dapp, etc.).
|
||||||
|
|
||||||
|
--retries Set how many times the test should be retried upon failure. Default is 0.
|
||||||
|
```
|
||||||
|
|
||||||
|
An example for running `account-details` testcase with chrome and leaving the browser open would be:
|
||||||
|
`yarn test:e2e:single test/e2e/tests/account-details.spec.js --browser=chrome --leave-running`
|
||||||
|
|
||||||
### Changing dependencies
|
### Changing dependencies
|
||||||
|
|
||||||
|
4
app/_locales/am/messages.json
generated
4
app/_locales/am/messages.json
generated
@ -131,10 +131,10 @@
|
|||||||
"message": "ማሰሺያዎት አልተደገፈም..."
|
"message": "ማሰሺያዎት አልተደገፈም..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "ETH በ Wyre ይግዙ"
|
"message": "$1 በ Wyre ይግዙ"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre ክሬዲት ካርድ ተጠቅመው ETH በቀጥታ በ MetaMask መለያዎ ላይ እንዲያስቀምጡ ያስችልዎታል።"
|
"message": "Wyre ክሬዲት ካርድ ተጠቅመው $1 በቀጥታ በ MetaMask መለያዎ ላይ እንዲያስቀምጡ ያስችልዎታል።"
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "ባይት"
|
"message": "ባይት"
|
||||||
|
2
app/_locales/ar/messages.json
generated
2
app/_locales/ar/messages.json
generated
@ -148,7 +148,7 @@
|
|||||||
"message": "قم بشراء عملة إيثير بواسطة Wyre"
|
"message": "قم بشراء عملة إيثير بواسطة Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "يتيح لك Wyre استخدام بطاقة ائتمان لإيداع ETH مباشرة في حساب MetaMask الخاص بك."
|
"message": "يتيح لك Wyre استخدام بطاقة ائتمان لإيداع 1$ مباشرة في حساب MetaMask الخاص بك."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "بايتات"
|
"message": "بايتات"
|
||||||
|
4
app/_locales/bg/messages.json
generated
4
app/_locales/bg/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Браузърът ви не се поддържа ..."
|
"message": "Браузърът ви не се поддържа ..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Купете ETH с Wyre"
|
"message": "Купете $1 с Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre ви позволява да използвате кредитна карта, за да депозирате ETH право във вашата MetaMask сметка."
|
"message": "Wyre ви позволява да използвате кредитна карта, за да депозирате $1 право във вашата MetaMask сметка."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Байта"
|
"message": "Байта"
|
||||||
|
4
app/_locales/bn/messages.json
generated
4
app/_locales/bn/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "আপনার ব্রাউজার সমর্থিত নয়..."
|
"message": "আপনার ব্রাউজার সমর্থিত নয়..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Wyre দিয়ে ETH ক্রয় করুন"
|
"message": "Wyre দিয়ে $1 ক্রয় করুন"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre আপনার MetaMask অ্যাকাউন্টে সরাসরি ETH জমা করতে আপনাকে একটি ক্রেডিট কার্ড ব্যবহার করতে দেয়।"
|
"message": "Wyre আপনার MetaMask অ্যাকাউন্টে সরাসরি $1 জমা করতে আপনাকে একটি ক্রেডিট কার্ড ব্যবহার করতে দেয়।"
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "বাইটস"
|
"message": "বাইটস"
|
||||||
|
4
app/_locales/ca/messages.json
generated
4
app/_locales/ca/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "El teu navegador no és suportat..."
|
"message": "El teu navegador no és suportat..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Compra ETH amb Wyre"
|
"message": "Compra $1 amb Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre et permet utilitzar una targeta de crèdit per dipositar ETH directe al teu compte MetaMask."
|
"message": "Wyre et permet utilitzar una targeta de crèdit per dipositar $1 directe al teu compte MetaMask."
|
||||||
},
|
},
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"message": "Cancel·la"
|
"message": "Cancel·la"
|
||||||
|
4
app/_locales/da/messages.json
generated
4
app/_locales/da/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Din browser er ikke understøttet..."
|
"message": "Din browser er ikke understøttet..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Køb ETH med Wyre"
|
"message": "Køb $1 med Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre lader dig bruge et kreditkort til at indbetale ETH på din MetaMask-konto."
|
"message": "Wyre lader dig bruge et kreditkort til at indbetale $1 på din MetaMask-konto."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Byte"
|
"message": "Byte"
|
||||||
|
666
app/_locales/de/messages.json
generated
666
app/_locales/de/messages.json
generated
File diff suppressed because it is too large
Load Diff
654
app/_locales/el/messages.json
generated
654
app/_locales/el/messages.json
generated
File diff suppressed because it is too large
Load Diff
110
app/_locales/en/messages.json
generated
110
app/_locales/en/messages.json
generated
@ -160,6 +160,10 @@
|
|||||||
"addNetwork": {
|
"addNetwork": {
|
||||||
"message": "Add Network"
|
"message": "Add Network"
|
||||||
},
|
},
|
||||||
|
"addNetworkTooltipWarning": {
|
||||||
|
"message": "This network connection relies on third parties. This connection may be less reliable or enable third-parties to track activity. $1",
|
||||||
|
"description": "$1 is Learn more link"
|
||||||
|
},
|
||||||
"addSuggestedTokens": {
|
"addSuggestedTokens": {
|
||||||
"message": "Add Suggested Tokens"
|
"message": "Add Suggested Tokens"
|
||||||
},
|
},
|
||||||
@ -199,9 +203,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "I Agree"
|
"message": "I Agree"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "Aggregator network fee"
|
|
||||||
},
|
|
||||||
"airgapVault": {
|
"airgapVault": {
|
||||||
"message": "AirGap Vault"
|
"message": "AirGap Vault"
|
||||||
},
|
},
|
||||||
@ -259,12 +260,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "Approval and aggregator network fee"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "Approval Tx Gas Cost"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "Approve spend limit"
|
"message": "Approve spend limit"
|
||||||
},
|
},
|
||||||
@ -416,6 +411,14 @@
|
|||||||
"message": "Buy $1",
|
"message": "Buy $1",
|
||||||
"description": "$1 is the ticker symbol of a an asset the user is being prompted to purchase"
|
"description": "$1 is the ticker symbol of a an asset the user is being prompted to purchase"
|
||||||
},
|
},
|
||||||
|
"buyCryptoWithCoinbasePay": {
|
||||||
|
"message": "Buy $1 with Coinbase Pay",
|
||||||
|
"description": "$1 represents the crypto symbol to be purchased"
|
||||||
|
},
|
||||||
|
"buyCryptoWithCoinbasePayDescription": {
|
||||||
|
"message": "You can easily buy or transfer crypto with your Coinbase account.",
|
||||||
|
"description": "$1 represents the crypto symbol to be purchased"
|
||||||
|
},
|
||||||
"buyCryptoWithMoonPay": {
|
"buyCryptoWithMoonPay": {
|
||||||
"message": "Buy $1 with MoonPay",
|
"message": "Buy $1 with MoonPay",
|
||||||
"description": "$1 represents the cypto symbol to be purchased"
|
"description": "$1 represents the cypto symbol to be purchased"
|
||||||
@ -432,10 +435,10 @@
|
|||||||
"description": "$1 represents the crypto symbol to be purchased"
|
"description": "$1 represents the crypto symbol to be purchased"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Buy ETH with Wyre"
|
"message": "Buy $1 with Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre lets you use a debit card to deposit ETH right in to your MetaMask account."
|
"message": "Easy onboarding for purchases up to $ 1000. Fast interactive high limit purchase verification. Supports Debit/Credit Card, Apple Pay, Bank Transfers. Available in 100+ countries. Tokens deposit into your MetaMask Account"
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bytes"
|
"message": "Bytes"
|
||||||
@ -622,6 +625,9 @@
|
|||||||
"continue": {
|
"continue": {
|
||||||
"message": "Continue"
|
"message": "Continue"
|
||||||
},
|
},
|
||||||
|
"continueToCoinbasePay": {
|
||||||
|
"message": "Continue to Coinbase Pay"
|
||||||
|
},
|
||||||
"continueToMoonPay": {
|
"continueToMoonPay": {
|
||||||
"message": "Continue to MoonPay"
|
"message": "Continue to MoonPay"
|
||||||
},
|
},
|
||||||
@ -734,9 +740,6 @@
|
|||||||
"customGasSubTitle": {
|
"customGasSubTitle": {
|
||||||
"message": "Increasing fee may decrease processing times, but it is not guaranteed."
|
"message": "Increasing fee may decrease processing times, but it is not guaranteed."
|
||||||
},
|
},
|
||||||
"customNetworks": {
|
|
||||||
"message": "Custom networks"
|
|
||||||
},
|
|
||||||
"customSpendLimit": {
|
"customSpendLimit": {
|
||||||
"message": "Custom Spend Limit"
|
"message": "Custom Spend Limit"
|
||||||
},
|
},
|
||||||
@ -804,9 +807,6 @@
|
|||||||
"decryptRequest": {
|
"decryptRequest": {
|
||||||
"message": "Decrypt request"
|
"message": "Decrypt request"
|
||||||
},
|
},
|
||||||
"defaultTheme": {
|
|
||||||
"message": "Default"
|
|
||||||
},
|
|
||||||
"delete": {
|
"delete": {
|
||||||
"message": "Delete"
|
"message": "Delete"
|
||||||
},
|
},
|
||||||
@ -1187,10 +1187,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "External Extension"
|
"message": "External Extension"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 approval gas",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "Failed"
|
"message": "Failed"
|
||||||
},
|
},
|
||||||
@ -1251,6 +1247,10 @@
|
|||||||
"message": "All Flask APIs are experimental. They may be changed or removed without notice, or they might stay on Flask indefinitely without ever being migrated to stable MetaMask. Use them at your own risk.",
|
"message": "All Flask APIs are experimental. They may be changed or removed without notice, or they might stay on Flask indefinitely without ever being migrated to stable MetaMask. Use them at your own risk.",
|
||||||
"description": "This message warns developers about unstable Flask APIs"
|
"description": "This message warns developers about unstable Flask APIs"
|
||||||
},
|
},
|
||||||
|
"flaskWelcomeWarning4": {
|
||||||
|
"message": "Make sure to disable your regular MetaMask extension when using Flask.",
|
||||||
|
"description": "This message calls to pay attention about multiple versions of MetaMask running on the same site (Flask + Prod)"
|
||||||
|
},
|
||||||
"flaskWelcomeWarningAcceptButton": {
|
"flaskWelcomeWarningAcceptButton": {
|
||||||
"message": "I accept the risks",
|
"message": "I accept the risks",
|
||||||
"description": "this text is shown on a button, which the user presses to confirm they understand the risks of using Flask"
|
"description": "this text is shown on a button, which the user presses to confirm they understand the risks of using Flask"
|
||||||
@ -1442,6 +1442,9 @@
|
|||||||
"hide": {
|
"hide": {
|
||||||
"message": "Hide"
|
"message": "Hide"
|
||||||
},
|
},
|
||||||
|
"hideFullTransactionDetails": {
|
||||||
|
"message": "Hide full transaction details"
|
||||||
|
},
|
||||||
"hideSeedPhrase": {
|
"hideSeedPhrase": {
|
||||||
"message": "Hide seed phrase"
|
"message": "Hide seed phrase"
|
||||||
},
|
},
|
||||||
@ -1471,6 +1474,12 @@
|
|||||||
"history": {
|
"history": {
|
||||||
"message": "History"
|
"message": "History"
|
||||||
},
|
},
|
||||||
|
"ignoreAll": {
|
||||||
|
"message": "Ignore all"
|
||||||
|
},
|
||||||
|
"ignoreTokenWarning": {
|
||||||
|
"message": "If you hide tokens, they will not be shown in your wallet. However, you can still add them by searching for them."
|
||||||
|
},
|
||||||
"import": {
|
"import": {
|
||||||
"message": "Import",
|
"message": "Import",
|
||||||
"description": "Button to import an account from a selected file"
|
"description": "Button to import an account from a selected file"
|
||||||
@ -1520,6 +1529,10 @@
|
|||||||
"importWallet": {
|
"importWallet": {
|
||||||
"message": "Import wallet"
|
"message": "Import wallet"
|
||||||
},
|
},
|
||||||
|
"importWithCount": {
|
||||||
|
"message": "Import $1",
|
||||||
|
"description": "$1 will the number of detected tokens that are selected for importing, if all of them are selected then $1 will be all"
|
||||||
|
},
|
||||||
"importYourExisting": {
|
"importYourExisting": {
|
||||||
"message": "Import your existing wallet using a Secret Recovery Phrase"
|
"message": "Import your existing wallet using a Secret Recovery Phrase"
|
||||||
},
|
},
|
||||||
@ -1714,6 +1727,9 @@
|
|||||||
"levelArrow": {
|
"levelArrow": {
|
||||||
"message": "level arrow"
|
"message": "level arrow"
|
||||||
},
|
},
|
||||||
|
"lightTheme": {
|
||||||
|
"message": "Light"
|
||||||
|
},
|
||||||
"likeToImportTokens": {
|
"likeToImportTokens": {
|
||||||
"message": "Would you like to import these tokens?"
|
"message": "Would you like to import these tokens?"
|
||||||
},
|
},
|
||||||
@ -2027,6 +2043,13 @@
|
|||||||
"newToMetaMask": {
|
"newToMetaMask": {
|
||||||
"message": "New to MetaMask?"
|
"message": "New to MetaMask?"
|
||||||
},
|
},
|
||||||
|
"newTokensImportedMessage": {
|
||||||
|
"message": "You’ve successfully imported $1.",
|
||||||
|
"description": "$1 is the string of symbols of all the tokens imported"
|
||||||
|
},
|
||||||
|
"newTokensImportedTitle": {
|
||||||
|
"message": "Token imported"
|
||||||
|
},
|
||||||
"newTotal": {
|
"newTotal": {
|
||||||
"message": "New Total"
|
"message": "New Total"
|
||||||
},
|
},
|
||||||
@ -2109,6 +2132,9 @@
|
|||||||
"notEnoughGas": {
|
"notEnoughGas": {
|
||||||
"message": "Not Enough Gas"
|
"message": "Not Enough Gas"
|
||||||
},
|
},
|
||||||
|
"notifications": {
|
||||||
|
"message": "Notifications"
|
||||||
|
},
|
||||||
"notifications10ActionText": {
|
"notifications10ActionText": {
|
||||||
"message": "Visit in settings",
|
"message": "Visit in settings",
|
||||||
"description": "The 'call to action' on the button, or link, of the 'Visit in settings' notification. Upon clicking, users will be taken to settings page."
|
"description": "The 'call to action' on the button, or link, of the 'Visit in settings' notification. Upon clicking, users will be taken to settings page."
|
||||||
@ -2131,6 +2157,15 @@
|
|||||||
"notifications11Title": {
|
"notifications11Title": {
|
||||||
"message": "Scam and security risks"
|
"message": "Scam and security risks"
|
||||||
},
|
},
|
||||||
|
"notifications12ActionText": {
|
||||||
|
"message": "Enable dark mode"
|
||||||
|
},
|
||||||
|
"notifications12Description": {
|
||||||
|
"message": "Dark mode on Extension is finally here! To turn it on, go to Settings -> Experimental and select one of the display options: Light, Dark, System."
|
||||||
|
},
|
||||||
|
"notifications12Title": {
|
||||||
|
"message": "Wen dark mode? Now dark mode! 🕶️🦊"
|
||||||
|
},
|
||||||
"notifications1Description": {
|
"notifications1Description": {
|
||||||
"message": "MetaMask Mobile users can now swap tokens inside their mobile wallet. Scan the QR code to get the mobile app and start swapping.",
|
"message": "MetaMask Mobile users can now swap tokens inside their mobile wallet. Scan the QR code to get the mobile app and start swapping.",
|
||||||
"description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature."
|
"description": "Description of a notification in the 'See What's New' popup. Describes the swapping on mobile feature."
|
||||||
@ -2220,6 +2255,19 @@
|
|||||||
"notifications9Title": {
|
"notifications9Title": {
|
||||||
"message": "👓 We are making transactions easier to read."
|
"message": "👓 We are making transactions easier to read."
|
||||||
},
|
},
|
||||||
|
"notificationsEmptyText": {
|
||||||
|
"message": "Nothing to see here."
|
||||||
|
},
|
||||||
|
"notificationsHeader": {
|
||||||
|
"message": "Notifications"
|
||||||
|
},
|
||||||
|
"notificationsInfos": {
|
||||||
|
"message": "$1 from $2",
|
||||||
|
"description": "$1 is the date at which the notification has been dispatched and $2 is the link to the snap that dispatched the notification."
|
||||||
|
},
|
||||||
|
"notificationsMarkAllAsRead": {
|
||||||
|
"message": "Mark all as read"
|
||||||
|
},
|
||||||
"numberOfNewTokensDetected": {
|
"numberOfNewTokensDetected": {
|
||||||
"message": "$1 new tokens found in this account",
|
"message": "$1 new tokens found in this account",
|
||||||
"description": "$1 is the number of new tokens detected"
|
"description": "$1 is the number of new tokens detected"
|
||||||
@ -2299,9 +2347,6 @@
|
|||||||
"onlyConnectTrust": {
|
"onlyConnectTrust": {
|
||||||
"message": "Only connect with sites you trust."
|
"message": "Only connect with sites you trust."
|
||||||
},
|
},
|
||||||
"onlyInteractWith": {
|
|
||||||
"message": "Only interact with entities you trust."
|
|
||||||
},
|
|
||||||
"openFullScreenForLedgerWebHid": {
|
"openFullScreenForLedgerWebHid": {
|
||||||
"message": "Open MetaMask in full screen to connect your ledger via WebHID.",
|
"message": "Open MetaMask in full screen to connect your ledger via WebHID.",
|
||||||
"description": "Shown to the user on the confirm screen when they are viewing MetaMask in a popup window but need to connect their ledger via webhid."
|
"description": "Shown to the user on the confirm screen when they are viewing MetaMask in a popup window but need to connect their ledger via webhid."
|
||||||
@ -2321,6 +2366,9 @@
|
|||||||
"origin": {
|
"origin": {
|
||||||
"message": "Origin"
|
"message": "Origin"
|
||||||
},
|
},
|
||||||
|
"osTheme": {
|
||||||
|
"message": "System"
|
||||||
|
},
|
||||||
"padlock": {
|
"padlock": {
|
||||||
"message": "Padlock"
|
"message": "Padlock"
|
||||||
},
|
},
|
||||||
@ -2394,6 +2442,10 @@
|
|||||||
"message": "See address, account balance, activity and suggest transactions to approve",
|
"message": "See address, account balance, activity and suggest transactions to approve",
|
||||||
"description": "The description for the `eth_accounts` permission"
|
"description": "The description for the `eth_accounts` permission"
|
||||||
},
|
},
|
||||||
|
"permission_longRunning": {
|
||||||
|
"message": "Run indefinitely.",
|
||||||
|
"description": "The description for the `endowment:long-running` permission"
|
||||||
|
},
|
||||||
"permission_manageBip44Keys": {
|
"permission_manageBip44Keys": {
|
||||||
"message": "Control your \"$1\" accounts and assets.",
|
"message": "Control your \"$1\" accounts and assets.",
|
||||||
"description": "The description for the `snap_getBip44Entropy_*` permission. $1 is the name of a protocol, e.g. 'Filecoin'."
|
"description": "The description for the `snap_getBip44Entropy_*` permission. $1 is the name of a protocol, e.g. 'Filecoin'."
|
||||||
@ -2423,6 +2475,9 @@
|
|||||||
"message": "+ $1 more",
|
"message": "+ $1 more",
|
||||||
"description": "$1 is a number of additional but unshown items in a list- this message will be shown in place of those items"
|
"description": "$1 is a number of additional but unshown items in a list- this message will be shown in place of those items"
|
||||||
},
|
},
|
||||||
|
"popularCustomNetworks": {
|
||||||
|
"message": "Popular custom networks"
|
||||||
|
},
|
||||||
"preferredLedgerConnectionType": {
|
"preferredLedgerConnectionType": {
|
||||||
"message": "Preferred Ledger Connection Type",
|
"message": "Preferred Ledger Connection Type",
|
||||||
"description": "A header for a dropdown in the advanced section of settings. Appears above the ledgerConnectionPreferenceDescription message"
|
"description": "A header for a dropdown in the advanced section of settings. Appears above the ledgerConnectionPreferenceDescription message"
|
||||||
@ -3621,6 +3676,10 @@
|
|||||||
"tokenSymbol": {
|
"tokenSymbol": {
|
||||||
"message": "Token Symbol"
|
"message": "Token Symbol"
|
||||||
},
|
},
|
||||||
|
"tokensFoundTitle": {
|
||||||
|
"message": "$1 new tokens found",
|
||||||
|
"description": "$1 is the number of new tokens detected"
|
||||||
|
},
|
||||||
"tooltipApproveButton": {
|
"tooltipApproveButton": {
|
||||||
"message": "I understand"
|
"message": "I understand"
|
||||||
},
|
},
|
||||||
@ -3926,6 +3985,9 @@
|
|||||||
"walletCreationSuccessTitle": {
|
"walletCreationSuccessTitle": {
|
||||||
"message": "Wallet creation successful"
|
"message": "Wallet creation successful"
|
||||||
},
|
},
|
||||||
|
"warning": {
|
||||||
|
"message": "Warning"
|
||||||
|
},
|
||||||
"weak": {
|
"weak": {
|
||||||
"message": "Weak"
|
"message": "Weak"
|
||||||
},
|
},
|
||||||
|
1758
app/_locales/es/messages.json
generated
1758
app/_locales/es/messages.json
generated
File diff suppressed because it is too large
Load Diff
17
app/_locales/es_419/messages.json
generated
17
app/_locales/es_419/messages.json
generated
@ -179,9 +179,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "Acepto"
|
"message": "Acepto"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "Cuota de red de agregador"
|
|
||||||
},
|
|
||||||
"alertDisableTooltip": {
|
"alertDisableTooltip": {
|
||||||
"message": "Esto se puede modificar en \"Configuración > Alertas\""
|
"message": "Esto se puede modificar en \"Configuración > Alertas\""
|
||||||
},
|
},
|
||||||
@ -233,12 +230,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "Cuota de red de agregador y aprobación"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "Costo de gas por transacción de aprobación"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "Aprobar límite de gastos"
|
"message": "Aprobar límite de gastos"
|
||||||
},
|
},
|
||||||
@ -372,10 +363,10 @@
|
|||||||
"message": "Comprar"
|
"message": "Comprar"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Comprar ETH con Wyre"
|
"message": "Comprar $1 con Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre le permite usar una tarjeta de débito para depositar ETH directamente en su cuenta de MetaMask."
|
"message": "Wyre le permite usar una tarjeta de débito para depositar $1 directamente en su cuenta de MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bytes"
|
"message": "Bytes"
|
||||||
@ -1047,10 +1038,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "Extensión externa"
|
"message": "Extensión externa"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 de gas por aprobación",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "Con errores"
|
"message": "Con errores"
|
||||||
},
|
},
|
||||||
|
4
app/_locales/et/messages.json
generated
4
app/_locales/et/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Teie lehitsejat ei toetata..."
|
"message": "Teie lehitsejat ei toetata..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Ostke ETH-d Wyre'iga"
|
"message": "Ostke $1 -d Wyre'iga"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre võimaldab kasutada krediitkaarti, et teha ETH sissemakse otse MetaMaski kontole."
|
"message": "Wyre võimaldab kasutada krediitkaarti, et teha $1 sissemakse otse MetaMaski kontole."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Baidid"
|
"message": "Baidid"
|
||||||
|
4
app/_locales/fa/messages.json
generated
4
app/_locales/fa/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "مرورگر شما پشتیبانی نمیشود"
|
"message": "مرورگر شما پشتیبانی نمیشود"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "ETH را توسط Wyre خریداری نمایید"
|
"message": "$1 را توسط Wyre خریداری نمایید"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre به شما اجازه میدهد تا یک کردیت کارت را جهت پرداخت ETH مستقیمًا به حساب MetaMask تان استفاده نمایید."
|
"message": "Wyre به شما اجازه میدهد تا یک کردیت کارت را جهت پرداخت 1$ مستقیمًا به حساب MetaMask تان استفاده نمایید."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "بایت ها"
|
"message": "بایت ها"
|
||||||
|
4
app/_locales/fi/messages.json
generated
4
app/_locales/fi/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Selaintasi ei tueta..."
|
"message": "Selaintasi ei tueta..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Osta ETH:ta Wyrella"
|
"message": "Osta $1 :ta Wyrella"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre antaa sinun käyttää luottokorttia, jotta voit tallettaa ETH:ta suoraan MetaMask-tilillesi."
|
"message": "Wyre antaa sinun käyttää luottokorttia, jotta voit tallettaa $1 :ta suoraan MetaMask-tilillesi."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Tavua"
|
"message": "Tavua"
|
||||||
|
4
app/_locales/fil/messages.json
generated
4
app/_locales/fil/messages.json
generated
@ -122,10 +122,10 @@
|
|||||||
"message": "Hindi sinusuportahan ang iyong Browser..."
|
"message": "Hindi sinusuportahan ang iyong Browser..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Bumili ng ETH gamit ang Wyre"
|
"message": "Bumili ng $1 gamit ang Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Binibigyang-daan ka ng Wyre na gumamit ng credit card para magdeposito ng ETH nang direkta sa iyong MetaMask account."
|
"message": "Binibigyang-daan ka ng Wyre na gumamit ng credit card para magdeposito ng $1 nang direkta sa iyong MetaMask account."
|
||||||
},
|
},
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"message": "Kanselahin"
|
"message": "Kanselahin"
|
||||||
|
652
app/_locales/fr/messages.json
generated
652
app/_locales/fr/messages.json
generated
File diff suppressed because it is too large
Load Diff
2
app/_locales/he/messages.json
generated
2
app/_locales/he/messages.json
generated
@ -140,7 +140,7 @@
|
|||||||
"message": "רכישת את'ר עם Wyre"
|
"message": "רכישת את'ר עם Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre מאפשרת לך להשתמש בכרטיס אשראי כדי להפקיד ETH ישירות בחשבון ה-MetaMask שלך."
|
"message": "Wyre מאפשרת לך להשתמש בכרטיס אשראי כדי להפקיד $1 ישירות בחשבון ה-MetaMask שלך."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "בייטים"
|
"message": "בייטים"
|
||||||
|
656
app/_locales/hi/messages.json
generated
656
app/_locales/hi/messages.json
generated
File diff suppressed because it is too large
Load Diff
4
app/_locales/hr/messages.json
generated
4
app/_locales/hr/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Vaš se preglednik ne podržava..."
|
"message": "Vaš se preglednik ne podržava..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kupi ETH Wyerom"
|
"message": "Kupi $1 Wyerom"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyreom vam se omogućava korištenje kreditnom karticom za polaganje ETH-a izravno na vaš račun za MetaMask."
|
"message": "Wyreom vam se omogućava korištenje kreditnom karticom za polaganje $1 -a izravno na vaš račun za MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bajtovi"
|
"message": "Bajtovi"
|
||||||
|
2
app/_locales/hu/messages.json
generated
2
app/_locales/hu/messages.json
generated
@ -137,7 +137,7 @@
|
|||||||
"message": "Az ön böngészője nem támogatott..."
|
"message": "Az ön böngészője nem támogatott..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Vásároljon ETH-t a Wyre-rel"
|
"message": "Vásároljon $1 -t a Wyre-rel"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "A Wyre segítségével egyensen a MetaMaks fiókjában tehet letétbe ETH-t."
|
"message": "A Wyre segítségével egyensen a MetaMaks fiókjában tehet letétbe ETH-t."
|
||||||
|
654
app/_locales/id/messages.json
generated
654
app/_locales/id/messages.json
generated
File diff suppressed because it is too large
Load Diff
17
app/_locales/it/messages.json
generated
17
app/_locales/it/messages.json
generated
@ -67,9 +67,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "Acconsento"
|
"message": "Acconsento"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "Tassa per la rete aggregatore"
|
|
||||||
},
|
|
||||||
"alertDisableTooltip": {
|
"alertDisableTooltip": {
|
||||||
"message": "Può essere cambiato in \"Impostazioni > Avvisi\""
|
"message": "Può essere cambiato in \"Impostazioni > Avvisi\""
|
||||||
},
|
},
|
||||||
@ -117,12 +114,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "Tassa di approvazione per la rete aggregatore"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "Costo Gas Approvazione Tx"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "Approva"
|
"message": "Approva"
|
||||||
},
|
},
|
||||||
@ -198,10 +189,10 @@
|
|||||||
"message": "Compra"
|
"message": "Compra"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Compra ETH con Wyre"
|
"message": "Compra $1 con Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre ti consente di usare la carta di credito per depositare ETH direttamente nel tuo account MetaMask."
|
"message": "Wyre ti consente di usare la carta di credito per depositare $1 direttamente nel tuo account MetaMask."
|
||||||
},
|
},
|
||||||
"canToggleInSettings": {
|
"canToggleInSettings": {
|
||||||
"message": "Puoi riabilitare questa notifica in Impostazioni -> Avvisi."
|
"message": "Puoi riabilitare questa notifica in Impostazioni -> Avvisi."
|
||||||
@ -568,10 +559,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "Estensione Esterna"
|
"message": "Estensione Esterna"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 gas approvazione",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "Fallita"
|
"message": "Fallita"
|
||||||
},
|
},
|
||||||
|
654
app/_locales/ja/messages.json
generated
654
app/_locales/ja/messages.json
generated
File diff suppressed because it is too large
Load Diff
4
app/_locales/kn/messages.json
generated
4
app/_locales/kn/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "ನಿಮ್ಮ ಬ್ರೌಸರ್ ಬೆಂಬಲಿಸುತ್ತಿಲ್ಲ..."
|
"message": "ನಿಮ್ಮ ಬ್ರೌಸರ್ ಬೆಂಬಲಿಸುತ್ತಿಲ್ಲ..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Wyre ನೊಂದಿಗೆ ETH ಖರೀದಿಸಿ"
|
"message": "Wyre ನೊಂದಿಗೆ $1 ಖರೀದಿಸಿ"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "ನಿಮ್ಮ MetaMask ಖಾತೆಗೆ ETH ಅನ್ನು ಜಮಾ ಮಾಡಲು ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಬಳಸಲು Wyre ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ."
|
"message": "ನಿಮ್ಮ MetaMask ಖಾತೆಗೆ $1 ಅನ್ನು ಜಮಾ ಮಾಡಲು ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಬಳಸಲು Wyre ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "ಬೈಟ್ಗಳು"
|
"message": "ಬೈಟ್ಗಳು"
|
||||||
|
652
app/_locales/ko/messages.json
generated
652
app/_locales/ko/messages.json
generated
File diff suppressed because it is too large
Load Diff
4
app/_locales/lt/messages.json
generated
4
app/_locales/lt/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Jūsų naršyklė neatpažįstama..."
|
"message": "Jūsų naršyklė neatpažįstama..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Pirkti ETH su „Wyre“"
|
"message": "Pirkti $1 su „Wyre“"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "„Wyre“ leidžia naudotis kreditine kortele norint įnešti ETH tiesiai į jūsų „MetaMask“ paskyrą."
|
"message": "„Wyre“ leidžia naudotis kreditine kortele norint įnešti $1 tiesiai į jūsų „MetaMask“ paskyrą."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Baitai"
|
"message": "Baitai"
|
||||||
|
4
app/_locales/lv/messages.json
generated
4
app/_locales/lv/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Jūsu pārlūkprogramma netiek atbalstīta..."
|
"message": "Jūsu pārlūkprogramma netiek atbalstīta..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Pirkt ETH ar Wyre"
|
"message": "Pirkt $1 ar Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre ļauj noguldīt ETH tieši jūsu MetaMask kontā, izmantojot kredītkarti."
|
"message": "Wyre ļauj noguldīt $1 tieši jūsu MetaMask kontā, izmantojot kredītkarti."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Baiti"
|
"message": "Baiti"
|
||||||
|
4
app/_locales/ms/messages.json
generated
4
app/_locales/ms/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Pelayar anda tidak disokong..."
|
"message": "Pelayar anda tidak disokong..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Beli ETH dengan Wyre"
|
"message": "Beli $1 dengan Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre membolehkan anda menggunakan kad kredit untuk mendeposit ETH secara terus ke dalam akaun MetaMask anda."
|
"message": "Wyre membolehkan anda menggunakan kad kredit untuk mendeposit $1 secara terus ke dalam akaun MetaMask anda."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bait"
|
"message": "Bait"
|
||||||
|
4
app/_locales/no/messages.json
generated
4
app/_locales/no/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Nettleseren din støttes ikke ..."
|
"message": "Nettleseren din støttes ikke ..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kjøp ETH med Wyre"
|
"message": "Kjøp $1 med Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre lar deg bruke et kredittkort for å sette inn ETH rett på MetaMask-kontoen din."
|
"message": "Wyre lar deg bruke et kredittkort for å sette inn $1 rett på MetaMask-kontoen din."
|
||||||
},
|
},
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"message": "Avbryt"
|
"message": "Avbryt"
|
||||||
|
17
app/_locales/ph/messages.json
generated
17
app/_locales/ph/messages.json
generated
@ -91,9 +91,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "Sang-ayon ako"
|
"message": "Sang-ayon ako"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "Bayarin sa aggregator network"
|
|
||||||
},
|
|
||||||
"alertDisableTooltip": {
|
"alertDisableTooltip": {
|
||||||
"message": "Mababago ito sa \"Mga Setting > Mga Alerto\""
|
"message": "Mababago ito sa \"Mga Setting > Mga Alerto\""
|
||||||
},
|
},
|
||||||
@ -141,12 +138,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "Bayarin sa pag-apruba at aggregator network"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "Approval Tx Gas Cost"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "Aprubahan ang limitasyon sa paggastos"
|
"message": "Aprubahan ang limitasyon sa paggastos"
|
||||||
},
|
},
|
||||||
@ -237,10 +228,10 @@
|
|||||||
"message": "Bumili"
|
"message": "Bumili"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Bumili ng ETH gamit ang Wyre"
|
"message": "Bumili ng $1 gamit ang Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Binibigyang-daan ka ng Wyre na gumamit ng debit card para mag-deposit ng ETH sa mismong MetaMask account mo."
|
"message": "Binibigyang-daan ka ng Wyre na gumamit ng debit card para mag-deposit ng $1 sa mismong MetaMask account mo."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bytes"
|
"message": "Bytes"
|
||||||
@ -674,10 +665,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "External Extension"
|
"message": "External Extension"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 na pag-apruba sa gas",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "Hindi matagumpay"
|
"message": "Hindi matagumpay"
|
||||||
},
|
},
|
||||||
|
4
app/_locales/pl/messages.json
generated
4
app/_locales/pl/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Twoja przeglądarka nie jest obsługiwana..."
|
"message": "Twoja przeglądarka nie jest obsługiwana..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kup ETH poprzez Wyre"
|
"message": "Kup $1 poprzez Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Dzięki Wyre możesz użyć karty kredytowej, aby wpłacić ETH bezpośrednio na swoje konto MetaMask."
|
"message": "Dzięki Wyre możesz użyć karty kredytowej, aby wpłacić $1 bezpośrednio na swoje konto MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bajty"
|
"message": "Bajty"
|
||||||
|
3587
app/_locales/pt/messages.json
generated
3587
app/_locales/pt/messages.json
generated
File diff suppressed because it is too large
Load Diff
17
app/_locales/pt_BR/messages.json
generated
17
app/_locales/pt_BR/messages.json
generated
@ -179,9 +179,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "Concordo"
|
"message": "Concordo"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "Taxa de rede do agregador"
|
|
||||||
},
|
|
||||||
"alertDisableTooltip": {
|
"alertDisableTooltip": {
|
||||||
"message": "Isso pode ser alterado em \"Configurações > Alertas\""
|
"message": "Isso pode ser alterado em \"Configurações > Alertas\""
|
||||||
},
|
},
|
||||||
@ -233,12 +230,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "Taxa de aprovação e da rede do agregador"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "Custo em gás da transação de aprovação"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "Aprovar limite de gastos"
|
"message": "Aprovar limite de gastos"
|
||||||
},
|
},
|
||||||
@ -372,10 +363,10 @@
|
|||||||
"message": "Comprar"
|
"message": "Comprar"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Comprar ETH com Wyre"
|
"message": "Comprar $1 com Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Com o Wyre, você pode usar um cartão de débito para depositar ETH diretamente na sua conta da MetaMask."
|
"message": "Com o Wyre, você pode usar um cartão de débito para depositar $1 diretamente na sua conta da MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bytes"
|
"message": "Bytes"
|
||||||
@ -1031,10 +1022,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "Extensão externa"
|
"message": "Extensão externa"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 de gás por aprovação",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "Falhou"
|
"message": "Falhou"
|
||||||
},
|
},
|
||||||
|
4
app/_locales/ro/messages.json
generated
4
app/_locales/ro/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Browserul dvs. nu este compatibil..."
|
"message": "Browserul dvs. nu este compatibil..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Cumpărați ETH cu Wyre"
|
"message": "Cumpărați $1 cu Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre vă permite să folosiți un card de credit pentru a depune ETH direct în contul dvs. MetaMask."
|
"message": "Wyre vă permite să folosiți un card de credit pentru a depune $1 direct în contul dvs. MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Octeți"
|
"message": "Octeți"
|
||||||
|
656
app/_locales/ru/messages.json
generated
656
app/_locales/ru/messages.json
generated
File diff suppressed because it is too large
Load Diff
4
app/_locales/sk/messages.json
generated
4
app/_locales/sk/messages.json
generated
@ -131,10 +131,10 @@
|
|||||||
"message": "Váš prehliadač nie je podporovaný..."
|
"message": "Váš prehliadač nie je podporovaný..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kúpte ETH s Wyre"
|
"message": "Kúpte $1 s Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre vám umožňuje použiť kreditnú kartu na vloženie depozitu ETH priamo na váš účet MetaMask."
|
"message": "Wyre vám umožňuje použiť kreditnú kartu na vloženie depozitu $1 priamo na váš účet MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bajty"
|
"message": "Bajty"
|
||||||
|
4
app/_locales/sl/messages.json
generated
4
app/_locales/sl/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Vaš brskalnik ni podptrt ..."
|
"message": "Vaš brskalnik ni podptrt ..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kupi ETH z Wyre"
|
"message": "Kupi $1 z Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre vam omogoča, da s kreditno kartico nakažete ETH neposredno na svoj račun MetaMask."
|
"message": "Wyre vam omogoča, da s kreditno kartico nakažete $1 neposredno na svoj račun MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bajti"
|
"message": "Bajti"
|
||||||
|
4
app/_locales/sr/messages.json
generated
4
app/_locales/sr/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Vaš pregledač nije podržan..."
|
"message": "Vaš pregledač nije podržan..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Kupite ETH preko servisa Wyre"
|
"message": "Kupite $1 preko servisa Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre vam dozvoljava da koristite kreditnu karticu kako biste deponovali ETH pravo na vaš MetaMask nalog."
|
"message": "Wyre vam dozvoljava da koristite kreditnu karticu kako biste deponovali $1 pravo na vaš MetaMask nalog."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Bajtovi"
|
"message": "Bajtovi"
|
||||||
|
4
app/_locales/sv/messages.json
generated
4
app/_locales/sv/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Din webbläsare stöds inte..."
|
"message": "Din webbläsare stöds inte..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Köp ETH med Wyre"
|
"message": "Köp $1 med Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre låter dig använda ett kreditkort för att sätta in ETH direkt på ditt MetaMask-konto."
|
"message": "Wyre låter dig använda ett kreditkort för att sätta in $1 direkt på ditt MetaMask-konto."
|
||||||
},
|
},
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"message": "Avbryt"
|
"message": "Avbryt"
|
||||||
|
4
app/_locales/sw/messages.json
generated
4
app/_locales/sw/messages.json
generated
@ -134,10 +134,10 @@
|
|||||||
"message": "Kivinjari chaku hakiwezeshwi..."
|
"message": "Kivinjari chaku hakiwezeshwi..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Nunua ETH kwa kutumia Wyre"
|
"message": "Nunua $1 kwa kutumia Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre inakuwezesha kutumia kadi ya benki kuweka ETH moja kwa moja kwenye akaunti yako ya MetaMask."
|
"message": "Wyre inakuwezesha kutumia kadi ya benki kuweka $1 moja kwa moja kwenye akaunti yako ya MetaMask."
|
||||||
},
|
},
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"message": "Ghairi"
|
"message": "Ghairi"
|
||||||
|
700
app/_locales/tl/messages.json
generated
700
app/_locales/tl/messages.json
generated
File diff suppressed because it is too large
Load Diff
658
app/_locales/tr/messages.json
generated
658
app/_locales/tr/messages.json
generated
File diff suppressed because it is too large
Load Diff
4
app/_locales/uk/messages.json
generated
4
app/_locales/uk/messages.json
generated
@ -137,10 +137,10 @@
|
|||||||
"message": "Ваш браузер не підтримується..."
|
"message": "Ваш браузер не підтримується..."
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "Купити ETH через Wyre"
|
"message": "Купити $1 через Wyre"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre дає змогу використовувати кредитну картку для внесення валюти ETH безпосередньо у свій гаманець MetaMask."
|
"message": "Wyre дає змогу використовувати кредитну картку для внесення валюти $1 безпосередньо у свій гаманець MetaMask."
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "Байти"
|
"message": "Байти"
|
||||||
|
652
app/_locales/vi/messages.json
generated
652
app/_locales/vi/messages.json
generated
File diff suppressed because it is too large
Load Diff
3980
app/_locales/zh/messages.json
generated
Normal file
3980
app/_locales/zh/messages.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
app/_locales/zh_CN/messages.json
generated
17
app/_locales/zh_CN/messages.json
generated
@ -179,9 +179,6 @@
|
|||||||
"affirmAgree": {
|
"affirmAgree": {
|
||||||
"message": "我同意"
|
"message": "我同意"
|
||||||
},
|
},
|
||||||
"aggregatorFeeCost": {
|
|
||||||
"message": "聚集器网络手续费"
|
|
||||||
},
|
|
||||||
"alertDisableTooltip": {
|
"alertDisableTooltip": {
|
||||||
"message": "这个可以在“设置 > 提醒”中进行更改"
|
"message": "这个可以在“设置 > 提醒”中进行更改"
|
||||||
},
|
},
|
||||||
@ -233,12 +230,6 @@
|
|||||||
"message": "MetaMask Flask",
|
"message": "MetaMask Flask",
|
||||||
"description": "The name of the application (Flask)"
|
"description": "The name of the application (Flask)"
|
||||||
},
|
},
|
||||||
"approvalAndAggregatorTxFeeCost": {
|
|
||||||
"message": "批准聚合商网络手续费"
|
|
||||||
},
|
|
||||||
"approvalTxGasCost": {
|
|
||||||
"message": "批准交易燃料成本"
|
|
||||||
},
|
|
||||||
"approve": {
|
"approve": {
|
||||||
"message": "批准消费限额"
|
"message": "批准消费限额"
|
||||||
},
|
},
|
||||||
@ -372,10 +363,10 @@
|
|||||||
"message": "购买"
|
"message": "购买"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "使用 Wyre 购买 ETH"
|
"message": "使用 Wyre 购买 $1"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "您可以通过 Wyre 使用信用卡将 ETH 存入您的 MetaMask 账户。"
|
"message": "您可以通过 Wyre 使用信用卡将 $1 存入您的 MetaMask 账户。"
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "字节"
|
"message": "字节"
|
||||||
@ -1017,10 +1008,6 @@
|
|||||||
"externalExtension": {
|
"externalExtension": {
|
||||||
"message": "外部扩展"
|
"message": "外部扩展"
|
||||||
},
|
},
|
||||||
"extraApprovalGas": {
|
|
||||||
"message": "+$1 批准燃料",
|
|
||||||
"description": "Expresses an additional gas amount the user will have to pay, on top of some other displayed amount. $1 is a decimal amount of gas"
|
|
||||||
},
|
|
||||||
"failed": {
|
"failed": {
|
||||||
"message": "失败"
|
"message": "失败"
|
||||||
},
|
},
|
||||||
|
4
app/_locales/zh_TW/messages.json
generated
4
app/_locales/zh_TW/messages.json
generated
@ -140,10 +140,10 @@
|
|||||||
"message": "買"
|
"message": "買"
|
||||||
},
|
},
|
||||||
"buyWithWyre": {
|
"buyWithWyre": {
|
||||||
"message": "用 Wyre 購買 ETH"
|
"message": "用 Wyre 購買 $1"
|
||||||
},
|
},
|
||||||
"buyWithWyreDescription": {
|
"buyWithWyreDescription": {
|
||||||
"message": "Wyre 讓你使用信用卡在 MetaMask 帳號中直接存入 ETH。"
|
"message": "Wyre 讓你使用信用卡在 MetaMask 帳號中直接存入 $1 。"
|
||||||
},
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"message": "位元組"
|
"message": "位元組"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
||||||
{{@if(it.useLavamoat)}}
|
{{@if(it.applyLavaMoat)}}
|
||||||
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="./index-rtl.css" title="rtl" disabled>
|
<link rel="stylesheet" type="text/css" href="./index-rtl.css" title="rtl" disabled>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app-content"></div>
|
<div id="app-content"><div id="app-loader">Loading...</div></div>
|
||||||
<div id="popover-content"></div>
|
<div id="popover-content"></div>
|
||||||
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
||||||
{{@if(it.useLavamoat)}}
|
{{@if(it.applyLavaMoat)}}
|
||||||
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
1
app/images/bsc-filled.svg
Normal file
1
app/images/bsc-filled.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 10 KiB |
BIN
app/images/darkmode-banner.png
Normal file
BIN
app/images/darkmode-banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
1
app/images/palm.svg
Normal file
1
app/images/palm.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 314 KiB |
81
app/manifest/v3/_base.json
Normal file
81
app/manifest/v3/_base.json
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "images/icon-16.png",
|
||||||
|
"19": "images/icon-19.png",
|
||||||
|
"32": "images/icon-32.png",
|
||||||
|
"38": "images/icon-38.png",
|
||||||
|
"64": "images/icon-64.png",
|
||||||
|
"128": "images/icon-128.png",
|
||||||
|
"512": "images/icon-512.png"
|
||||||
|
},
|
||||||
|
"default_title": "MetaMask",
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"author": "https://metamask.io",
|
||||||
|
"background": {
|
||||||
|
"service_worker": "app-init.js"
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"_execute_browser_action": {
|
||||||
|
"suggested_key": {
|
||||||
|
"windows": "Alt+Shift+M",
|
||||||
|
"mac": "Alt+Shift+M",
|
||||||
|
"chromeos": "Alt+Shift+M",
|
||||||
|
"linux": "Alt+Shift+M"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["file://*/*", "http://*/*", "https://*/*"],
|
||||||
|
"js": [
|
||||||
|
"disable-console.js",
|
||||||
|
"globalthis.js",
|
||||||
|
"lockdown-install.js",
|
||||||
|
"lockdown-run.js",
|
||||||
|
"lockdown-more.js",
|
||||||
|
"contentscript.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_start",
|
||||||
|
"all_frames": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matches": ["*://connect.trezor.io/*/popup.html"],
|
||||||
|
"js": ["vendor/trezor/content-script.js"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_locale": "en",
|
||||||
|
"description": "__MSG_appDescription__",
|
||||||
|
"icons": {
|
||||||
|
"16": "images/icon-16.png",
|
||||||
|
"19": "images/icon-19.png",
|
||||||
|
"32": "images/icon-32.png",
|
||||||
|
"38": "images/icon-38.png",
|
||||||
|
"48": "images/icon-48.png",
|
||||||
|
"64": "images/icon-64.png",
|
||||||
|
"128": "images/icon-128.png",
|
||||||
|
"512": "images/icon-512.png"
|
||||||
|
},
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "__MSG_appName__",
|
||||||
|
"permissions": [
|
||||||
|
"storage",
|
||||||
|
"unlimitedStorage",
|
||||||
|
"clipboardWrite",
|
||||||
|
"http://localhost:8545/",
|
||||||
|
"https://*.infura.io/",
|
||||||
|
"https://lattice.gridplus.io/*",
|
||||||
|
"activeTab",
|
||||||
|
"webRequest",
|
||||||
|
"*://*.eth/",
|
||||||
|
"notifications"
|
||||||
|
],
|
||||||
|
"short_name": "__MSG_appName__",
|
||||||
|
"web_accessible_resources": [
|
||||||
|
{
|
||||||
|
"resources": ["inpage.js", "phishing.html"],
|
||||||
|
"matches": ["http://*/*", "https://*/*"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
app/manifest/v3/brave.json
Normal file
1
app/manifest/v3/brave.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
7
app/manifest/v3/chrome.json
Normal file
7
app/manifest/v3/chrome.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"externally_connectable": {
|
||||||
|
"matches": ["https://metamask.io/*"],
|
||||||
|
"ids": ["*"]
|
||||||
|
},
|
||||||
|
"minimum_chrome_version": "66"
|
||||||
|
}
|
26
app/manifest/v3/firefox.json
Normal file
26
app/manifest/v3/firefox.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "webextension@metamask.io",
|
||||||
|
"strict_min_version": "68.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"page": "background.html",
|
||||||
|
"persistent": true
|
||||||
|
},
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "images/icon-16.png",
|
||||||
|
"19": "images/icon-19.png",
|
||||||
|
"32": "images/icon-32.png",
|
||||||
|
"38": "images/icon-38.png",
|
||||||
|
"64": "images/icon-64.png",
|
||||||
|
"128": "images/icon-128.png",
|
||||||
|
"512": "images/icon-512.png"
|
||||||
|
},
|
||||||
|
"default_title": "MetaMask",
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"manifest_version": 2
|
||||||
|
}
|
9
app/manifest/v3/opera.json
Normal file
9
app/manifest/v3/opera.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"permissions": [
|
||||||
|
"storage",
|
||||||
|
"tabs",
|
||||||
|
"clipboardWrite",
|
||||||
|
"clipboardRead",
|
||||||
|
"http://localhost:8545/"
|
||||||
|
]
|
||||||
|
}
|
@ -35,7 +35,7 @@
|
|||||||
<div id="popover-content"></div>
|
<div id="popover-content"></div>
|
||||||
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
||||||
{{@if(it.useLavamoat)}}
|
{{@if(it.applyLavaMoat)}}
|
||||||
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<div id="popover-content"></div>
|
<div id="popover-content"></div>
|
||||||
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./globalthis.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./sentry-install.js" type="text/javascript" charset="utf-8"></script>
|
||||||
{{@if(it.useLavamoat)}}
|
{{@if(it.applyLavaMoat)}}
|
||||||
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./runtime-lavamoat.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./lockdown-more.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
<script src="./policy-load.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
55
app/scripts/app-init.js
Normal file
55
app/scripts/app-init.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// eslint-disable-next-line import/unambiguous
|
||||||
|
function tryImport(...fileNames) {
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
importScripts(...fileNames);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function importAllScripts() {
|
||||||
|
const startImportScriptsTime = Date.now();
|
||||||
|
// applyLavaMoat has been hard coded to "true" as
|
||||||
|
// tryImport('./runtime-cjs.js') is giving issue with XMLHttpRequest object which is not avaialble to service worker.
|
||||||
|
// we need to dynamically inject values of applyLavaMoat once this is fixed.
|
||||||
|
const applyLavaMoat = true;
|
||||||
|
|
||||||
|
tryImport('./globalthis.js');
|
||||||
|
tryImport('./sentry-install.js');
|
||||||
|
|
||||||
|
if (applyLavaMoat) {
|
||||||
|
tryImport('./runtime-lavamoat.js');
|
||||||
|
tryImport('./lockdown-more.js');
|
||||||
|
tryImport('./policy-load.js');
|
||||||
|
} else {
|
||||||
|
tryImport('./lockdown-install.js');
|
||||||
|
tryImport('./lockdown-more.js');
|
||||||
|
tryImport('./lockdown-run.js');
|
||||||
|
tryImport('./runtime-cjs.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList = [
|
||||||
|
// The list of files is injected at build time by replacing comment below with comma separated strings of file names
|
||||||
|
/** FILE NAMES */
|
||||||
|
];
|
||||||
|
|
||||||
|
fileList.forEach((fileName) => tryImport(fileName));
|
||||||
|
|
||||||
|
// for performance metrics/reference
|
||||||
|
console.log(
|
||||||
|
`SCRIPTS IMPORT COMPLETE in Seconds: ${
|
||||||
|
(Date.now() - startImportScriptsTime) / 1000
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placing script import call here ensures that scripts are inported each time service worker is activated.
|
||||||
|
importAllScripts();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An open issue is changes in this file break during hot reloading. Reason is dynamic injection of "FILE NAMES".
|
||||||
|
* Developers need to restart local server if they change this file.
|
||||||
|
*/
|
@ -23,6 +23,7 @@ import {
|
|||||||
REJECT_NOTFICIATION_CLOSE,
|
REJECT_NOTFICIATION_CLOSE,
|
||||||
REJECT_NOTFICIATION_CLOSE_SIG,
|
REJECT_NOTFICIATION_CLOSE_SIG,
|
||||||
} from '../../shared/constants/metametrics';
|
} from '../../shared/constants/metametrics';
|
||||||
|
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
||||||
import migrations from './migrations';
|
import migrations from './migrations';
|
||||||
import Migrator from './lib/migrator';
|
import Migrator from './lib/migrator';
|
||||||
import ExtensionPlatform from './platforms/extension';
|
import ExtensionPlatform from './platforms/extension';
|
||||||
@ -45,6 +46,14 @@ import { getPlatform } from './lib/util';
|
|||||||
const { sentry } = global;
|
const { sentry } = global;
|
||||||
const firstTimeState = { ...rawFirstTimeState };
|
const firstTimeState = { ...rawFirstTimeState };
|
||||||
|
|
||||||
|
const metamaskInternalProcessHash = {
|
||||||
|
[ENVIRONMENT_TYPE_POPUP]: true,
|
||||||
|
[ENVIRONMENT_TYPE_NOTIFICATION]: true,
|
||||||
|
[ENVIRONMENT_TYPE_FULLSCREEN]: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const metamaskBlockedPorts = ['trezor-connect'];
|
||||||
|
|
||||||
log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'info');
|
log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'info');
|
||||||
|
|
||||||
const platform = new ExtensionPlatform();
|
const platform = new ExtensionPlatform();
|
||||||
@ -73,8 +82,23 @@ const ONE_SECOND_IN_MILLISECONDS = 1_000;
|
|||||||
// Timeout for initializing phishing warning page.
|
// Timeout for initializing phishing warning page.
|
||||||
const PHISHING_WARNING_PAGE_TIMEOUT = ONE_SECOND_IN_MILLISECONDS;
|
const PHISHING_WARNING_PAGE_TIMEOUT = ONE_SECOND_IN_MILLISECONDS;
|
||||||
|
|
||||||
// initialization flow
|
/**
|
||||||
initialize().catch(log.error);
|
* In case of MV3 we attach a "onConnect" event listener as soon as the application is initialised.
|
||||||
|
* Reason is that in case of MV3 a delay in doing this was resulting in missing first connect event after service worker is re-activated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const initApp = async (remotePort) => {
|
||||||
|
browser.runtime.onConnect.removeListener(initApp);
|
||||||
|
await initialize(remotePort);
|
||||||
|
log.info('MetaMask initialization complete.');
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isManifestV3()) {
|
||||||
|
browser.runtime.onConnect.addListener(initApp);
|
||||||
|
} else {
|
||||||
|
// initialization flow
|
||||||
|
initialize().catch(log.error);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../shared/constants/transaction').TransactionMeta} TransactionMeta
|
* @typedef {import('../../shared/constants/transaction').TransactionMeta} TransactionMeta
|
||||||
@ -134,12 +158,13 @@ initialize().catch(log.error);
|
|||||||
/**
|
/**
|
||||||
* Initializes the MetaMask controller, and sets up all platform configuration.
|
* Initializes the MetaMask controller, and sets up all platform configuration.
|
||||||
*
|
*
|
||||||
|
* @param {string} remotePort - remote application port connecting to extension.
|
||||||
* @returns {Promise} Setup complete.
|
* @returns {Promise} Setup complete.
|
||||||
*/
|
*/
|
||||||
async function initialize() {
|
async function initialize(remotePort) {
|
||||||
const initState = await loadStateFromPersistence();
|
const initState = await loadStateFromPersistence();
|
||||||
const initLangCode = await getFirstPreferredLangCode();
|
const initLangCode = await getFirstPreferredLangCode();
|
||||||
await setupController(initState, initLangCode);
|
await setupController(initState, initLangCode, remotePort);
|
||||||
await loadPhishingWarningPage();
|
await loadPhishingWarningPage();
|
||||||
log.info('MetaMask initialization complete.');
|
log.info('MetaMask initialization complete.');
|
||||||
}
|
}
|
||||||
@ -278,9 +303,10 @@ async function loadStateFromPersistence() {
|
|||||||
*
|
*
|
||||||
* @param {Object} initState - The initial state to start the controller with, matches the state that is emitted from the controller.
|
* @param {Object} initState - The initial state to start the controller with, matches the state that is emitted from the controller.
|
||||||
* @param {string} initLangCode - The region code for the language preferred by the current user.
|
* @param {string} initLangCode - The region code for the language preferred by the current user.
|
||||||
|
* @param {string} remoteSourcePort - remote application port connecting to extension.
|
||||||
* @returns {Promise} After setup is complete.
|
* @returns {Promise} After setup is complete.
|
||||||
*/
|
*/
|
||||||
function setupController(initState, initLangCode) {
|
function setupController(initState, initLangCode, remoteSourcePort) {
|
||||||
//
|
//
|
||||||
// MetaMask Controller
|
// MetaMask Controller
|
||||||
//
|
//
|
||||||
@ -367,17 +393,13 @@ function setupController(initState, initLangCode) {
|
|||||||
//
|
//
|
||||||
// connect to other contexts
|
// connect to other contexts
|
||||||
//
|
//
|
||||||
|
if (isManifestV3() && remoteSourcePort) {
|
||||||
|
connectRemote(remoteSourcePort);
|
||||||
|
}
|
||||||
|
|
||||||
browser.runtime.onConnect.addListener(connectRemote);
|
browser.runtime.onConnect.addListener(connectRemote);
|
||||||
browser.runtime.onConnectExternal.addListener(connectExternal);
|
browser.runtime.onConnectExternal.addListener(connectExternal);
|
||||||
|
|
||||||
const metamaskInternalProcessHash = {
|
|
||||||
[ENVIRONMENT_TYPE_POPUP]: true,
|
|
||||||
[ENVIRONMENT_TYPE_NOTIFICATION]: true,
|
|
||||||
[ENVIRONMENT_TYPE_FULLSCREEN]: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const metamaskBlockedPorts = ['trezor-connect'];
|
|
||||||
|
|
||||||
const isClientOpenStatus = () => {
|
const isClientOpenStatus = () => {
|
||||||
return (
|
return (
|
||||||
popupIsOpen ||
|
popupIsOpen ||
|
||||||
@ -445,6 +467,13 @@ function setupController(initState, initLangCode) {
|
|||||||
controller.isClientOpen = true;
|
controller.isClientOpen = true;
|
||||||
controller.setupTrustedCommunication(portStream, remotePort.sender);
|
controller.setupTrustedCommunication(portStream, remotePort.sender);
|
||||||
|
|
||||||
|
if (isManifestV3()) {
|
||||||
|
// Message below if captured by UI code in app/scripts/ui.js which will trigger UI initialisation
|
||||||
|
// This ensures that UI is initialised only after background is ready
|
||||||
|
// It fixes the issue of blank screen coming when extension is loaded, the issue is very frequent in MV3
|
||||||
|
remotePort.postMessage({ name: 'CONNECTION_READY' });
|
||||||
|
}
|
||||||
|
|
||||||
if (processName === ENVIRONMENT_TYPE_POPUP) {
|
if (processName === ENVIRONMENT_TYPE_POPUP) {
|
||||||
popupIsOpen = true;
|
popupIsOpen = true;
|
||||||
endOfStream(portStream, () => {
|
endOfStream(portStream, () => {
|
||||||
@ -566,8 +595,14 @@ function setupController(initState, initLangCode) {
|
|||||||
if (count) {
|
if (count) {
|
||||||
label = String(count);
|
label = String(count);
|
||||||
}
|
}
|
||||||
browser.browserAction.setBadgeText({ text: label });
|
// browserAction has been replaced by action in MV3
|
||||||
browser.browserAction.setBadgeBackgroundColor({ color: '#037DD6' });
|
if (isManifestV3()) {
|
||||||
|
browser.action.setBadgeText({ text: label });
|
||||||
|
browser.action.setBadgeBackgroundColor({ color: '#037DD6' });
|
||||||
|
} else {
|
||||||
|
browser.browserAction.setBadgeText({ text: label });
|
||||||
|
browser.browserAction.setBadgeBackgroundColor({ color: '#037DD6' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUnapprovedTransactionCount() {
|
function getUnapprovedTransactionCount() {
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export const TRANSAK_API_KEY = '25ac1309-a49b-4411-b20e-5e56c61a5b1c'; // It's a public key, which will be included in a URL for Transak.
|
export const TRANSAK_API_KEY = '25ac1309-a49b-4411-b20e-5e56c61a5b1c'; // It's a public key, which will be included in a URL for Transak.
|
||||||
export const MOONPAY_API_KEY = 'pk_live_WbCpe6PxSIcGPCSd6lKCbJNRht7uy'; // Publishable key.
|
export const MOONPAY_API_KEY = 'pk_live_WbCpe6PxSIcGPCSd6lKCbJNRht7uy'; // Publishable key.
|
||||||
|
export const COINBASEPAY_API_KEY = 'ab4b8829-a59d-44d3-accc-de77e4f18df2'; // Publishable key.
|
||||||
|
@ -6,6 +6,8 @@ import browser from 'webextension-polyfill';
|
|||||||
import PortStream from 'extension-port-stream';
|
import PortStream from 'extension-port-stream';
|
||||||
import { obj as createThoughStream } from 'through2';
|
import { obj as createThoughStream } from 'through2';
|
||||||
|
|
||||||
|
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
||||||
|
|
||||||
// These require calls need to use require to be statically recognized by browserify
|
// These require calls need to use require to be statically recognized by browserify
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@ -54,7 +56,12 @@ function injectScript(content) {
|
|||||||
const container = document.head || document.documentElement;
|
const container = document.head || document.documentElement;
|
||||||
const scriptTag = document.createElement('script');
|
const scriptTag = document.createElement('script');
|
||||||
scriptTag.setAttribute('async', 'false');
|
scriptTag.setAttribute('async', 'false');
|
||||||
scriptTag.textContent = content;
|
// Inline scripts do not work in MV3 due to more strict security policy
|
||||||
|
if (isManifestV3()) {
|
||||||
|
scriptTag.setAttribute('src', browser.runtime.getURL('inpage.js'));
|
||||||
|
} else {
|
||||||
|
scriptTag.textContent = content;
|
||||||
|
}
|
||||||
container.insertBefore(scriptTag, container.children[0]);
|
container.insertBefore(scriptTag, container.children[0]);
|
||||||
container.removeChild(scriptTag);
|
container.removeChild(scriptTag);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -6,6 +6,9 @@ import { MINUTE } from '../../../shared/constants/time';
|
|||||||
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
|
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
|
||||||
import { isTokenDetectionEnabledForNetwork } from '../../../shared/modules/network.utils';
|
import { isTokenDetectionEnabledForNetwork } from '../../../shared/modules/network.utils';
|
||||||
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||||
|
import { TOKEN_STANDARDS } from '../../../ui/helpers/constants/common';
|
||||||
|
import { ASSET_TYPES } from '../../../shared/constants/transaction';
|
||||||
|
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||||
|
|
||||||
// By default, poll every 3 minutes
|
// By default, poll every 3 minutes
|
||||||
const DEFAULT_INTERVAL = MINUTE * 3;
|
const DEFAULT_INTERVAL = MINUTE * 3;
|
||||||
@ -26,6 +29,7 @@ export default class DetectTokensController {
|
|||||||
* @param config.tokenList
|
* @param config.tokenList
|
||||||
* @param config.tokensController
|
* @param config.tokensController
|
||||||
* @param config.assetsContractController
|
* @param config.assetsContractController
|
||||||
|
* @param config.trackMetaMetricsEvent
|
||||||
*/
|
*/
|
||||||
constructor({
|
constructor({
|
||||||
interval = DEFAULT_INTERVAL,
|
interval = DEFAULT_INTERVAL,
|
||||||
@ -35,6 +39,7 @@ export default class DetectTokensController {
|
|||||||
tokenList,
|
tokenList,
|
||||||
tokensController,
|
tokensController,
|
||||||
assetsContractController = null,
|
assetsContractController = null,
|
||||||
|
trackMetaMetricsEvent,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.assetsContractController = assetsContractController;
|
this.assetsContractController = assetsContractController;
|
||||||
this.tokensController = tokensController;
|
this.tokensController = tokensController;
|
||||||
@ -51,6 +56,7 @@ export default class DetectTokensController {
|
|||||||
this.detectedTokens = process.env.TOKEN_DETECTION_V2
|
this.detectedTokens = process.env.TOKEN_DETECTION_V2
|
||||||
? this.tokensController?.state.detectedTokens
|
? this.tokensController?.state.detectedTokens
|
||||||
: [];
|
: [];
|
||||||
|
this._trackMetaMetricsEvent = trackMetaMetricsEvent;
|
||||||
|
|
||||||
preferences?.store.subscribe(({ selectedAddress, useTokenDetection }) => {
|
preferences?.store.subscribe(({ selectedAddress, useTokenDetection }) => {
|
||||||
if (
|
if (
|
||||||
@ -162,6 +168,7 @@ export default class DetectTokensController {
|
|||||||
|
|
||||||
let tokensWithBalance = [];
|
let tokensWithBalance = [];
|
||||||
if (process.env.TOKEN_DETECTION_V2) {
|
if (process.env.TOKEN_DETECTION_V2) {
|
||||||
|
const eventTokensDetails = [];
|
||||||
if (result) {
|
if (result) {
|
||||||
const nonZeroTokenAddresses = Object.keys(result);
|
const nonZeroTokenAddresses = Object.keys(result);
|
||||||
for (const nonZeroTokenAddress of nonZeroTokenAddresses) {
|
for (const nonZeroTokenAddress of nonZeroTokenAddresses) {
|
||||||
@ -172,6 +179,9 @@ export default class DetectTokensController {
|
|||||||
iconUrl,
|
iconUrl,
|
||||||
aggregators,
|
aggregators,
|
||||||
} = tokenList[nonZeroTokenAddress];
|
} = tokenList[nonZeroTokenAddress];
|
||||||
|
|
||||||
|
eventTokensDetails.push(`${symbol} - ${address}`);
|
||||||
|
|
||||||
tokensWithBalance.push({
|
tokensWithBalance.push({
|
||||||
address,
|
address,
|
||||||
symbol,
|
symbol,
|
||||||
@ -180,7 +190,17 @@ export default class DetectTokensController {
|
|||||||
aggregators,
|
aggregators,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokensWithBalance.length > 0) {
|
if (tokensWithBalance.length > 0) {
|
||||||
|
this._trackMetaMetricsEvent({
|
||||||
|
event: EVENT_NAMES.TOKEN_DETECTED,
|
||||||
|
category: EVENT.CATEGORIES.WALLET,
|
||||||
|
properties: {
|
||||||
|
tokens: eventTokensDetails,
|
||||||
|
token_standard: TOKEN_STANDARDS.ERC20,
|
||||||
|
asset_type: ASSET_TYPES.TOKEN,
|
||||||
|
},
|
||||||
|
});
|
||||||
await this.tokensController.addDetectedTokens(tokensWithBalance);
|
await this.tokensController.addDetectedTokens(tokensWithBalance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import { isEqual, merge, omit, omitBy, pickBy, size, sum } from 'lodash';
|
import {
|
||||||
|
isEqual,
|
||||||
|
memoize,
|
||||||
|
merge,
|
||||||
|
omit,
|
||||||
|
omitBy,
|
||||||
|
pickBy,
|
||||||
|
size,
|
||||||
|
sum,
|
||||||
|
} from 'lodash';
|
||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import { bufferToHex, keccak } from 'ethereumjs-util';
|
import { bufferToHex, keccak } from 'ethereumjs-util';
|
||||||
import { generateUUID } from 'pubnub';
|
import { generateUUID } from 'pubnub';
|
||||||
@ -540,9 +549,7 @@ export default class MetaMetricsController {
|
|||||||
* @returns {MetaMetricsTraits | null} traits that have changed since last update
|
* @returns {MetaMetricsTraits | null} traits that have changed since last update
|
||||||
*/
|
*/
|
||||||
_buildUserTraitsObject(metamaskState) {
|
_buildUserTraitsObject(metamaskState) {
|
||||||
/**
|
/** @type {MetaMetricsTraits} */
|
||||||
* @type {MetaMetricsTraits}
|
|
||||||
*/
|
|
||||||
const currentTraits = {
|
const currentTraits = {
|
||||||
[TRAITS.ADDRESS_BOOK_ENTRIES]: sum(
|
[TRAITS.ADDRESS_BOOK_ENTRIES]: sum(
|
||||||
Object.values(metamaskState.addressBook).map(size),
|
Object.values(metamaskState.addressBook).map(size),
|
||||||
@ -551,16 +558,29 @@ export default class MetaMetricsController {
|
|||||||
[TRAITS.NETWORKS_ADDED]: metamaskState.frequentRpcListDetail.map(
|
[TRAITS.NETWORKS_ADDED]: metamaskState.frequentRpcListDetail.map(
|
||||||
(rpc) => rpc.chainId,
|
(rpc) => rpc.chainId,
|
||||||
),
|
),
|
||||||
|
[TRAITS.NETWORKS_WITHOUT_TICKER]: metamaskState.frequentRpcListDetail.reduce(
|
||||||
|
(networkList, currentNetwork) => {
|
||||||
|
if (!currentNetwork.ticker) {
|
||||||
|
networkList.push(currentNetwork.chainId);
|
||||||
|
}
|
||||||
|
return networkList;
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
),
|
||||||
[TRAITS.NFT_AUTODETECTION_ENABLED]: metamaskState.useCollectibleDetection,
|
[TRAITS.NFT_AUTODETECTION_ENABLED]: metamaskState.useCollectibleDetection,
|
||||||
[TRAITS.NUMBER_OF_ACCOUNTS]: Object.values(metamaskState.identities)
|
[TRAITS.NUMBER_OF_ACCOUNTS]: Object.values(metamaskState.identities)
|
||||||
.length,
|
.length,
|
||||||
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getNumberOfNFtCollection(
|
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getAllUniqueNFTAddressesLength(
|
||||||
metamaskState,
|
metamaskState.allCollectibles,
|
||||||
),
|
),
|
||||||
|
[TRAITS.NUMBER_OF_NFTS]: this._getAllNFTsFlattened(
|
||||||
|
metamaskState.allCollectibles,
|
||||||
|
).length,
|
||||||
[TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState),
|
[TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState),
|
||||||
[TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled,
|
[TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled,
|
||||||
[TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed,
|
[TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed,
|
||||||
[TRAITS.THEME]: metamaskState.theme || 'default',
|
[TRAITS.THEME]: metamaskState.theme || 'default',
|
||||||
|
[TRAITS.TOKEN_DETECTION_ENABLED]: metamaskState.useTokenDetection,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.previousTraits) {
|
if (!this.previousTraits) {
|
||||||
@ -603,22 +623,33 @@ export default class MetaMetricsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns an array of all of the collectibles/NFTs the user
|
||||||
|
* possesses across all networks and accounts.
|
||||||
*
|
*
|
||||||
* @param {object} metamaskState
|
* @param {Object} allCollectibles
|
||||||
* @returns number of unique collectible addresses
|
* @returns {[]}
|
||||||
*/
|
*/
|
||||||
_getNumberOfNFtCollection(metamaskState) {
|
_getAllNFTsFlattened = memoize((allCollectibles = {}) => {
|
||||||
const { allCollectibles } = metamaskState;
|
return Object.values(allCollectibles)
|
||||||
if (!allCollectibles) {
|
.reduce((result, chainNFTs) => {
|
||||||
return 0;
|
return result.concat(Object.values(chainNFTs));
|
||||||
}
|
}, [])
|
||||||
|
.flat();
|
||||||
|
});
|
||||||
|
|
||||||
const allAddresses = Object.values(allCollectibles)
|
/**
|
||||||
.flatMap((chainCollectibles) => Object.values(chainCollectibles))
|
* Returns the number of unique collectible/NFT addresses the user
|
||||||
.flat()
|
* possesses across all networks and accounts.
|
||||||
.map((collectible) => collectible.address);
|
*
|
||||||
const unique = [...new Set(allAddresses)];
|
* @param {Object} allCollectibles
|
||||||
return unique.length;
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
_getAllUniqueNFTAddressesLength(allCollectibles = {}) {
|
||||||
|
const allNFTAddresses = this._getAllNFTsFlattened(allCollectibles).map(
|
||||||
|
(nft) => nft.address,
|
||||||
|
);
|
||||||
|
const uniqueAddresses = new Set(allNFTAddresses);
|
||||||
|
return uniqueAddresses.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,8 +9,10 @@ import {
|
|||||||
} from '../../../shared/constants/metametrics';
|
} from '../../../shared/constants/metametrics';
|
||||||
import waitUntilCalled from '../../../test/lib/wait-until-called';
|
import waitUntilCalled from '../../../test/lib/wait-until-called';
|
||||||
import {
|
import {
|
||||||
|
ETH_SYMBOL,
|
||||||
MAINNET_CHAIN_ID,
|
MAINNET_CHAIN_ID,
|
||||||
ROPSTEN_CHAIN_ID,
|
ROPSTEN_CHAIN_ID,
|
||||||
|
TEST_ETH_SYMBOL,
|
||||||
} from '../../../shared/constants/network';
|
} from '../../../shared/constants/network';
|
||||||
import MetaMetricsController from './metametrics';
|
import MetaMetricsController from './metametrics';
|
||||||
import { NETWORK_EVENTS } from './network';
|
import { NETWORK_EVENTS } from './network';
|
||||||
@ -673,8 +675,9 @@ describe('MetaMetricsController', function () {
|
|||||||
},
|
},
|
||||||
allTokens: MOCK_ALL_TOKENS,
|
allTokens: MOCK_ALL_TOKENS,
|
||||||
frequentRpcListDetail: [
|
frequentRpcListDetail: [
|
||||||
{ chainId: MAINNET_CHAIN_ID },
|
{ chainId: MAINNET_CHAIN_ID, ticker: ETH_SYMBOL },
|
||||||
{ chainId: ROPSTEN_CHAIN_ID },
|
{ chainId: ROPSTEN_CHAIN_ID, ticker: TEST_ETH_SYMBOL },
|
||||||
|
{ chainId: '0xaf' },
|
||||||
],
|
],
|
||||||
identities: [{}, {}],
|
identities: [{}, {}],
|
||||||
ledgerTransportType: 'web-hid',
|
ledgerTransportType: 'web-hid',
|
||||||
@ -682,19 +685,23 @@ describe('MetaMetricsController', function () {
|
|||||||
threeBoxSyncingAllowed: false,
|
threeBoxSyncingAllowed: false,
|
||||||
useCollectibleDetection: false,
|
useCollectibleDetection: false,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
useTokenDetection: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(traits, {
|
assert.deepEqual(traits, {
|
||||||
[TRAITS.ADDRESS_BOOK_ENTRIES]: 3,
|
[TRAITS.ADDRESS_BOOK_ENTRIES]: 3,
|
||||||
[TRAITS.LEDGER_CONNECTION_TYPE]: 'web-hid',
|
[TRAITS.LEDGER_CONNECTION_TYPE]: 'web-hid',
|
||||||
[TRAITS.NETWORKS_ADDED]: [MAINNET_CHAIN_ID, ROPSTEN_CHAIN_ID],
|
[TRAITS.NETWORKS_ADDED]: [MAINNET_CHAIN_ID, ROPSTEN_CHAIN_ID, '0xaf'],
|
||||||
|
[TRAITS.NETWORKS_WITHOUT_TICKER]: ['0xaf'],
|
||||||
[TRAITS.NFT_AUTODETECTION_ENABLED]: false,
|
[TRAITS.NFT_AUTODETECTION_ENABLED]: false,
|
||||||
[TRAITS.NUMBER_OF_ACCOUNTS]: 2,
|
[TRAITS.NUMBER_OF_ACCOUNTS]: 2,
|
||||||
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3,
|
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3,
|
||||||
|
[TRAITS.NUMBER_OF_NFTS]: 4,
|
||||||
[TRAITS.NUMBER_OF_TOKENS]: 5,
|
[TRAITS.NUMBER_OF_TOKENS]: 5,
|
||||||
[TRAITS.OPENSEA_API_ENABLED]: true,
|
[TRAITS.OPENSEA_API_ENABLED]: true,
|
||||||
[TRAITS.THREE_BOX_ENABLED]: false,
|
[TRAITS.THREE_BOX_ENABLED]: false,
|
||||||
[TRAITS.THEME]: 'default',
|
[TRAITS.THEME]: 'default',
|
||||||
|
[TRAITS.TOKEN_DETECTION_ENABLED]: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -716,6 +723,7 @@ describe('MetaMetricsController', function () {
|
|||||||
threeBoxSyncingAllowed: false,
|
threeBoxSyncingAllowed: false,
|
||||||
useCollectibleDetection: false,
|
useCollectibleDetection: false,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
useTokenDetection: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
||||||
@ -736,6 +744,7 @@ describe('MetaMetricsController', function () {
|
|||||||
threeBoxSyncingAllowed: false,
|
threeBoxSyncingAllowed: false,
|
||||||
useCollectibleDetection: false,
|
useCollectibleDetection: false,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
useTokenDetection: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(updatedTraits, {
|
assert.deepEqual(updatedTraits, {
|
||||||
@ -764,6 +773,7 @@ describe('MetaMetricsController', function () {
|
|||||||
threeBoxSyncingAllowed: false,
|
threeBoxSyncingAllowed: false,
|
||||||
useCollectibleDetection: true,
|
useCollectibleDetection: true,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
useTokenDetection: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
||||||
@ -782,6 +792,7 @@ describe('MetaMetricsController', function () {
|
|||||||
threeBoxSyncingAllowed: false,
|
threeBoxSyncingAllowed: false,
|
||||||
useCollectibleDetection: true,
|
useCollectibleDetection: true,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
useTokenDetection: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.equal(updatedTraits, null);
|
assert.equal(updatedTraits, null);
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
MAINNET_CHAIN_ID,
|
MAINNET_CHAIN_ID,
|
||||||
RINKEBY_CHAIN_ID,
|
RINKEBY_CHAIN_ID,
|
||||||
INFURA_BLOCKED_KEY,
|
INFURA_BLOCKED_KEY,
|
||||||
|
TEST_NETWORK_TICKER_MAP,
|
||||||
} from '../../../../shared/constants/network';
|
} from '../../../../shared/constants/network';
|
||||||
import { SECOND } from '../../../../shared/constants/time';
|
import { SECOND } from '../../../../shared/constants/time';
|
||||||
import {
|
import {
|
||||||
@ -41,7 +42,11 @@ if (process.env.IN_TEST) {
|
|||||||
nickname: 'Localhost 8545',
|
nickname: 'Localhost 8545',
|
||||||
};
|
};
|
||||||
} else if (process.env.METAMASK_DEBUG || env === 'test') {
|
} else if (process.env.METAMASK_DEBUG || env === 'test') {
|
||||||
defaultProviderConfigOpts = { type: RINKEBY, chainId: RINKEBY_CHAIN_ID };
|
defaultProviderConfigOpts = {
|
||||||
|
type: RINKEBY,
|
||||||
|
chainId: RINKEBY_CHAIN_ID,
|
||||||
|
ticker: TEST_NETWORK_TICKER_MAP.rinkeby,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
defaultProviderConfigOpts = { type: MAINNET, chainId: MAINNET_CHAIN_ID };
|
defaultProviderConfigOpts = { type: MAINNET, chainId: MAINNET_CHAIN_ID };
|
||||||
}
|
}
|
||||||
@ -296,12 +301,12 @@ export default class NetworkController extends EventEmitter {
|
|||||||
INFURA_PROVIDER_TYPES.includes(type),
|
INFURA_PROVIDER_TYPES.includes(type),
|
||||||
`Unknown Infura provider type "${type}".`,
|
`Unknown Infura provider type "${type}".`,
|
||||||
);
|
);
|
||||||
const { chainId } = NETWORK_TYPE_TO_ID_MAP[type];
|
const { chainId, ticker } = NETWORK_TYPE_TO_ID_MAP[type];
|
||||||
this.setProviderConfig({
|
this.setProviderConfig({
|
||||||
type,
|
type,
|
||||||
rpcUrl: '',
|
rpcUrl: '',
|
||||||
chainId,
|
chainId,
|
||||||
ticker: 'ETH',
|
ticker: ticker ?? 'ETH',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { endowmentPermissionBuilders } from '@metamask/controllers';
|
import { endowmentPermissionBuilders } from '@metamask/snap-controllers';
|
||||||
import {
|
import {
|
||||||
restrictedMethodPermissionBuilders,
|
restrictedMethodPermissionBuilders,
|
||||||
selectHooks,
|
selectHooks,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import stringify from 'fast-safe-stringify';
|
|
||||||
import { CaveatTypes } from '../../../../shared/constants/permissions';
|
import { CaveatTypes } from '../../../../shared/constants/permissions';
|
||||||
import {
|
import {
|
||||||
LOG_IGNORE_METHODS,
|
LOG_IGNORE_METHODS,
|
||||||
@ -158,9 +157,7 @@ export class PermissionLogController {
|
|||||||
? LOG_METHOD_TYPES.internal
|
? LOG_METHOD_TYPES.internal
|
||||||
: LOG_METHOD_TYPES.restricted,
|
: LOG_METHOD_TYPES.restricted,
|
||||||
origin: request.origin,
|
origin: request.origin,
|
||||||
request: stringify(request, null, 2),
|
|
||||||
requestTime: Date.now(),
|
requestTime: Date.now(),
|
||||||
response: null,
|
|
||||||
responseTime: null,
|
responseTime: null,
|
||||||
success: null,
|
success: null,
|
||||||
};
|
};
|
||||||
@ -181,9 +178,12 @@ export class PermissionLogController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.response = stringify(response, null, 2);
|
// The JSON-RPC 2.0 specification defines "success" by the presence of
|
||||||
|
// either the "result" or "error" property. The specification forbids
|
||||||
|
// both properties from being present simultaneously, and our JSON-RPC
|
||||||
|
// stack is spec-compliant at the time of writing.
|
||||||
|
entry.success = Object.hasOwnProperty.call(response, 'result');
|
||||||
entry.responseTime = time;
|
entry.responseTime = time;
|
||||||
entry.success = !response.error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import nanoid from 'nanoid';
|
import nanoid from 'nanoid';
|
||||||
import { useFakeTimers } from 'sinon';
|
import { useFakeTimers } from 'sinon';
|
||||||
import stringify from 'fast-safe-stringify';
|
|
||||||
import { constants, getters, noop } from '../../../../test/mocks/permissions';
|
import { constants, getters, noop } from '../../../../test/mocks/permissions';
|
||||||
import { PermissionLogController } from './permission-log';
|
import { PermissionLogController } from './permission-log';
|
||||||
import { LOG_LIMIT, LOG_METHOD_TYPES } from './enums';
|
import { LOG_LIMIT, LOG_METHOD_TYPES } from './enums';
|
||||||
@ -67,7 +66,7 @@ describe('PermissionLogController', () => {
|
|||||||
|
|
||||||
req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
||||||
req.id = REQUEST_IDS.a;
|
req.id = REQUEST_IDS.a;
|
||||||
res = { foo: 'bar' };
|
res = { result: 'bar' };
|
||||||
|
|
||||||
logMiddleware({ ...req }, res);
|
logMiddleware({ ...req }, res);
|
||||||
|
|
||||||
@ -143,11 +142,17 @@ describe('PermissionLogController', () => {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
// validate final state
|
// Validate final state
|
||||||
expect(entry1).toStrictEqual(log[0]);
|
expect(entry1).toStrictEqual(log[0]);
|
||||||
expect(entry2).toStrictEqual(log[1]);
|
expect(entry2).toStrictEqual(log[1]);
|
||||||
expect(entry3).toStrictEqual(log[2]);
|
expect(entry3).toStrictEqual(log[2]);
|
||||||
expect(entry4).toStrictEqual(log[3]);
|
expect(entry4).toStrictEqual(log[3]);
|
||||||
|
|
||||||
|
// Regression test: ensure "response" and "request" properties
|
||||||
|
// are not present
|
||||||
|
log.forEach((entry) =>
|
||||||
|
expect('request' in entry && 'response' in entry).toBe(false),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles responses added out of order', () => {
|
it('handles responses added out of order', () => {
|
||||||
@ -163,15 +168,15 @@ describe('PermissionLogController', () => {
|
|||||||
|
|
||||||
// get make requests
|
// get make requests
|
||||||
req.id = id1;
|
req.id = id1;
|
||||||
const res1 = { foo: id1 };
|
const res1 = { result: id1 };
|
||||||
logMiddleware({ ...req }, { ...res1 }, getSavedMockNext(handlerArray));
|
logMiddleware({ ...req }, { ...res1 }, getSavedMockNext(handlerArray));
|
||||||
|
|
||||||
req.id = id2;
|
req.id = id2;
|
||||||
const res2 = { foo: id2 };
|
const res2 = { result: id2 };
|
||||||
logMiddleware({ ...req }, { ...res2 }, getSavedMockNext(handlerArray));
|
logMiddleware({ ...req }, { ...res2 }, getSavedMockNext(handlerArray));
|
||||||
|
|
||||||
req.id = id3;
|
req.id = id3;
|
||||||
const res3 = { foo: id3 };
|
const res3 = { result: id3 };
|
||||||
logMiddleware({ ...req }, { ...res3 }, getSavedMockNext(handlerArray));
|
logMiddleware({ ...req }, { ...res3 }, getSavedMockNext(handlerArray));
|
||||||
|
|
||||||
// verify log state
|
// verify log state
|
||||||
@ -181,10 +186,10 @@ describe('PermissionLogController', () => {
|
|||||||
const entry2 = log[1];
|
const entry2 = log[1];
|
||||||
const entry3 = log[2];
|
const entry3 = log[2];
|
||||||
|
|
||||||
// all entries should be in correct order, without responses
|
// all entries should be in correct order
|
||||||
expect(entry1).toMatchObject({ id: id1, response: null });
|
expect(entry1).toMatchObject({ id: id1, responseTime: null });
|
||||||
expect(entry2).toMatchObject({ id: id2, response: null });
|
expect(entry2).toMatchObject({ id: id2, responseTime: null });
|
||||||
expect(entry3).toMatchObject({ id: id3, response: null });
|
expect(entry3).toMatchObject({ id: id3, responseTime: null });
|
||||||
|
|
||||||
// call response handlers
|
// call response handlers
|
||||||
for (const i of [1, 2, 0]) {
|
for (const i of [1, 2, 0]) {
|
||||||
@ -226,7 +231,7 @@ describe('PermissionLogController', () => {
|
|||||||
it('handles a lack of response', () => {
|
it('handles a lack of response', () => {
|
||||||
let req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
let req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
||||||
req.id = REQUEST_IDS.a;
|
req.id = REQUEST_IDS.a;
|
||||||
let res = { foo: 'bar' };
|
let res = { result: 'bar' };
|
||||||
|
|
||||||
// noop for next handler prevents recording of response
|
// noop for next handler prevents recording of response
|
||||||
logMiddleware({ ...req }, res, noop);
|
logMiddleware({ ...req }, res, noop);
|
||||||
@ -270,7 +275,7 @@ describe('PermissionLogController', () => {
|
|||||||
let log = permLog.getActivityLog();
|
let log = permLog.getActivityLog();
|
||||||
expect(log).toHaveLength(0);
|
expect(log).toHaveLength(0);
|
||||||
|
|
||||||
const res = { foo: 'bar' };
|
const res = { result: 'bar' };
|
||||||
const req1 = RPC_REQUESTS.metamask_sendDomainMetadata(
|
const req1 = RPC_REQUESTS.metamask_sendDomainMetadata(
|
||||||
SUBJECTS.c.origin,
|
SUBJECTS.c.origin,
|
||||||
'foobar',
|
'foobar',
|
||||||
@ -288,7 +293,7 @@ describe('PermissionLogController', () => {
|
|||||||
|
|
||||||
it('enforces log limit', () => {
|
it('enforces log limit', () => {
|
||||||
const req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
const req = RPC_REQUESTS.test_method(SUBJECTS.a.origin);
|
||||||
const res = { foo: 'bar' };
|
const res = { result: 'bar' };
|
||||||
|
|
||||||
// max out log
|
// max out log
|
||||||
let lastId;
|
let lastId;
|
||||||
@ -647,19 +652,15 @@ function validateActivityEntry(entry, req, res, methodType, success) {
|
|||||||
expect(entry.method).toStrictEqual(req.method);
|
expect(entry.method).toStrictEqual(req.method);
|
||||||
expect(entry.origin).toStrictEqual(req.origin);
|
expect(entry.origin).toStrictEqual(req.origin);
|
||||||
expect(entry.methodType).toStrictEqual(methodType);
|
expect(entry.methodType).toStrictEqual(methodType);
|
||||||
expect(entry.request).toStrictEqual(stringify(req, null, 2));
|
|
||||||
|
|
||||||
expect(Number.isInteger(entry.requestTime)).toBe(true);
|
expect(Number.isInteger(entry.requestTime)).toBe(true);
|
||||||
if (res) {
|
if (res) {
|
||||||
expect(Number.isInteger(entry.responseTime)).toBe(true);
|
expect(Number.isInteger(entry.responseTime)).toBe(true);
|
||||||
expect(entry.requestTime <= entry.responseTime).toBe(true);
|
expect(entry.requestTime <= entry.responseTime).toBe(true);
|
||||||
|
|
||||||
expect(entry.success).toStrictEqual(success);
|
expect(entry.success).toStrictEqual(success);
|
||||||
expect(entry.response).toStrictEqual(stringify(res, null, 2));
|
|
||||||
} else {
|
} else {
|
||||||
expect(entry.requestTime > 0).toBe(true);
|
expect(entry.requestTime > 0).toBe(true);
|
||||||
expect(entry).toMatchObject({
|
expect(entry).toMatchObject({
|
||||||
response: null,
|
|
||||||
responseTime: null,
|
responseTime: null,
|
||||||
success: null,
|
success: null,
|
||||||
});
|
});
|
||||||
|
@ -68,7 +68,7 @@ export default class PreferencesController {
|
|||||||
ledgerTransportType: window.navigator.hid
|
ledgerTransportType: window.navigator.hid
|
||||||
? LEDGER_TRANSPORT_TYPES.WEBHID
|
? LEDGER_TRANSPORT_TYPES.WEBHID
|
||||||
: LEDGER_TRANSPORT_TYPES.U2F,
|
: LEDGER_TRANSPORT_TYPES.U2F,
|
||||||
theme: 'default',
|
theme: 'light',
|
||||||
...opts.initState,
|
...opts.initState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -353,14 +353,14 @@ describe('preferences controller', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('setTheme', function () {
|
describe('setTheme', function () {
|
||||||
it('should default to value "default"', function () {
|
it('should default to value "light"', function () {
|
||||||
const state = preferencesController.store.getState();
|
const state = preferencesController.store.getState();
|
||||||
assert.equal(state.theme, 'default');
|
assert.equal(state.theme, 'light');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the setTheme property in state', function () {
|
it('should set the setTheme property in state', function () {
|
||||||
const state = preferencesController.store.getState();
|
const state = preferencesController.store.getState();
|
||||||
assert.equal(state.theme, 'default');
|
assert.equal(state.theme, 'light');
|
||||||
preferencesController.setTheme('dark');
|
preferencesController.setTheme('dark');
|
||||||
assert.equal(preferencesController.store.getState().theme, 'dark');
|
assert.equal(preferencesController.store.getState().theme, 'dark');
|
||||||
});
|
});
|
||||||
|
@ -19,6 +19,11 @@ import {
|
|||||||
SWAPS_CHAINID_CONTRACT_ADDRESS_MAP,
|
SWAPS_CHAINID_CONTRACT_ADDRESS_MAP,
|
||||||
} from '../../../shared/constants/swaps';
|
} from '../../../shared/constants/swaps';
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
|
import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
|
||||||
|
import {
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_DEADLINE,
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
|
||||||
|
} from '../../../shared/constants/smartTransactions';
|
||||||
|
|
||||||
import { isSwapsDefaultTokenAddress } from '../../../shared/modules/swaps.utils';
|
import { isSwapsDefaultTokenAddress } from '../../../shared/modules/swaps.utils';
|
||||||
|
|
||||||
@ -41,8 +46,6 @@ const POLL_COUNT_LIMIT = 3;
|
|||||||
// If for any reason the MetaSwap API fails to provide a refresh time,
|
// If for any reason the MetaSwap API fails to provide a refresh time,
|
||||||
// provide a reasonable fallback to avoid further errors
|
// provide a reasonable fallback to avoid further errors
|
||||||
const FALLBACK_QUOTE_REFRESH_TIME = MINUTE;
|
const FALLBACK_QUOTE_REFRESH_TIME = MINUTE;
|
||||||
const FALLBACK_SMART_TRANSACTION_REFRESH_TIME = SECOND * 10;
|
|
||||||
const FALLBACK_SMART_TRANSACTIONS_DEADLINE = 180;
|
|
||||||
|
|
||||||
function calculateGasEstimateWithRefund(
|
function calculateGasEstimateWithRefund(
|
||||||
maxGas = MAX_GAS_LIMIT,
|
maxGas = MAX_GAS_LIMIT,
|
||||||
@ -86,8 +89,9 @@ const initialState = {
|
|||||||
saveFetchedQuotes: false,
|
saveFetchedQuotes: false,
|
||||||
swapsQuoteRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
|
swapsQuoteRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
|
||||||
swapsQuotePrefetchingRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
|
swapsQuotePrefetchingRefreshTime: FALLBACK_QUOTE_REFRESH_TIME,
|
||||||
swapsStxBatchStatusRefreshTime: FALLBACK_SMART_TRANSACTION_REFRESH_TIME,
|
swapsStxBatchStatusRefreshTime: FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
swapsStxGetTransactionsRefreshTime: FALLBACK_SMART_TRANSACTION_REFRESH_TIME,
|
swapsStxGetTransactionsRefreshTime: FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
|
swapsStxMaxFeeMultiplier: FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
|
||||||
swapsFeatureFlags: {},
|
swapsFeatureFlags: {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -129,13 +133,13 @@ export default class SwapsController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchSwapsRefreshRates(chainId) {
|
async fetchSwapsNetworkConfig(chainId) {
|
||||||
const response = await fetchWithCache(
|
const response = await fetchWithCache(
|
||||||
getBaseApi('network', chainId),
|
getBaseApi('network', chainId),
|
||||||
{ method: 'GET' },
|
{ method: 'GET' },
|
||||||
{ cacheRefreshTime: 600000 },
|
{ cacheRefreshTime: 600000 },
|
||||||
);
|
);
|
||||||
const { refreshRates } = response || {};
|
const { refreshRates, parameters = {} } = response || {};
|
||||||
if (
|
if (
|
||||||
!refreshRates ||
|
!refreshRates ||
|
||||||
typeof refreshRates.quotes !== 'number' ||
|
typeof refreshRates.quotes !== 'number' ||
|
||||||
@ -152,35 +156,39 @@ export default class SwapsController {
|
|||||||
stxGetTransactions: refreshRates.stxGetTransactions * 1000,
|
stxGetTransactions: refreshRates.stxGetTransactions * 1000,
|
||||||
stxBatchStatus: refreshRates.stxBatchStatus * 1000,
|
stxBatchStatus: refreshRates.stxBatchStatus * 1000,
|
||||||
stxStatusDeadline: refreshRates.stxStatusDeadline,
|
stxStatusDeadline: refreshRates.stxStatusDeadline,
|
||||||
|
stxMaxFeeMultiplier: parameters.stxMaxFeeMultiplier,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the refresh rate for quote updates from the MetaSwap API
|
// Sets the network config from the MetaSwap API.
|
||||||
async _setSwapsRefreshRates() {
|
async _setSwapsNetworkConfig() {
|
||||||
const chainId = this._getCurrentChainId();
|
const chainId = this._getCurrentChainId();
|
||||||
let swapsRefreshRates;
|
let swapsNetworkConfig;
|
||||||
try {
|
try {
|
||||||
swapsRefreshRates = await this.fetchSwapsRefreshRates(chainId);
|
swapsNetworkConfig = await this.fetchSwapsNetworkConfig(chainId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Request for swaps quote refresh time failed: ', e);
|
console.error('Request for Swaps network config failed: ', e);
|
||||||
}
|
}
|
||||||
const { swapsState: latestSwapsState } = this.store.getState();
|
const { swapsState: latestSwapsState } = this.store.getState();
|
||||||
this.store.updateState({
|
this.store.updateState({
|
||||||
swapsState: {
|
swapsState: {
|
||||||
...latestSwapsState,
|
...latestSwapsState,
|
||||||
swapsQuoteRefreshTime:
|
swapsQuoteRefreshTime:
|
||||||
swapsRefreshRates?.quotes || FALLBACK_QUOTE_REFRESH_TIME,
|
swapsNetworkConfig?.quotes || FALLBACK_QUOTE_REFRESH_TIME,
|
||||||
swapsQuotePrefetchingRefreshTime:
|
swapsQuotePrefetchingRefreshTime:
|
||||||
swapsRefreshRates?.quotesPrefetching || FALLBACK_QUOTE_REFRESH_TIME,
|
swapsNetworkConfig?.quotesPrefetching || FALLBACK_QUOTE_REFRESH_TIME,
|
||||||
swapsStxGetTransactionsRefreshTime:
|
swapsStxGetTransactionsRefreshTime:
|
||||||
swapsRefreshRates?.stxGetTransactions ||
|
swapsNetworkConfig?.stxGetTransactions ||
|
||||||
FALLBACK_SMART_TRANSACTION_REFRESH_TIME,
|
FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
swapsStxBatchStatusRefreshTime:
|
swapsStxBatchStatusRefreshTime:
|
||||||
swapsRefreshRates?.stxBatchStatus ||
|
swapsNetworkConfig?.stxBatchStatus ||
|
||||||
FALLBACK_SMART_TRANSACTION_REFRESH_TIME,
|
FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
swapsStxStatusDeadline:
|
swapsStxStatusDeadline:
|
||||||
swapsRefreshRates?.stxStatusDeadline ||
|
swapsNetworkConfig?.stxStatusDeadline ||
|
||||||
FALLBACK_SMART_TRANSACTIONS_DEADLINE,
|
FALLBACK_SMART_TRANSACTIONS_DEADLINE,
|
||||||
|
swapsStxMaxFeeMultiplier:
|
||||||
|
swapsNetworkConfig?.stxMaxFeeMultiplier ||
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -253,7 +261,7 @@ export default class SwapsController {
|
|||||||
this._fetchTradesInfo(fetchParams, {
|
this._fetchTradesInfo(fetchParams, {
|
||||||
...fetchParamsMetaData,
|
...fetchParamsMetaData,
|
||||||
}),
|
}),
|
||||||
this._setSwapsRefreshRates(),
|
this._setSwapsNetworkConfig(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -13,6 +13,10 @@ import { ETH_SWAPS_TOKEN_OBJECT } from '../../../shared/constants/swaps';
|
|||||||
import { createTestProviderTools } from '../../../test/stub/provider';
|
import { createTestProviderTools } from '../../../test/stub/provider';
|
||||||
import { SECOND } from '../../../shared/constants/time';
|
import { SECOND } from '../../../shared/constants/time';
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
|
import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
|
||||||
|
import {
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
|
FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
|
||||||
|
} from '../../../shared/constants/smartTransactions';
|
||||||
import SwapsController, { utils } from './swaps';
|
import SwapsController, { utils } from './swaps';
|
||||||
import { NETWORK_EVENTS } from './network';
|
import { NETWORK_EVENTS } from './network';
|
||||||
|
|
||||||
@ -134,8 +138,9 @@ const EMPTY_INIT_STATE = {
|
|||||||
swapsFeatureFlags: {},
|
swapsFeatureFlags: {},
|
||||||
swapsQuoteRefreshTime: 60000,
|
swapsQuoteRefreshTime: 60000,
|
||||||
swapsQuotePrefetchingRefreshTime: 60000,
|
swapsQuotePrefetchingRefreshTime: 60000,
|
||||||
swapsStxBatchStatusRefreshTime: 10000,
|
swapsStxBatchStatusRefreshTime: FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
swapsStxGetTransactionsRefreshTime: 10000,
|
swapsStxGetTransactionsRefreshTime: FALLBACK_SMART_TRANSACTIONS_REFRESH_TIME,
|
||||||
|
swapsStxMaxFeeMultiplier: FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
|
||||||
swapsUserFeeLevel: '',
|
swapsUserFeeLevel: '',
|
||||||
saveFetchedQuotes: false,
|
saveFetchedQuotes: false,
|
||||||
},
|
},
|
||||||
|
@ -18,10 +18,12 @@ import {
|
|||||||
getChainType,
|
getChainType,
|
||||||
} from '../../lib/util';
|
} from '../../lib/util';
|
||||||
import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/helpers/constants/error-keys';
|
import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/helpers/constants/error-keys';
|
||||||
|
import { calcGasTotal } from '../../../../ui/pages/send/send.utils';
|
||||||
import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/pages/swaps/swaps.util';
|
import { getSwapsTokensReceivedFromTxMeta } from '../../../../ui/pages/swaps/swaps.util';
|
||||||
import {
|
import {
|
||||||
hexWEIToDecGWEI,
|
hexWEIToDecGWEI,
|
||||||
decimalToHex,
|
decimalToHex,
|
||||||
|
hexWEIToDecETH,
|
||||||
} from '../../../../ui/helpers/utils/conversions.util';
|
} from '../../../../ui/helpers/utils/conversions.util';
|
||||||
import {
|
import {
|
||||||
TRANSACTION_STATUSES,
|
TRANSACTION_STATUSES,
|
||||||
@ -39,6 +41,7 @@ import {
|
|||||||
PRIORITY_LEVELS,
|
PRIORITY_LEVELS,
|
||||||
} from '../../../../shared/constants/gas';
|
} from '../../../../shared/constants/gas';
|
||||||
import { decGWEIToHexWEI } from '../../../../shared/modules/conversion.utils';
|
import { decGWEIToHexWEI } from '../../../../shared/modules/conversion.utils';
|
||||||
|
import { EVENT } from '../../../../shared/constants/metametrics';
|
||||||
import {
|
import {
|
||||||
HARDFORKS,
|
HARDFORKS,
|
||||||
MAINNET,
|
MAINNET,
|
||||||
@ -50,6 +53,7 @@ import {
|
|||||||
determineTransactionType,
|
determineTransactionType,
|
||||||
isEIP1559Transaction,
|
isEIP1559Transaction,
|
||||||
} from '../../../../shared/modules/transaction.utils';
|
} from '../../../../shared/modules/transaction.utils';
|
||||||
|
import { ORIGIN_METAMASK } from '../../../../shared/constants/app';
|
||||||
import TransactionStateManager from './tx-state-manager';
|
import TransactionStateManager from './tx-state-manager';
|
||||||
import TxGasUtil from './tx-gas-utils';
|
import TxGasUtil from './tx-gas-utils';
|
||||||
import PendingTransactionTracker from './pending-tx-tracker';
|
import PendingTransactionTracker from './pending-tx-tracker';
|
||||||
@ -62,6 +66,15 @@ const SWAP_TRANSACTION_TYPES = [
|
|||||||
TRANSACTION_TYPES.SWAP_APPROVAL,
|
TRANSACTION_TYPES.SWAP_APPROVAL,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Only certain types of transactions should be allowed to be specified when
|
||||||
|
// adding a new unapproved transaction.
|
||||||
|
const VALID_UNAPPROVED_TRANSACTION_TYPES = [
|
||||||
|
...SWAP_TRANSACTION_TYPES,
|
||||||
|
TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
|
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
|
||||||
|
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../../shared/constants/transaction').TransactionMeta} TransactionMeta
|
* @typedef {import('../../../../shared/constants/transaction').TransactionMeta} TransactionMeta
|
||||||
* @typedef {import('../../../../shared/constants/transaction').TransactionMetaMetricsEventString} TransactionMetaMetricsEventString
|
* @typedef {import('../../../../shared/constants/transaction').TransactionMetaMetricsEventString} TransactionMetaMetricsEventString
|
||||||
@ -432,7 +445,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
* @param {string} editableParams.gasPrice
|
* @param {string} editableParams.gasPrice
|
||||||
* @returns {TransactionMeta} the txMeta of the updated transaction
|
* @returns {TransactionMeta} the txMeta of the updated transaction
|
||||||
*/
|
*/
|
||||||
updateEditableParams(txId, { data, from, to, value, gas, gasPrice }) {
|
async updateEditableParams(txId, { data, from, to, value, gas, gasPrice }) {
|
||||||
this._throwErrorIfNotUnapprovedTx(txId, 'updateEditableParams');
|
this._throwErrorIfNotUnapprovedTx(txId, 'updateEditableParams');
|
||||||
|
|
||||||
const editableParams = {
|
const editableParams = {
|
||||||
@ -448,7 +461,20 @@ export default class TransactionController extends EventEmitter {
|
|||||||
|
|
||||||
// only update what is defined
|
// only update what is defined
|
||||||
editableParams.txParams = pickBy(editableParams.txParams);
|
editableParams.txParams = pickBy(editableParams.txParams);
|
||||||
|
|
||||||
|
// update transaction type in case it has changes
|
||||||
|
const transactionBeforeEdit = this._getTransaction(txId);
|
||||||
|
const { type } = await determineTransactionType(
|
||||||
|
{
|
||||||
|
...transactionBeforeEdit.txParams,
|
||||||
|
...editableParams.txParams,
|
||||||
|
},
|
||||||
|
this.query,
|
||||||
|
);
|
||||||
|
editableParams.type = type;
|
||||||
|
|
||||||
const note = `Update Editable Params for ${txId}`;
|
const note = `Update Editable Params for ${txId}`;
|
||||||
|
|
||||||
this._updateTransaction(txId, editableParams, note);
|
this._updateTransaction(txId, editableParams, note);
|
||||||
return this._getTransaction(txId);
|
return this._getTransaction(txId);
|
||||||
}
|
}
|
||||||
@ -636,6 +662,35 @@ export default class TransactionController extends EventEmitter {
|
|||||||
return this._getTransaction(txId);
|
return this._getTransaction(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append new sendFlowHistory to the transaction with id if the transaction
|
||||||
|
* state is unapproved. Returns the updated transaction.
|
||||||
|
*
|
||||||
|
* @param {string} txId - transaction id
|
||||||
|
* @param {Array<{ entry: string, timestamp: number }>} sendFlowHistory -
|
||||||
|
* history to add to the sendFlowHistory property of txMeta.
|
||||||
|
* @returns {TransactionMeta} the txMeta of the updated transaction
|
||||||
|
*/
|
||||||
|
updateTransactionSendFlowHistory(txId, sendFlowHistory) {
|
||||||
|
this._throwErrorIfNotUnapprovedTx(txId, 'updateTransactionSendFlowHistory');
|
||||||
|
const txMeta = this._getTransaction(txId);
|
||||||
|
|
||||||
|
// only update what is defined
|
||||||
|
const note = `Update sendFlowHistory for ${txId}`;
|
||||||
|
|
||||||
|
this.txStateManager.updateTransaction(
|
||||||
|
{
|
||||||
|
...txMeta,
|
||||||
|
sendFlowHistory: [
|
||||||
|
...(txMeta?.sendFlowHistory ?? []),
|
||||||
|
...sendFlowHistory,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
note,
|
||||||
|
);
|
||||||
|
return this._getTransaction(txId);
|
||||||
|
}
|
||||||
|
|
||||||
// ====================================================================================================================================================
|
// ====================================================================================================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -645,12 +700,18 @@ export default class TransactionController extends EventEmitter {
|
|||||||
* @param txParams
|
* @param txParams
|
||||||
* @param origin
|
* @param origin
|
||||||
* @param transactionType
|
* @param transactionType
|
||||||
|
* @param sendFlowHistory
|
||||||
* @returns {txMeta}
|
* @returns {txMeta}
|
||||||
*/
|
*/
|
||||||
async addUnapprovedTransaction(txParams, origin, transactionType) {
|
async addUnapprovedTransaction(
|
||||||
|
txParams,
|
||||||
|
origin,
|
||||||
|
transactionType,
|
||||||
|
sendFlowHistory = [],
|
||||||
|
) {
|
||||||
if (
|
if (
|
||||||
transactionType !== undefined &&
|
transactionType !== undefined &&
|
||||||
!SWAP_TRANSACTION_TYPES.includes(transactionType)
|
!VALID_UNAPPROVED_TRANSACTION_TYPES.includes(transactionType)
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`TransactionController - invalid transactionType value: ${transactionType}`,
|
`TransactionController - invalid transactionType value: ${transactionType}`,
|
||||||
@ -672,9 +733,10 @@ export default class TransactionController extends EventEmitter {
|
|||||||
let txMeta = this.txStateManager.generateTxMeta({
|
let txMeta = this.txStateManager.generateTxMeta({
|
||||||
txParams: normalizedTxParams,
|
txParams: normalizedTxParams,
|
||||||
origin,
|
origin,
|
||||||
|
sendFlowHistory,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (origin === 'metamask') {
|
if (origin === ORIGIN_METAMASK) {
|
||||||
// Assert the from address is the selected address
|
// Assert the from address is the selected address
|
||||||
if (normalizedTxParams.from !== this.getSelectedAddress()) {
|
if (normalizedTxParams.from !== this.getSelectedAddress()) {
|
||||||
throw ethErrors.rpc.internal({
|
throw ethErrors.rpc.internal({
|
||||||
@ -783,7 +845,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
// then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice.
|
// then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice.
|
||||||
txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice;
|
txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice;
|
||||||
txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice;
|
txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice;
|
||||||
if (eip1559V2Enabled && txMeta.origin !== 'metamask') {
|
if (eip1559V2Enabled && txMeta.origin !== ORIGIN_METAMASK) {
|
||||||
txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED;
|
txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED;
|
||||||
} else {
|
} else {
|
||||||
txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE;
|
txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE;
|
||||||
@ -794,7 +856,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
defaultMaxPriorityFeePerGas &&
|
defaultMaxPriorityFeePerGas &&
|
||||||
!txMeta.txParams.maxFeePerGas &&
|
!txMeta.txParams.maxFeePerGas &&
|
||||||
!txMeta.txParams.maxPriorityFeePerGas) ||
|
!txMeta.txParams.maxPriorityFeePerGas) ||
|
||||||
txMeta.origin === 'metamask'
|
txMeta.origin === ORIGIN_METAMASK
|
||||||
) {
|
) {
|
||||||
txMeta.userFeeLevel = GAS_RECOMMENDATIONS.MEDIUM;
|
txMeta.userFeeLevel = GAS_RECOMMENDATIONS.MEDIUM;
|
||||||
} else if (eip1559V2Enabled) {
|
} else if (eip1559V2Enabled) {
|
||||||
@ -1779,7 +1841,10 @@ export default class TransactionController extends EventEmitter {
|
|||||||
txMeta,
|
txMeta,
|
||||||
'transactions/pending-tx-tracker#event: tx:confirmed reference to confirmed txHash with same nonce',
|
'transactions/pending-tx-tracker#event: tx:confirmed reference to confirmed txHash with same nonce',
|
||||||
);
|
);
|
||||||
this._dropTransaction(otherTxMeta.id);
|
// Drop any transaction that wasn't previously failed (off chain failure)
|
||||||
|
if (otherTxMeta.status !== TRANSACTION_STATUSES.FAILED) {
|
||||||
|
this._dropTransaction(otherTxMeta.id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1827,13 +1892,37 @@ export default class TransactionController extends EventEmitter {
|
|||||||
this.memStore.updateState({ unapprovedTxs, currentNetworkTxList });
|
this.memStore.updateState({ unapprovedTxs, currentNetworkTxList });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_calculateTransactionsCost(txMeta, approvalTxMeta) {
|
||||||
|
let approvalGasCost = '0x0';
|
||||||
|
if (approvalTxMeta?.txReceipt) {
|
||||||
|
approvalGasCost = calcGasTotal(
|
||||||
|
approvalTxMeta.txReceipt.gasUsed,
|
||||||
|
approvalTxMeta.txReceipt.effectiveGasPrice,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const tradeGasCost = calcGasTotal(
|
||||||
|
txMeta.txReceipt.gasUsed,
|
||||||
|
txMeta.txReceipt.effectiveGasPrice,
|
||||||
|
);
|
||||||
|
const tradeAndApprovalGasCost = new BigNumber(tradeGasCost, 16)
|
||||||
|
.plus(approvalGasCost, 16)
|
||||||
|
.toString(16);
|
||||||
|
return {
|
||||||
|
approvalGasCostInEth: Number(hexWEIToDecETH(approvalGasCost)),
|
||||||
|
tradeGasCostInEth: Number(hexWEIToDecETH(tradeGasCost)),
|
||||||
|
tradeAndApprovalGasCostInEth: Number(
|
||||||
|
hexWEIToDecETH(tradeAndApprovalGasCost),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
_trackSwapsMetrics(txMeta, approvalTxMeta) {
|
_trackSwapsMetrics(txMeta, approvalTxMeta) {
|
||||||
if (this._getParticipateInMetrics() && txMeta.swapMetaData) {
|
if (this._getParticipateInMetrics() && txMeta.swapMetaData) {
|
||||||
if (txMeta.txReceipt.status === '0x0') {
|
if (txMeta.txReceipt.status === '0x0') {
|
||||||
this._trackMetaMetricsEvent({
|
this._trackMetaMetricsEvent({
|
||||||
event: 'Swap Failed',
|
event: 'Swap Failed',
|
||||||
sensitiveProperties: { ...txMeta.swapMetaData },
|
sensitiveProperties: { ...txMeta.swapMetaData },
|
||||||
category: 'swaps',
|
category: EVENT.CATEGORIES.SWAPS,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const tokensReceived = getSwapsTokensReceivedFromTxMeta(
|
const tokensReceived = getSwapsTokensReceivedFromTxMeta(
|
||||||
@ -1861,14 +1950,23 @@ export default class TransactionController extends EventEmitter {
|
|||||||
.round(2)}%`
|
.round(2)}%`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
const transactionsCost = this._calculateTransactionsCost(
|
||||||
|
txMeta,
|
||||||
|
approvalTxMeta,
|
||||||
|
);
|
||||||
|
|
||||||
this._trackMetaMetricsEvent({
|
this._trackMetaMetricsEvent({
|
||||||
event: 'Swap Completed',
|
event: 'Swap Completed',
|
||||||
category: 'swaps',
|
category: EVENT.CATEGORIES.SWAPS,
|
||||||
sensitiveProperties: {
|
sensitiveProperties: {
|
||||||
...txMeta.swapMetaData,
|
...txMeta.swapMetaData,
|
||||||
token_to_amount_received: tokensReceived,
|
token_to_amount_received: tokensReceived,
|
||||||
quote_vs_executionRatio: quoteVsExecutionRatio,
|
quote_vs_executionRatio: quoteVsExecutionRatio,
|
||||||
estimated_vs_used_gasRatio: estimatedVsUsedGasRatio,
|
estimated_vs_used_gasRatio: estimatedVsUsedGasRatio,
|
||||||
|
approval_gas_cost_in_eth: transactionsCost.approvalGasCostInEth,
|
||||||
|
trade_gas_cost_in_eth: transactionsCost.tradeGasCostInEth,
|
||||||
|
trade_and_approval_gas_cost_in_eth:
|
||||||
|
transactionsCost.tradeAndApprovalGasCostInEth,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1893,7 +1991,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
defaultGasEstimates,
|
defaultGasEstimates,
|
||||||
metamaskNetworkId: network,
|
metamaskNetworkId: network,
|
||||||
} = txMeta;
|
} = txMeta;
|
||||||
const source = referrer === 'metamask' ? 'user' : 'dapp';
|
const source = referrer === ORIGIN_METAMASK ? 'user' : 'dapp';
|
||||||
|
|
||||||
const { assetType, tokenStandard } = await determineTransactionAssetType(
|
const { assetType, tokenStandard } = await determineTransactionAssetType(
|
||||||
txMeta,
|
txMeta,
|
||||||
@ -1955,6 +2053,10 @@ export default class TransactionController extends EventEmitter {
|
|||||||
gasParams.estimate_used = estimateUsed;
|
gasParams.estimate_used = estimateUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extraParams?.gas_used) {
|
||||||
|
gasParams.gas_used = extraParams.gas_used;
|
||||||
|
}
|
||||||
|
|
||||||
const gasParamsInGwei = this._getGasValuesInGWEI(gasParams);
|
const gasParamsInGwei = this._getGasValuesInGWEI(gasParams);
|
||||||
|
|
||||||
let eip1559Version = '0';
|
let eip1559Version = '0';
|
||||||
@ -1985,8 +2087,8 @@ export default class TransactionController extends EventEmitter {
|
|||||||
: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
|
: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
|
||||||
first_seen: time,
|
first_seen: time,
|
||||||
gas_limit: gasLimit,
|
gas_limit: gasLimit,
|
||||||
...gasParamsInGwei,
|
|
||||||
...extraParams,
|
...extraParams,
|
||||||
|
...gasParamsInGwei,
|
||||||
};
|
};
|
||||||
|
|
||||||
return { properties, sensitiveProperties };
|
return { properties, sensitiveProperties };
|
||||||
@ -2036,7 +2138,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
// occur.
|
// occur.
|
||||||
case TRANSACTION_EVENTS.ADDED:
|
case TRANSACTION_EVENTS.ADDED:
|
||||||
this.createEventFragment({
|
this.createEventFragment({
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
initialEvent: TRANSACTION_EVENTS.ADDED,
|
initialEvent: TRANSACTION_EVENTS.ADDED,
|
||||||
successEvent: TRANSACTION_EVENTS.APPROVED,
|
successEvent: TRANSACTION_EVENTS.APPROVED,
|
||||||
failureEvent: TRANSACTION_EVENTS.REJECTED,
|
failureEvent: TRANSACTION_EVENTS.REJECTED,
|
||||||
@ -2057,7 +2159,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
case TRANSACTION_EVENTS.APPROVED:
|
case TRANSACTION_EVENTS.APPROVED:
|
||||||
case TRANSACTION_EVENTS.REJECTED:
|
case TRANSACTION_EVENTS.REJECTED:
|
||||||
this.createEventFragment({
|
this.createEventFragment({
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
successEvent: TRANSACTION_EVENTS.APPROVED,
|
successEvent: TRANSACTION_EVENTS.APPROVED,
|
||||||
failureEvent: TRANSACTION_EVENTS.REJECTED,
|
failureEvent: TRANSACTION_EVENTS.REJECTED,
|
||||||
properties,
|
properties,
|
||||||
@ -2078,7 +2180,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
// properties to the transaction event.
|
// properties to the transaction event.
|
||||||
case TRANSACTION_EVENTS.SUBMITTED:
|
case TRANSACTION_EVENTS.SUBMITTED:
|
||||||
this.createEventFragment({
|
this.createEventFragment({
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
initialEvent: TRANSACTION_EVENTS.SUBMITTED,
|
initialEvent: TRANSACTION_EVENTS.SUBMITTED,
|
||||||
successEvent: TRANSACTION_EVENTS.FINALIZED,
|
successEvent: TRANSACTION_EVENTS.FINALIZED,
|
||||||
properties,
|
properties,
|
||||||
@ -2097,7 +2199,7 @@ export default class TransactionController extends EventEmitter {
|
|||||||
// fragment does not exist.
|
// fragment does not exist.
|
||||||
case TRANSACTION_EVENTS.FINALIZED:
|
case TRANSACTION_EVENTS.FINALIZED:
|
||||||
this.createEventFragment({
|
this.createEventFragment({
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
successEvent: TRANSACTION_EVENTS.FINALIZED,
|
successEvent: TRANSACTION_EVENTS.FINALIZED,
|
||||||
properties,
|
properties,
|
||||||
sensitiveProperties,
|
sensitiveProperties,
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
getTestAccounts,
|
getTestAccounts,
|
||||||
} from '../../../../test/stub/provider';
|
} from '../../../../test/stub/provider';
|
||||||
import mockEstimates from '../../../../test/data/mock-estimates.json';
|
import mockEstimates from '../../../../test/data/mock-estimates.json';
|
||||||
|
import { EVENT } from '../../../../shared/constants/metametrics';
|
||||||
import {
|
import {
|
||||||
TRANSACTION_STATUSES,
|
TRANSACTION_STATUSES,
|
||||||
TRANSACTION_TYPES,
|
TRANSACTION_TYPES,
|
||||||
@ -26,6 +27,7 @@ import {
|
|||||||
import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions';
|
import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
|
||||||
import { TOKEN_STANDARDS } from '../../../../ui/helpers/constants/common';
|
import { TOKEN_STANDARDS } from '../../../../ui/helpers/constants/common';
|
||||||
|
import { ORIGIN_METAMASK } from '../../../../shared/constants/app';
|
||||||
import TransactionController from '.';
|
import TransactionController from '.';
|
||||||
|
|
||||||
const noop = () => true;
|
const noop = () => true;
|
||||||
@ -791,7 +793,7 @@ describe('Transaction Controller', function () {
|
|||||||
},
|
},
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
|
transaction_envelope_type: TRANSACTION_ENVELOPE_TYPE_NAMES.LEGACY,
|
||||||
origin: 'metamask',
|
origin: ORIGIN_METAMASK,
|
||||||
chainId: currentChainId,
|
chainId: currentChainId,
|
||||||
time: 1624408066355,
|
time: 1624408066355,
|
||||||
metamaskNetworkId: currentNetworkId,
|
metamaskNetworkId: currentNetworkId,
|
||||||
@ -1442,7 +1444,7 @@ describe('Transaction Controller', function () {
|
|||||||
nonce: '0x4b',
|
nonce: '0x4b',
|
||||||
},
|
},
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
origin: 'metamask',
|
origin: ORIGIN_METAMASK,
|
||||||
chainId: currentChainId,
|
chainId: currentChainId,
|
||||||
time: 1624408066355,
|
time: 1624408066355,
|
||||||
metamaskNetworkId: currentNetworkId,
|
metamaskNetworkId: currentNetworkId,
|
||||||
@ -1459,7 +1461,7 @@ describe('Transaction Controller', function () {
|
|||||||
successEvent: 'Transaction Approved',
|
successEvent: 'Transaction Approved',
|
||||||
failureEvent: 'Transaction Rejected',
|
failureEvent: 'Transaction Rejected',
|
||||||
uniqueIdentifier: 'transaction-added-1',
|
uniqueIdentifier: 'transaction-added-1',
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
persist: true,
|
persist: true,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
@ -1467,8 +1469,8 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_attempted: 'none',
|
gas_edit_attempted: 'none',
|
||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'metamask',
|
referrer: ORIGIN_METAMASK,
|
||||||
source: 'user',
|
source: EVENT.SOURCE.TRANSACTION.USER,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -1538,7 +1540,7 @@ describe('Transaction Controller', function () {
|
|||||||
initialEvent: 'Transaction Submitted',
|
initialEvent: 'Transaction Submitted',
|
||||||
successEvent: 'Transaction Finalized',
|
successEvent: 'Transaction Finalized',
|
||||||
uniqueIdentifier: 'transaction-submitted-1',
|
uniqueIdentifier: 'transaction-submitted-1',
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
persist: true,
|
persist: true,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
@ -1546,8 +1548,8 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_attempted: 'none',
|
gas_edit_attempted: 'none',
|
||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'metamask',
|
referrer: ORIGIN_METAMASK,
|
||||||
source: 'user',
|
source: EVENT.SOURCE.TRANSACTION.USER,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -1627,7 +1629,7 @@ describe('Transaction Controller', function () {
|
|||||||
successEvent: 'Transaction Approved',
|
successEvent: 'Transaction Approved',
|
||||||
failureEvent: 'Transaction Rejected',
|
failureEvent: 'Transaction Rejected',
|
||||||
uniqueIdentifier: 'transaction-added-1',
|
uniqueIdentifier: 'transaction-added-1',
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
persist: true,
|
persist: true,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
@ -1636,7 +1638,7 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'other',
|
referrer: 'other',
|
||||||
source: 'dapp',
|
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -1708,7 +1710,7 @@ describe('Transaction Controller', function () {
|
|||||||
initialEvent: 'Transaction Submitted',
|
initialEvent: 'Transaction Submitted',
|
||||||
successEvent: 'Transaction Finalized',
|
successEvent: 'Transaction Finalized',
|
||||||
uniqueIdentifier: 'transaction-submitted-1',
|
uniqueIdentifier: 'transaction-submitted-1',
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
persist: true,
|
persist: true,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
@ -1717,7 +1719,7 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'other',
|
referrer: 'other',
|
||||||
source: 'dapp',
|
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -1789,7 +1791,7 @@ describe('Transaction Controller', function () {
|
|||||||
successEvent: 'Transaction Approved',
|
successEvent: 'Transaction Approved',
|
||||||
failureEvent: 'Transaction Rejected',
|
failureEvent: 'Transaction Rejected',
|
||||||
uniqueIdentifier: 'transaction-added-1',
|
uniqueIdentifier: 'transaction-added-1',
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
persist: true,
|
persist: true,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
@ -1798,7 +1800,7 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'other',
|
referrer: 'other',
|
||||||
source: 'dapp',
|
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -1853,11 +1855,11 @@ describe('Transaction Controller', function () {
|
|||||||
failureEvent: 'Transaction Rejected',
|
failureEvent: 'Transaction Rejected',
|
||||||
uniqueIdentifier: 'transaction-added-1',
|
uniqueIdentifier: 'transaction-added-1',
|
||||||
persist: true,
|
persist: true,
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
properties: {
|
properties: {
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'other',
|
referrer: 'other',
|
||||||
source: 'dapp',
|
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
eip_1559_version: '0',
|
eip_1559_version: '0',
|
||||||
@ -1926,7 +1928,7 @@ describe('Transaction Controller', function () {
|
|||||||
failureEvent: 'Transaction Rejected',
|
failureEvent: 'Transaction Rejected',
|
||||||
uniqueIdentifier: 'transaction-added-1',
|
uniqueIdentifier: 'transaction-added-1',
|
||||||
persist: true,
|
persist: true,
|
||||||
category: 'Transactions',
|
category: EVENT.CATEGORIES.TRANSACTIONS,
|
||||||
properties: {
|
properties: {
|
||||||
chain_id: '0x2a',
|
chain_id: '0x2a',
|
||||||
eip_1559_version: '1',
|
eip_1559_version: '1',
|
||||||
@ -1934,7 +1936,7 @@ describe('Transaction Controller', function () {
|
|||||||
gas_edit_type: 'none',
|
gas_edit_type: 'none',
|
||||||
network: '42',
|
network: '42',
|
||||||
referrer: 'other',
|
referrer: 'other',
|
||||||
source: 'dapp',
|
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||||
account_type: 'MetaMask',
|
account_type: 'MetaMask',
|
||||||
asset_type: ASSET_TYPES.NATIVE,
|
asset_type: ASSET_TYPES.NATIVE,
|
||||||
@ -2243,4 +2245,125 @@ describe('Transaction Controller', function () {
|
|||||||
assert.equal(result.destinationTokenAddress, VALID_ADDRESS_TWO); // not updated even though it's passed in to update
|
assert.equal(result.destinationTokenAddress, VALID_ADDRESS_TWO); // not updated even though it's passed in to update
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('updateEditableParams', function () {
|
||||||
|
let txStateManager;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
txStateManager = txController.txStateManager;
|
||||||
|
txStateManager.addTransaction({
|
||||||
|
id: '1',
|
||||||
|
status: TRANSACTION_STATUSES.UNAPPROVED,
|
||||||
|
metamaskNetworkId: currentNetworkId,
|
||||||
|
txParams: {
|
||||||
|
gas: '0x001',
|
||||||
|
gasPrice: '0x002',
|
||||||
|
// max fees can not be mixed with gasPrice
|
||||||
|
// maxPriorityFeePerGas: '0x003',
|
||||||
|
// maxFeePerGas: '0x004',
|
||||||
|
to: VALID_ADDRESS,
|
||||||
|
from: VALID_ADDRESS,
|
||||||
|
},
|
||||||
|
estimateUsed: '0x005',
|
||||||
|
estimatedBaseFee: '0x006',
|
||||||
|
decEstimatedBaseFee: '6',
|
||||||
|
type: 'simpleSend',
|
||||||
|
userEditedGasLimit: '0x008',
|
||||||
|
userFeeLevel: 'medium',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates editible params when type changes from simple send to token transfer', async function () {
|
||||||
|
// test update gasFees
|
||||||
|
await txController.updateEditableParams('1', {
|
||||||
|
data:
|
||||||
|
'0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000',
|
||||||
|
});
|
||||||
|
const result = txStateManager.getTransaction('1');
|
||||||
|
assert.equal(
|
||||||
|
result.txParams.data,
|
||||||
|
'0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000',
|
||||||
|
);
|
||||||
|
assert.equal(result.type, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates editible params when type changes from token transfer to simple send', async function () {
|
||||||
|
// test update gasFees
|
||||||
|
txStateManager.addTransaction({
|
||||||
|
id: '2',
|
||||||
|
status: TRANSACTION_STATUSES.UNAPPROVED,
|
||||||
|
metamaskNetworkId: currentNetworkId,
|
||||||
|
txParams: {
|
||||||
|
gas: '0x001',
|
||||||
|
gasPrice: '0x002',
|
||||||
|
// max fees can not be mixed with gasPrice
|
||||||
|
// maxPriorityFeePerGas: '0x003',
|
||||||
|
// maxFeePerGas: '0x004',
|
||||||
|
to: VALID_ADDRESS,
|
||||||
|
from: VALID_ADDRESS,
|
||||||
|
data:
|
||||||
|
'0xa9059cbb000000000000000000000000e18035bf8712672935fdb4e5e431b1a0183d2dfc0000000000000000000000000000000000000000000000000de0b6b3a7640000',
|
||||||
|
},
|
||||||
|
estimateUsed: '0x005',
|
||||||
|
estimatedBaseFee: '0x006',
|
||||||
|
decEstimatedBaseFee: '6',
|
||||||
|
type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
|
||||||
|
userEditedGasLimit: '0x008',
|
||||||
|
userFeeLevel: 'medium',
|
||||||
|
});
|
||||||
|
await txController.updateEditableParams('2', {
|
||||||
|
data: '0x',
|
||||||
|
});
|
||||||
|
const result = txStateManager.getTransaction('2');
|
||||||
|
assert.equal(result.txParams.data, '0x');
|
||||||
|
assert.equal(result.type, TRANSACTION_TYPES.SIMPLE_SEND);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates editible params when type changes from simpleSend to contract interaction', async function () {
|
||||||
|
// test update gasFees
|
||||||
|
txStateManager.addTransaction({
|
||||||
|
id: '3',
|
||||||
|
status: TRANSACTION_STATUSES.UNAPPROVED,
|
||||||
|
metamaskNetworkId: currentNetworkId,
|
||||||
|
txParams: {
|
||||||
|
gas: '0x001',
|
||||||
|
gasPrice: '0x002',
|
||||||
|
// max fees can not be mixed with gasPrice
|
||||||
|
// maxPriorityFeePerGas: '0x003',
|
||||||
|
// maxFeePerGas: '0x004',
|
||||||
|
to: VALID_ADDRESS,
|
||||||
|
from: VALID_ADDRESS,
|
||||||
|
},
|
||||||
|
estimateUsed: '0x005',
|
||||||
|
estimatedBaseFee: '0x006',
|
||||||
|
decEstimatedBaseFee: '6',
|
||||||
|
type: TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
|
||||||
|
userEditedGasLimit: '0x008',
|
||||||
|
userFeeLevel: 'medium',
|
||||||
|
});
|
||||||
|
providerResultStub.eth_getCode = '0x5';
|
||||||
|
await txController.updateEditableParams('3', {
|
||||||
|
data: '0x123',
|
||||||
|
});
|
||||||
|
const result = txStateManager.getTransaction('3');
|
||||||
|
assert.equal(result.txParams.data, '0x123');
|
||||||
|
assert.equal(result.type, TRANSACTION_TYPES.CONTRACT_INTERACTION);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates editible params when type does not change', async function () {
|
||||||
|
// test update gasFees
|
||||||
|
await txController.updateEditableParams('1', {
|
||||||
|
data: '0x123',
|
||||||
|
gas: '0xabc',
|
||||||
|
from: VALID_ADDRESS_TWO,
|
||||||
|
});
|
||||||
|
const result = txStateManager.getTransaction('1');
|
||||||
|
assert.equal(result.txParams.data, '0x123');
|
||||||
|
assert.equal(result.txParams.gas, '0xabc');
|
||||||
|
assert.equal(result.txParams.from, VALID_ADDRESS_TWO);
|
||||||
|
assert.equal(result.txParams.to, VALID_ADDRESS);
|
||||||
|
assert.equal(result.txParams.gasPrice, '0x002');
|
||||||
|
assert.equal(result.type, TRANSACTION_TYPES.SIMPLE_SEND);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import createId from '../../../../shared/modules/random-id';
|
|||||||
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction';
|
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller';
|
||||||
import { transactionMatchesNetwork } from '../../../../shared/modules/transaction.utils';
|
import { transactionMatchesNetwork } from '../../../../shared/modules/transaction.utils';
|
||||||
|
import { ORIGIN_METAMASK } from '../../../../shared/constants/app';
|
||||||
import {
|
import {
|
||||||
generateHistoryEntry,
|
generateHistoryEntry,
|
||||||
replayHistory,
|
replayHistory,
|
||||||
@ -92,7 +93,7 @@ export default class TransactionStateManager extends EventEmitter {
|
|||||||
if (
|
if (
|
||||||
opts.txParams &&
|
opts.txParams &&
|
||||||
typeof opts.origin === 'string' &&
|
typeof opts.origin === 'string' &&
|
||||||
opts.origin !== 'metamask'
|
opts.origin !== ORIGIN_METAMASK
|
||||||
) {
|
) {
|
||||||
if (typeof opts.txParams.gasPrice !== 'undefined') {
|
if (typeof opts.txParams.gasPrice !== 'undefined') {
|
||||||
dappSuggestedGasFees = {
|
dappSuggestedGasFees = {
|
||||||
@ -126,6 +127,7 @@ export default class TransactionStateManager extends EventEmitter {
|
|||||||
chainId,
|
chainId,
|
||||||
loadingDefaults: true,
|
loadingDefaults: true,
|
||||||
dappSuggestedGasFees,
|
dappSuggestedGasFees,
|
||||||
|
sendFlowHistory: [],
|
||||||
...opts,
|
...opts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
KOVAN_NETWORK_ID,
|
KOVAN_NETWORK_ID,
|
||||||
} from '../../../../shared/constants/network';
|
} from '../../../../shared/constants/network';
|
||||||
import { GAS_LIMITS } from '../../../../shared/constants/gas';
|
import { GAS_LIMITS } from '../../../../shared/constants/gas';
|
||||||
|
import { ORIGIN_METAMASK } from '../../../../shared/constants/app';
|
||||||
import TxStateManager from './tx-state-manager';
|
import TxStateManager from './tx-state-manager';
|
||||||
import { snapshotFromTxMeta } from './lib/tx-state-history-helpers';
|
import { snapshotFromTxMeta } from './lib/tx-state-history-helpers';
|
||||||
|
|
||||||
@ -1188,7 +1189,7 @@ describe('TransactionStateManager', function () {
|
|||||||
};
|
};
|
||||||
const generatedTransaction = txStateManager.generateTxMeta({
|
const generatedTransaction = txStateManager.generateTxMeta({
|
||||||
txParams,
|
txParams,
|
||||||
origin: 'metamask',
|
origin: ORIGIN_METAMASK,
|
||||||
});
|
});
|
||||||
assert.ok(generatedTransaction);
|
assert.ok(generatedTransaction);
|
||||||
assert.strictEqual(generatedTransaction.dappSuggestedGasFees, null);
|
assert.strictEqual(generatedTransaction.dappSuggestedGasFees, null);
|
||||||
|
55
app/scripts/detect-multiple-instances.js
Normal file
55
app/scripts/detect-multiple-instances.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Sets up two-way communication between the
|
||||||
|
* mainline version of extension and Flask build
|
||||||
|
* in order to detect & warn if there are two different
|
||||||
|
* versions running simultaneously.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import browser from 'webextension-polyfill';
|
||||||
|
import {
|
||||||
|
PLATFORM_CHROME,
|
||||||
|
PLATFORM_FIREFOX,
|
||||||
|
CHROME_BUILD_IDS,
|
||||||
|
FIREFOX_BUILD_IDS,
|
||||||
|
} from '../../shared/constants/app';
|
||||||
|
import { getPlatform } from './lib/util';
|
||||||
|
|
||||||
|
const MESSAGE_TEXT = 'isRunning';
|
||||||
|
|
||||||
|
const showWarning = () =>
|
||||||
|
console.warn('Warning! You have multiple instances of MetaMask running!');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the ping message sent from other extension.
|
||||||
|
* Displays console warning if it's active.
|
||||||
|
*
|
||||||
|
* @param message - The message received from the other extension
|
||||||
|
*/
|
||||||
|
export const onMessageReceived = (message) => {
|
||||||
|
if (message === MESSAGE_TEXT) {
|
||||||
|
showWarning();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the ping message sent to other extensions to detect whether it's active or not.
|
||||||
|
*/
|
||||||
|
export const checkForMultipleVersionsRunning = async () => {
|
||||||
|
if (getPlatform() !== PLATFORM_CHROME && getPlatform() !== PLATFORM_FIREFOX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const buildIds =
|
||||||
|
getPlatform() === PLATFORM_CHROME ? CHROME_BUILD_IDS : FIREFOX_BUILD_IDS;
|
||||||
|
|
||||||
|
const thisBuild = browser.runtime.id;
|
||||||
|
|
||||||
|
for (const id of buildIds) {
|
||||||
|
if (id !== thisBuild) {
|
||||||
|
try {
|
||||||
|
await browser.runtime.sendMessage(id, MESSAGE_TEXT);
|
||||||
|
} catch (error) {
|
||||||
|
// Should do nothing if receiving end was not reached (no other instances running)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
104
app/scripts/detect-multiple-instances.test.js
Normal file
104
app/scripts/detect-multiple-instances.test.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import browser from 'webextension-polyfill';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import {
|
||||||
|
PLATFORM_CHROME,
|
||||||
|
PLATFORM_EDGE,
|
||||||
|
METAMASK_BETA_CHROME_ID,
|
||||||
|
METAMASK_PROD_CHROME_ID,
|
||||||
|
METAMASK_FLASK_CHROME_ID,
|
||||||
|
} from '../../shared/constants/app';
|
||||||
|
import {
|
||||||
|
checkForMultipleVersionsRunning,
|
||||||
|
onMessageReceived,
|
||||||
|
} from './detect-multiple-instances';
|
||||||
|
import * as util from './lib/util';
|
||||||
|
|
||||||
|
describe('multiple instances running detector', function () {
|
||||||
|
const PING_MESSAGE = 'isRunning';
|
||||||
|
|
||||||
|
let sendMessageStub = sinon.stub();
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
sinon.replace(browser, 'runtime', {
|
||||||
|
sendMessage: sendMessageStub,
|
||||||
|
id: METAMASK_BETA_CHROME_ID,
|
||||||
|
});
|
||||||
|
|
||||||
|
sinon.stub(util, 'getPlatform').callsFake((_) => {
|
||||||
|
return PLATFORM_CHROME;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('checkForMultipleVersionsRunning', function () {
|
||||||
|
it('should send ping message to multiple instances', async function () {
|
||||||
|
await checkForMultipleVersionsRunning();
|
||||||
|
|
||||||
|
assert(sendMessageStub.calledTwice);
|
||||||
|
assert(
|
||||||
|
sendMessageStub
|
||||||
|
.getCall(0)
|
||||||
|
.calledWithExactly(METAMASK_PROD_CHROME_ID, PING_MESSAGE),
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
sendMessageStub
|
||||||
|
.getCall(1)
|
||||||
|
.calledWithExactly(METAMASK_FLASK_CHROME_ID, PING_MESSAGE),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not send ping message if platform is not Chrome or Firefox', async function () {
|
||||||
|
util.getPlatform.restore();
|
||||||
|
sendMessageStub = sinon.stub();
|
||||||
|
|
||||||
|
sinon.stub(util, 'getPlatform').callsFake((_) => {
|
||||||
|
return PLATFORM_EDGE;
|
||||||
|
});
|
||||||
|
|
||||||
|
await checkForMultipleVersionsRunning();
|
||||||
|
|
||||||
|
assert(sendMessageStub.notCalled);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not expose an error outside if sendMessage throws', async function () {
|
||||||
|
sinon.restore();
|
||||||
|
|
||||||
|
sinon.replace(browser, 'runtime', {
|
||||||
|
sendMessage: sinon.stub().throws(),
|
||||||
|
id: METAMASK_BETA_CHROME_ID,
|
||||||
|
});
|
||||||
|
|
||||||
|
const spy = sinon.spy(checkForMultipleVersionsRunning);
|
||||||
|
|
||||||
|
await checkForMultipleVersionsRunning();
|
||||||
|
|
||||||
|
assert(!spy.threw());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onMessageReceived', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
sinon.spy(console, 'warn');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should print warning message to on ping message received', async function () {
|
||||||
|
onMessageReceived(PING_MESSAGE);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
console.warn.calledWithExactly(
|
||||||
|
'Warning! You have multiple instances of MetaMask running!',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not print warning message if wrong message received', async function () {
|
||||||
|
onMessageReceived(PING_MESSAGE.concat('wrong'));
|
||||||
|
|
||||||
|
assert(console.warn.notCalled);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -7,24 +7,32 @@ import {
|
|||||||
MAINNET_CHAIN_ID,
|
MAINNET_CHAIN_ID,
|
||||||
RINKEBY_CHAIN_ID,
|
RINKEBY_CHAIN_ID,
|
||||||
ROPSTEN_CHAIN_ID,
|
ROPSTEN_CHAIN_ID,
|
||||||
MAINNET_NETWORK_ID,
|
|
||||||
BUYABLE_CHAINS_MAP,
|
BUYABLE_CHAINS_MAP,
|
||||||
} from '../../../shared/constants/network';
|
} from '../../../shared/constants/network';
|
||||||
import { SECOND } from '../../../shared/constants/time';
|
import { SECOND } from '../../../shared/constants/time';
|
||||||
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
|
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
|
||||||
import { TRANSAK_API_KEY, MOONPAY_API_KEY } from '../constants/on-ramp';
|
import {
|
||||||
|
TRANSAK_API_KEY,
|
||||||
|
MOONPAY_API_KEY,
|
||||||
|
COINBASEPAY_API_KEY,
|
||||||
|
} from '../constants/on-ramp';
|
||||||
|
|
||||||
const fetchWithTimeout = getFetchWithTimeout(SECOND * 30);
|
const fetchWithTimeout = getFetchWithTimeout(SECOND * 30);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Wyre purchase URL.
|
* Create a Wyre purchase URL.
|
||||||
*
|
*
|
||||||
* @param {string} address - Ethereum destination address
|
* @param {string} walletAddress - Ethereum destination address
|
||||||
|
* @param {string} chainId - Current chain ID
|
||||||
* @returns String
|
* @returns String
|
||||||
*/
|
*/
|
||||||
const createWyrePurchaseUrl = async (address) => {
|
const createWyrePurchaseUrl = async (walletAddress, chainId) => {
|
||||||
const fiatOnRampUrlApi = `${SWAPS_API_V2_BASE_URL}/networks/${MAINNET_NETWORK_ID}/fiatOnRampUrl?serviceName=wyre&destinationAddress=${address}`;
|
const { wyre = {} } = BUYABLE_CHAINS_MAP[chainId];
|
||||||
const wyrePurchaseUrlFallback = `https://pay.sendwyre.com/purchase?dest=ethereum:${address}&destCurrency=ETH&accountId=AC-7AG3W4XH4N2&paymentMethod=debit-card`;
|
const { srn, currencyCode } = wyre;
|
||||||
|
|
||||||
|
const networkId = parseInt(chainId, 16);
|
||||||
|
const fiatOnRampUrlApi = `${SWAPS_API_V2_BASE_URL}/networks/${networkId}/fiatOnRampUrl?serviceName=wyre&destinationAddress=${walletAddress}`;
|
||||||
|
const wyrePurchaseUrlFallback = `https://pay.sendwyre.com/purchase?dest=${srn}:${walletAddress}&destCurrency=${currencyCode}&accountId=AC-7AG3W4XH4N2&paymentMethod=debit-card`;
|
||||||
try {
|
try {
|
||||||
const response = await fetchWithTimeout(fiatOnRampUrlApi, {
|
const response = await fetchWithTimeout(fiatOnRampUrlApi, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
@ -108,6 +116,28 @@ const createMoonPayUrl = async (walletAddress, chainId) => {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Coinbase Pay Checkout URL.
|
||||||
|
*
|
||||||
|
* @param {string} walletAddress - Ethereum destination address
|
||||||
|
* @param {string} chainId - Current chain ID
|
||||||
|
* @returns String
|
||||||
|
*/
|
||||||
|
const createCoinbasePayUrl = (walletAddress, chainId) => {
|
||||||
|
const { coinbasePayCurrencies } = BUYABLE_CHAINS_MAP[chainId];
|
||||||
|
const queryParams = new URLSearchParams({
|
||||||
|
appId: COINBASEPAY_API_KEY,
|
||||||
|
attribution: 'extension',
|
||||||
|
destinationWallets: JSON.stringify([
|
||||||
|
{
|
||||||
|
address: walletAddress,
|
||||||
|
assets: coinbasePayCurrencies,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
return `https://pay.coinbase.com/buy?${queryParams}`;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives the caller a url at which the user can acquire eth, depending on the network they are in
|
* Gives the caller a url at which the user can acquire eth, depending on the network they are in
|
||||||
*
|
*
|
||||||
@ -127,11 +157,13 @@ export default async function getBuyUrl({ chainId, address, service }) {
|
|||||||
|
|
||||||
switch (service) {
|
switch (service) {
|
||||||
case 'wyre':
|
case 'wyre':
|
||||||
return await createWyrePurchaseUrl(address);
|
return await createWyrePurchaseUrl(address, chainId);
|
||||||
case 'transak':
|
case 'transak':
|
||||||
return createTransakUrl(address, chainId);
|
return createTransakUrl(address, chainId);
|
||||||
case 'moonpay':
|
case 'moonpay':
|
||||||
return createMoonPayUrl(address, chainId);
|
return createMoonPayUrl(address, chainId);
|
||||||
|
case 'coinbase':
|
||||||
|
return createCoinbasePayUrl(address, chainId);
|
||||||
case 'metamask-faucet':
|
case 'metamask-faucet':
|
||||||
return 'https://faucet.metamask.io/';
|
return 'https://faucet.metamask.io/';
|
||||||
case 'rinkeby-faucet':
|
case 'rinkeby-faucet':
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { EVENT_NAMES } from '../../../shared/constants/metametrics';
|
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||||
import { SECOND } from '../../../shared/constants/time';
|
import { SECOND } from '../../../shared/constants/time';
|
||||||
|
|
||||||
const USER_PROMPTED_EVENT_NAME_MAP = {
|
const USER_PROMPTED_EVENT_NAME_MAP = {
|
||||||
@ -46,7 +46,7 @@ export default function createRPCMethodTrackingMiddleware({
|
|||||||
const userRejected = res.error?.code === 4001;
|
const userRejected = res.error?.code === 4001;
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event: USER_PROMPTED_EVENT_NAME_MAP[req.method],
|
event: USER_PROMPTED_EVENT_NAME_MAP[req.method],
|
||||||
category: 'inpage_provider',
|
category: EVENT.CATEGORIES.INPAGE_PROVIDER,
|
||||||
referrer: {
|
referrer: {
|
||||||
url: origin,
|
url: origin,
|
||||||
},
|
},
|
||||||
@ -62,7 +62,7 @@ export default function createRPCMethodTrackingMiddleware({
|
|||||||
} else if (typeof samplingTimeouts[req.method] === 'undefined') {
|
} else if (typeof samplingTimeouts[req.method] === 'undefined') {
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event: 'Provider Method Called',
|
event: 'Provider Method Called',
|
||||||
category: 'inpage_provider',
|
category: EVENT.CATEGORIES.INPAGE_PROVIDER,
|
||||||
referrer: {
|
referrer: {
|
||||||
url: origin,
|
url: origin,
|
||||||
},
|
},
|
||||||
|
@ -4,6 +4,7 @@ import { bufferToHex, stripHexPrefix } from 'ethereumjs-util';
|
|||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
||||||
|
import { EVENT } from '../../../shared/constants/metametrics';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
||||||
import createId from '../../../shared/modules/random-id';
|
import createId from '../../../shared/modules/random-id';
|
||||||
import { addHexPrefix } from './util';
|
import { addHexPrefix } from './util';
|
||||||
@ -227,7 +228,7 @@ export default class DecryptMessageManager extends EventEmitter {
|
|||||||
if (reason) {
|
if (reason) {
|
||||||
this.metricsEvent({
|
this.metricsEvent({
|
||||||
event: reason,
|
event: reason,
|
||||||
category: 'Messages',
|
category: EVENT.CATEGORIES.MESSAGES,
|
||||||
properties: {
|
properties: {
|
||||||
action: 'Decrypt Message Request',
|
action: 'Decrypt Message Request',
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import { ObservableStore } from '@metamask/obs-store';
|
|||||||
import { ethErrors } from 'eth-rpc-errors';
|
import { ethErrors } from 'eth-rpc-errors';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
||||||
|
import { EVENT } from '../../../shared/constants/metametrics';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
||||||
import createId from '../../../shared/modules/random-id';
|
import createId from '../../../shared/modules/random-id';
|
||||||
|
|
||||||
@ -216,7 +217,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter {
|
|||||||
if (reason) {
|
if (reason) {
|
||||||
this.metricsEvent({
|
this.metricsEvent({
|
||||||
event: reason,
|
event: reason,
|
||||||
category: 'Messages',
|
category: EVENT.CATEGORIES.MESSAGES,
|
||||||
properties: {
|
properties: {
|
||||||
action: 'Encryption public key Request',
|
action: 'Encryption public key Request',
|
||||||
},
|
},
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user