In #10510 we changed how tokens are stored, keying them by `chainId`
rather than network type. However we didn't update our mobile sync
function to account for this, which ended up breaking the filtering
logic used to prepare the data that is synced.
Specifically, custom tokens added by users are filtered out to just
those that are confirmed to be ERC20 tokens in our built-in list of
tokens. This filters out unrecognized tokens and NFTs.
The filtering logic has been restored to the pre-#10510 behaviour.
* use @lavamoat/allow-scripts for package postinstall allow list
* dnode: set "weak" to false
Co-authored-by: kumavis <kumavis@users.noreply.github.com>
Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com>
Fixes#10111
Determine if the msgParams/address for the newRequestEncryptionPublicKey is a ledger keyring via getKeyringForAccount and return a promise rejection.
This restores support for versions of the inpage provider prior to v8.
This is intended to support dapps and extensions that directly
instantiated their own provider rather than using the injected
provider.
* Forward traffic between old and new provider streams
* Ignore publicConfig stream for non-legacy muxes
* Transform accountsChanged notification for legacy streams
* Convert publicConfigStore to singleton
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Migration 51: ensure chainId is set in network controller provider state for all infura/default networks
* Clean up
* Migrate incorrect as well as falsy chainIds
Co-authored-by: Erik Marks <rekmarks@protonmail.com>
Our automatic token detection was hard-coded to only work on our built-
in Infura Mainnet endpoint. It now works with custom Mainnet RPC
endpoints as well.
Relates to #6992
The `disable-console` script introduced in #10040 used an arrow-
function no-op function to replace `console.log` and `console.info`.
This replacement function was early-bound to the `this` context of the
`disable-console` script, because that's how arrow functions work.
This violates an assumption baked into Sentry, which also replaces the
`console` functions. It wraps them in a function it uses to track
console logs as breadcrumbs. This wrapper function blows up for some
reason if the "original" `console` function is early-bound to a `this`
value of `undefined`.
This resulted in various UI freezes. One example is during onboarding,
when using Firefox with Enhanced Tracking Protection set in "strict"
mode. After submitting a password in the 'Create wallet' flow, the
Sentry `console` wrapper would throw and leave the user stuck on the
loading screen.
By replacing the no-op arrow function with a no-op function
declaration, the problem has been resolved.
Relates to #10097
Failure to persist state will now only report to Sentry if the last
attempt to save state succeeded. This ensures that if anyone is stuck
in a state where state can't be saved (e.g. low disk space), we aren't
flooded with repeated errors on Sentry.
This update comes with a breaking change to the Approval controller. It
now requires a `defaultApprovalType` parameter.
I don't think we have any use for a default approval type, but I've
added a "NO_TYPE" one for now because it's a strict requirement. We
should consider making this parameter optional in the future, for cases
like this where it's not needed.
This update will hopefully address some caching issues we've been
seeing with our phishing configuration. See here for more details:
https://github.com/MetaMask/controllers/pull/297
`eth_getProof` is an unpermissioned, read-only RPC method for getting account-related Merkle proofs, specified here: https://eips.ethereum.org/EIPS/eip-1186
It's been supported by major Ethereum clients, and Infura, for some time. By adding it to the safe methods list, we enable this method for our users.
* Maintain console logging in dev mode
Co-authored-by: kumavis <aaron@kumavis.me>
Co-authored-by: Erik Marks <rekmarks@protonmail.com>
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
This PR introduces the new approval controller to the extension codebase. We use it for the permissions controller's pending approval functionality.
The approval controller sets us up for a new pattern of requesting and managing user confirmations in RPC methods. Along with the generic RPC method middleware, the approval controller will allow us to eliminate our message managers, and decouple various method handlers from our provider stack, making the implementations more portable between the extension and mobile.
On Firefox 56 and Waterfox Classic, our `runLockdown.js` script throws
an error. This is fine on the HTML pages, as the next script tags still
get run without issue (though they don't benefit from the SES lockdown
sadly). But in the `contentscript`, an exception thrown here appears to
halt the execution of subsequent scripts.
To prevent the `contentscript` from crashing completely, lockdown
errors are now caught and logged. They are also logged to Sentry on the
pages where Sentry is setup.
From a behavioral standpoint this PR fixes the issue with tracking, and persisting, tokens that the user hides. Whether we can/should optimize this to prevent duplicates of the accountHiddenTokens and hiddenToken is a point of contention, but it acts similiarly to how we track tokens and accountTokens.
Also to note, for tokens under a custom network there is no way to distinguish two different custom network sets of hidden tokens, they are all under the `rpc` property, same as accountTokens.
* @metamask/inpage-provider@^8.0.0
* Replace public config store with JSON-RPC notifications
* Encapsulate notification permissioning in permissions controller
* Update prefix of certain internal RPC methods and notifications
* Add accounts to getProviderState
* Send accounts with isUnlocked notification (#10007)
* Rename provider streams, notify provider of stream failures (#10006)
The new metrics controller has a `trackEvent` function that was being
called unbound, so `this` references were undefined. It is now bound
early in both places where it is passed in as a parameter.
The SES lockdown added in #9729 had the effect of obfuscating our error
messages. Any messages printed to the console would have the error
message replaced with the string "Error #" followed by a number. The
stack was also updated to point at `lockdown.cjs`, though the original
stack was preserved beneath the top stack frame.
Marking the `console` API as untamed seems to have fixed both issues.
The original error message is now printed to the console, along with
the original stack.
* Migration to remove legacy local storage keys from localStorage
* Update app/scripts/migrations/050.js
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Update app/scripts/migrations/050.js
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Fix unit tests for migration 50
* Fixing stubbing and localstorage reference in migration 50
* Update test/helper.js
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Attempts to send metrics would fail when no `options` were used. This
was because when the options parameter was not set, it was often sent
over our RPC connection as `undefined`, which gets serialized to `null`
when the message is converted to JSON. This `null` parameter didn't
trigger the default parameter set in the metametrics controller, as
default parameters are only used for `undefined`.
Instead the `options` parameter is now treated as fully optional, with
no default value set. The optional chaining operator is used to ensure
it won't blow up if it's not set. A fallback of `{}` was used for the
one destructure case as well.
If a `gasPrice` was specified in a transaction sent via a dapp, we
would include it in our `eth_estimateGas` call, causing it to fail if
the user had insufficient balance (for either the transaction amount or
the gas fee). This resulted in the fallback gas estimate being used;
the block gas limit. The block gas limit is quite a bit larger than
most transactions need, so this resulted in wildly inflated gas costs
being shown on our confirmation screen.
The `gasPrice` has been removed from the `txParams` object we pass to
`eth_estimateGas`, so now it won't perform any balance checks anymore.
This ensures that we'll get a valid gas estimate, as long as geth is
able to simulate the contract execution properly.
Fixes#9967
* Remove use of ethgassthat; use metaswap /gasPrices api for gas price estimates
* Remove references to ethgasstation
* Pass base to BigNumber constructor in fetchExternalBasicGasEstimates
* Update ui/app/hooks/useTokenTracker.js
Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com>
* Delete gas price chart
* Remove price chart css import
* Delete additional fee chart code
* Lint fix
* Delete more code no longer used after ethgasstation removal
Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com>
* Freezeglobals: remove Promise freezing, add lockdown
* background & UI: temp disable sentry
* add loose-envify, dedupe symbol-observable
* use loose envify
* add symbol-observable patch
* run freezeGlobals after sentry init
* use require instead of import
* add lockdown to contentscript
* add error code in message
* try increasing node env heap size to 2048
* change back circe CI option
* make freezeGlobals an exported function
* make freezeGlobals an exported function
* use freezeIntrinsics
* pass down env to child process
* fix unknown module
* fix tests
* change back to 2048
* fix import error
* attempt to fix memory error
* fix lint
* fix lint
* fix mem gain
* use lockdown in phishing detect
* fix lint
* move sentry init into freezeIntrinsics to run lockdown before other imports
* lint fix
* custom lockdown modules per context
* lint fix
* fix global test
* remove run in child process
* remove lavamoat-core, use ses, require lockdown directly
* revert childprocess
* patch package postinstall
* revert back child process
* add postinstall to ci
* revert node max space size to 1024
* put back loose-envify
* Disable sentry to see if e2e tetss pass
* use runLockdown, add as script in manifest
* remove global and require from runlockdown
* add more memory to tests
* upgrade resource class for prep-build & prep-build-test
* fix lint
* lint fix
* upgrade remote-redux-devtools
* skillfully re-add sentry
* lintfix
* fix lint
* put back beep
* remove envify, add loose-envify and patch-package in dev deps
* Replace patch with Yarn resolution (#9923)
Instead of patching `symbol-observable`, this ensures that all
versions of `symbol-observable` are resolved to the given range, even
if it contradicts the requested range.
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The `matomo` option passed to the send metrics function is invalid. The
intent was to set the `matomoEvent` option, but instead of rectifying
that, we've decide to keep sending this event to the production Segment
project for now. The invalid option has been removed.
A few inconsistencies in JSDoc formatting have been fixed throughout
the project. Many issues remain; these were just the few things that
were easy to fix with a regular expression.
The changes include:
* Using lower-case for primitive types, but capitalizing non-primitive
types
* Separating the parameter identifier and the description with a dash
* Omitting a dash between the return type and the return description
* Ensuring the parameter type is first and the identifier is second (in
a few places it was backwards)
* Using square brackets to denote when a parameter is optional, rather
than putting "(optional)" in the parameter description
* Including a type and identifier with every parameter
* Fixing inconsistent spacing, except where it's used for alignment
* Remove incorrectly formatted `@deprecated` tags that reference non-
existent properties
* Remove lone comment block without accompanying function
Additionally, one parameter was renamed for clarity.
The `seedPhraseBackedUp` now tracks whether or not the seed phrase has
been backed up. Previously this defaulted to `true`, which left no way
to distinguish whether it had been backed up or not during onboarding.
The default is now `null`, and the UI logic has been updated to account
for this, so that "existing users" (i.e. users that have a backup that
is years old) aren't mistakenly considered to have not backed up their
seed phrase. This value is already set explicitly to `true` or `false`
during onboarding, in both the create and import flow.
This change was made primarily to make it easier to fix the onboarding
library integration, which will be done in a subsequent PR.
* Alternative savings fix
* Further required changes to savings fix
* Further fix to savings calculations that properly accounts for metamask fees
* metaMaskFeeInEth property on quotes to decimal string
* Fix swaps controller unit tests
* Improve documentation in swaps controller
* Prevent getMedianEthValueQuote from mutation passed quotes array with .sort() call
* Another fix and refactor to savings calculations in _findTopQuoteAndCalculateSavings
Cleaner structuring of conditionals for setting tokenValueOfQuoteForSorting, ethValueOfQuote and metaMaskFeeInEth in swaps controller
Stop subtracting medianMetaMaskFee from savings, but include it in savings data
Another fix and refactor to savings calculations in _findTopQuoteAndCalculateSavings
* Add and update unit tests for _findTopQuoteAndCalculateSavings
* Improve calculation of overallValueOfQuoteForSorting for case where ETH is the source token
* Clean up getMedianEthValueQuote code, test and comments
* Clean up _findTopQuoteAndCalculateSavings, create test input and expected results helper functions
* Update getMedianEthValueQuote to account for multiple quotes with overall values equal to the median
* Add jsdoc comment for meansOfQuotesFeesAndValue
* Fix jsdoc comment for getMedianEthValueQuote
* create custom addHexPrefix function
* switch to custom addHexPrefix
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Co-authored-by: Erik Marks <rekmarks@protonmail.com>
* Log web3 usage for functions and nested properties only
* Change web3 metrics source to legacy
* Update web3 metrics properties and event name
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The incoming transactions controller now uses the `chainId` for the
current network instead of the `networkId`. This ensures that custom
RPC endpoints for the built-in supported networks do correctly receive
incoming transactions.
As part of this change, the incoming transactions controller will also
cease keeping track of the "last block fetched" for networks that are
not supported. This piece of state never really represented the last
block fetched, as _no_ blocks were fetched for any such networks. It
been removed.
If the swaps state is cleared in between the initial quote fetch and
the subsequent poll fetch, a `TypeError` will be thrown due to
`fetchParams` being set to `null`.
This is of no functional consequence, as `fetchParams` _should_ be
`null` in this case, and and no further action should be taken.
The optional chaining operator is now used to ensure the call no longer
throws.
This is a continuation of #9726, which did not fix the problem
described.
If the initial network when the extension is started is something other
than Mainnet, the swaps controller will never successfully retrieve
swap quotes. This is because `ethers` will continue to communicate
with whichever network the provider was initially on.
We tried fixing this by hard-coding the `chainId` to Mainnet's
`chainId` when constructing the Ethers provider, but this did not work.
I suspect this failed because the `provider` we pass to `ethers` is not
compliant with EIP 1193, as `ethers` doubtless expects it to be.
Instead the entire `ethers` provider is now reconstructed each time the
network changes. This mirrors the approach we take in some other
controllers.
If the initial network when the extension is started is something other
than Mainnet, the swaps controller will never successfully retrieve
swap quotes. This is because the `ethers` provider used by the swaps
controller doesn't allow network changes by default - it assumes that
the network remains the same as when the provider was initialized.
This was fixed by hard-coding Mainnet as the initial chain ID for this
`ethers` provider used by the swaps controller.
Some adjustments needed to be made to the `provider` stub to allow
setting `1` as the network ID and chain ID in unit tests.
Refs #9663
See [`node/no-deprecated-api`][1] for more information.
This change enables `node/no-deprecated-api` and fixes the issues raised by the rule.
[1]:https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-deprecated-api.md
The change to the way that `punycode` is imported is to address the fact that
third-party module is hidden by the built-in. This is a silly hack but it works.
Our ENS resolver for the browser address bar was incorrectly resolving
addresses that included query strings. We were concatenating the `path`
property with the `search` property, despite the fact that the `path`
property already contains `search`. As a result, `search` was
duplicated in the resolved addresses.
For example, if an IPFS content ID was found for this address, the
resolved address for `metamask.eth/?foo=bar` would have the path
`/?foo=bar?foo=bar`
The original intent was likely to use `pathname` in place of `path`.
The resolver has been updated to use `pathname`, and the query string
now appears only once in the resolved address.
Consolidates the background and UI segment implementations into a shared solution.
This results in the introduction of our first shared module.
Co-authored-by: Erik Marks <25517051+rekmarks@users.noreply.github.com>
`@metamask/eslint-config` has been updated to v4.1.0. This update
requires that we update `eslint` to v7 as well, which in turn requires
updating most `eslint`-related packages.
Most notably, `babel-eslint` was replaced with `@babel/eslint-parser`,
and `babel-eslint-plugin` was replaced by `@babel/eslint-plugin`. This
required renaming all the `babel/*` rules to `@babel/*`.
Most new or updated rules that resulted in lint errors have been
temporarily disabled. They will be fixed and re-enabled in subsequent
PRs.
* Calculate savings per swap relative to median values
* Update test mock quotes, add getMedian tests
* Identify assets by sourceToken and destinationToken
The account tracker had one doc comment above the constructor that
partially served to document the constructor, but mostly contained a
type definition for the class itself. It has been split into two
blocks; one for the class, one for the constructor. The constructor doc
comment has also been expanded to document all constructor options.
The `chainId` is now used by the account tracker to identify the
current network, instead of the `networkId`. This should have no
functional impact, aside from that different chains with the same
`networkId` will now be correctly distinguished from each other.
An attempt to safely release the `nonceLock` upon failure has instead
made failure worse by masking it with a new error. If the call to get
the `nonceLock` throws an exception, then the `finally` block here
would attempt to call `releaseLock` on the `nonceLock` variable, which
is guaranteed to be `undefined` if the previous call failed. The
attempt to call a method on `undefined` throws another error, masking
the original error.
It is safer to obtain the `nonceLock` and release it without using any
`try` or `finally` block. The `nonceLock` is synchronously released
immediately after it is obtained, and any errors bubble up correctly
without being masked. There is no case where the lock is left
unreleased.
If the `signTypedData` background function threw an exception, it would
return `undefined` to the UI, which would throw another exception in
the UI. It now re-throws the error if an error is thrown, which
allows the UI to handle the error.
I'm not sure why this might fail, and I'm not sure we're handling this
failure well, but this is an improvement at least.
* Add data point to 'Swaps Completed' segment event: estimated vs used gas
* Linted
* Correct property name for estimated gas on swapMetaData in _trackSwapsMetrics()
* Set estimated_gas property on swapMetaData to a hex string
* Correct base when dividing by estimated_gas
Co-authored-by: Dan Finlay <dan@danfinlay.com>
* Delete CachedBalancesController.cachedBalances
* Migrate provider to Rinkeby instead of deleting it
* Convert hex transaction metamaskNetworkId values to decimal
* Don't migrate provider state in e2e tests
* Don't kick custom RPC users to Rinkeby unnecessarily
* Use provider.chainId for address book chainId values
* Add address book migration
* Fix failing unit test
* fixup! Merge branch 'develop' into address-book-use-chainId
* Select address book entries for display by chainId
* Merge all address book entry keys
* fixup! Merge all address book entry keys
* Delete localhost provider type
* Use ganache-cli default chain ID for tests
* Delete unused test firstTimeState variable
* Migrate default ganache-cli network to frequentRpcListDetail
* Add default test provider state
* Add test functionality to createJsonRpcClient
* Lint locales
* Update test middleware creation
* fixup! Update test middleware creation
* Update txMeta after postTxBalance has been retrieved
* Use gas used from txReceipt to calculate eth received
* Return null from getSwapsTokensReceivedFromTxMeta in tokenSymbol is ETH and txReceipt is missing
* Get latest txMeta before updating it with postTxBalance in case of a swaps tx in confirmTransaction
* Lint fix
* Use initial transaction for settings swap transaction title params, and remove addition of swap properties to cancel transcations
* Update unit test data
* Use token symbol properties from initial transaction for filitering in transaction list
* call this.txStateManager.setTxStatusConfirmed before async call in confirmTransaction in the transactions controller
* Clone txMeta before setTxStatusConfirmed in confirmTransaction
* Correctly updateTx in confirmTransaction
* Track swaps event only if it is a swap transaction
* Create wrapper function for segment events
* Extract transaction controller metrics calls into own function
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Stop passing a gas param to the estimateGas call initiated in the swaps controller timedoutGasReturn
* Stop passing gas params to timedoutGasReturn
* Lint fix
* Stop passing no longer used param to setInitialGasEstimate
When the `chainId` for a custom RPC endpoint is edited, we now migrate
the corresponding address book entries to ensure they are not orphaned.
The address book entries are grouped by the `metamask.network` state,
which unfortunately was sometimes the `chainId`, and sometimes the
`networkId`. It was always the `networkId` for built-in Infura
networks, but for custom RPC endpoints it would be set to the user-set
`chainId` field, with a fallback to the `networkId` of the network.
A recent change will force users to enter valid `chainId`s on all
custom networks, which will be normalized to be hex-prefixed. As a
result, address book contacts will now be keyed by a different string.
The contact entries are now migrated when this edit takes place.
There are some edge cases where two separate entries share the same set
of contacts. For example, if two entries have the same `chainId`, or if
they had the same `networkId` and had no `chainId` set. When the
`chainId` is edited in such cases, the contacts are duplicated on both
networks. This is the best we can do, as we don't have any way to know
which network the contacts _should_ be on.
The `typed-message-manager` unit tests have also been updated as part
of this commit because the addition of `sinon.restore()` to the
preferences controller tests ended up clearing a test object in-between
individual tests in that file. The test object is now re-constructed
before each individual test.
The `_fetchAndSetSwapsLiveness` was accidentally passed to
`setInterval` without being bound first, so the `this` reference was
not defined when it was called. It is now bound before being passed to
`setInterval`.
* Remove network config store
* Remove inline networks variable in network controller
* Re-key network controller 'rpcTarget' to 'rpcUrl'
* Require chainId in lookupNetwork, implement eth_chainId
* Require chain ID in network form
* Add alert, migrations, and tests
* Add chainId validation to addToFrequentRpcList
* Update public config state selector to match new network controller
state
* Use network enums in networks-tab.constants
* Ensure chainId in provider config is current
* Update tests
Right now when editing an address in "Settings > Contact", the contact
is lost after saving. This is because the code awaits
`removeFromAddressBook()` before creating the new contact but
`removeFromAddressBook()` never resolves. This change fixes this bug.