The Sentry DSN is now expected to be provided via environment variable
for production builds. The build script will fail if it is missing, and
an error will be thrown at runtime if it is missing.
The `SENTRY_DSN` environment variable has been set in CI to the old
value for `SENTRY_PROD_DSN`. We can migrate to a new DSN at some point
in the future.
In a non-production environment, Sentry was configured to send error
reports to a "test" MetaMask project. It will still do this during e2e
tests, but in development Sentry is now disabled completely.
In practice this was never useful in development.
* Fix popup/notification when browser is in fullscreen, primarily on OSX.
The issue was reported internally via Slack. User was running Mac OSX Chrome in fullscreen mode where Chrome is created in a new Desktop workspace.
The issue reproduced on OSX Chrome in fullscreen/maximized view overrides the explicitly set width and height for `windows.create()`. Possibly not overrides, but creates a window based off of the window that it was created from. Found a related [Chromium bug](https://bugs.chromium.org/p/chromium/issues/detail?id=263092&q=window%20create%20width%20os%3DMac&can=2).
The fullscreen `popup.left` pixel will calculate the window position incorrectly since we set and assume the width of the created window. The incorrect `left` position the window and transition the focus Desktop/Workspace incorrectly and make is seem to lose focus of the new window/workspace. Incidentally this will make the popup full width/height, and create a new workspace for the view, which we have no control over until Chrome
fixes it.
This will check if the popup is 'fullscreen', which it gets passed from the origin window, if so then don't reposition the window. If Chrome fixes the issue we can revert this change.
* Feedback commit
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The `extra` property of errors sent to Sentry is sometimes not
initialized when we add the application state. A check has been added
to initialize it if it's missing.
I suspect that this changed with v5 of `@sentry/browser`, though I
can't find any explicit confirmation of this in their changelog.
The state snapshot that was attached to Sentry errors was removed
recently in #8794 because it had become too large. The snapshot has
now been restored and reduced in size.
A utility function has been written to reduce the state object to just
the requested properties. This seemed safer than filtering out state
that is known to be large or to contain identifiable information.
This is not a great solution, as now knowledge about the state shape
resides in this large constant, but it will suffice for now. I am
hopeful that we can decorate our controllers with this metadata in the
future instead, as part of the upcoming background controller refactor.
A separate `getSentryState` global function has been added to get the
reduced state, so that the old `getCleanAppState` function that we used
to use could remain unchanged. It's still useful to get that full state
copy while debugging, and in e2e tests.
This migration had referred to the non-existent
`TransactionsController` instead of `TransactionController`, so it
effectively did nothing. Now it should work.
This migration hasn't been included in any release yet, so we can fix
it in-place instead of adding an additional corrected migration.
The migration comment has also been updated, as it was inaccurate.
This method was accidentally broken with the introduction of the
permissions controller, as this was missing from the list of safe
methods.
It is now included in the list of safe methods.
Fixes#8993
The currency rate controller is updated upon each network change, as
the "native currency" is network-dependent and might have changed.
However, any thrown errors were being caught and passed to an empty
callback.
The errors are now re-thrown in the callback. As a result, the errors
will now be printed to the console and sent to Sentry.
It seems that this blocklist checker never worked correctly. Ever since
the initial commit, it was comparing the Number `1` to the `networkId`,
which is a string. Additionally, even if it did throw, the transaction
continued unhindered. The user could still approve it, and there was no
indication shown to the user that anything went wrong. Also some of the
blocklist entries were incorrectly mixed-case, and were never hit.
We can remove this for now, and re-add it later on after we rewrite the
transaction controller.
The `metamaskNetworkId` property in the `txMeta` for incoming
transactions was incorrectly set as a Number instead of a String. This
change was made accidentally as part of #8627.
As a result incoming transactions were being excluded from the
transaction list, as they didn't have a matching network ID.
`metamaskNetworkId` is now set to a string, and a migration has been
added to ensure `metamaskNetworkId` is converted to a string for any
incoming transactions in state.
An optimization in `account-tracker.js` was being skipped consistently
due to a type error (a number was being compared to a string).
The optimization in this case was to update the balances for all
accounts with a single request, rather than one request per account.
The `activeTab.id` property is relied upon in the connected sites modal
to prevent the user from manually connecting to the MetaMask extension
itself. Unfortunately the `id` property was never set.
`id` is now set on the `activeTab` state, so manually connecting to the
extension UI is now impossible.
The `activeTab` state is now set to an empty object if the `origin` of
the active tab is missing or invalid. It can be invalid if the URL
passed to the `URL` constructor is missing a scheme (e.g.
`about: blank`).
There are currently no cases where the rest of the data in `activeTab`
is useful in the absence of an `origin`. This will make upcoming UI
logic changes a bit simpler than they would be otherwise. Now we can
assume that if any property is set on `activeTab`, it must have a valid
`origin`.
There were three cases where execution unintentionally continued after
an error was encountered. These cases likely are impossible to
encounter in practice due to recent validation improvements in the
`eth-json-rpc-middleware/wallet` module, but they were broken
nonetheless.
Execution inside the Promise constructor now halts immediately after
`reject` is called.
* Use over the whole stringified error object which doesn't show the actual error message that is set as the
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Feedback commit
The code for checking whether a transaction was dropped or not was
refactored in #8398, but in the process an off-by-one error was
introduced.
The old version of `_checkIfTxWasDropped` would query for an updated
transaction count from the network, and would consider the pending
transaction to be dropped if the count was above the nonce. However,
the version introduced in #8398 considers the transaction to be dropped
if the count is above *or equal to* the nonce.
The pending transaction nonce is expected to be equal to the
transaction count, because the nonce starts at zero. The transaction
count is equal to the expected next nonce.
The variable name has been updated to make this more clear
(`networkNextNonce` is how the `nonce-tracker` refers to this value).
`parseInt` is now called with an explicit radix of `16` as well, to
ensure both nonce strings are always parsed as hex. In all cases I am
aware of, these nonce strings were prefixed by `0x`, meaning that
`parseInt` would default to a radix of `16`, so this likely doesn't
constitute a functional change.
Fixes#8688
* update connected accounts appearance
* consolidate account alerts
* UnconnectedAccountAlert: use ConnectedAccountsList
* move switch account action out of menu in all views
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Imported accounts can be removed, but the permissions controller is not
informed when this happens. Permissions are now removed as part of the
account removal process.
Additionally, the `getPermittedIdentitiesForCurrentTab` selector now
filters out any non-existent accounts, in case a render occurs in the
middle of an account removal.
This was resulting in a render crash upon opening the popup on a site
that was connected to the removed account.
The state snapshot we were attaching to Sentry errors was too large.
As a temporary solution, it has been removed completely. We can re-add
it later after reducing its size.
* restore and enhance the time est feature
background: we had a feature for showing a time estimate on pending txs
that was accidently removed during the redesign implementation. This PR
restores that feature and also enhances it:
1. Displays the time estimate on all views instead of just fullscreen
2. Uses Intl.RelativeTimeFormat to format the time
3. Adds a way to toggle the feature flag.
4. Uses a hook to calculate the time remaining instead of a component
* Update app/_locales/en/messages.json
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* do not display on test nets
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The `TokenRatesController` was accidentally broken in #8744, when the
logic for starting and stopping polling was moved from the `isActive`
property to start/stop functions.
A reference to the now-obsolete `isActive` property was accidentally
left behind, resulting in no exchange rate updates.
Each "message" requiring a user confirmation has a unique `type`
property. These `type` properties have all been added as enums, and the
enum is now used wherever the literal string was used previously.
A new page has been created for viewing assets. This replaces the old
`selectedToken` state, which previously would augment the home page
to show token-specific information.
The new asset page shows the standard token overview as seen previously
on the home page, plus a history filtered to show just transactions
relevant to that token.
The actions that were available in the old token list menu have been
moved to a "Token Options" menu that mirrors the "Account Options"
menu.
The `selectedTokenAddress` state has been removed, as it is no longer
being used for anything.
`getMetaMetricState` has been renamed to `getBackgroundMetaMetricState`
because its sole purpose is extracting data from the background state
to send metrics from the background. It's not really a selector, but
it was convenient for it to use the same selectors the UI uses to
extract background data, so I left it there for now.
A new Redux store has been added to track state related to browser history.
The most recent "overview" page (i.e. the home page or the asset page) is
currently being tracked, so that actions taken from the asset page can return
the user back to the asset page when the action has finished.
We inject `web3` globally on most websites. This has been breaking
websites that attempted to serialize the `window` object, because any
attempt to access certain `web3` properties (such as `web3.eth.mining`)
would throw an error. This is because `web3` defined a getter for these
properties that would call `.send([method])`, which doesn't work for
most methods.
An example of a site that this breaks is `Storybook`, when the
`@storybook/addon-actions` addon is being used. When using storybook
with this addon and with the MetaMask extension installed, actions
would not be properly dispatched because an error would be thrown in
the attempt to serialize the event (which includes a reference to the
`window`).
The `web3` global we inject is now defined as non-enumerable, so it
will be skipped automatically in any attempt to serialize the `window`
object.
Defaults have been added for all three preferences. The default values
added are both falsey, so this shouldn't result in any functional
change. This was done to help make this preferences more easily
discoverable.
The max listener count of the preferences store has been increased to
12. Recently the 12th listener was added, which resulted in console
warnings during the unit tests - this prevents those warnings.
The default max listener value is 10; we didn't see this warning until
now because one of the twelve listeners is only setup when 3Box is
enabled, which doesn't occur during our unit tests.
Add alert suggesting that the user switch to a connected account. This
alert is displayed when the popup is opened over an active tab that is
connected to some account, but not the current selected account. The
user can choose to switch to a connected account, or dismiss the alert.
This alert is only shown once per account switch. So if the user
repeatedly opens the popup on a dapp without switching accounts, it'll
only be shown the first time. The alert also won't be shown if the user
has just dismissed an "Unconnected account" alert on this same dapp
and account, as that would be redundant.
The alert has a "Don't show me this again" checkbox that allows the
user to disable the alert. It can be re-enabled again on the Alerts
settings page.
All transaction status updates were moved into a `setTimeout` callback
and wrapped in a `try...catch` block in #4131, apparently in an attempt
to prevent failures in event subscribers from interrupting the
transaction logic. The `try...catch` block did accomplish that, but by
putting the status update in a `setTimeout` callback the operation was
made asynchronous.
Transaction status updates now happen unpredictably, in some future
event loop from when they're triggered. This creates a race condition,
where the transaction status update may occur before or after
subsequent state changes. This also introduces a risk of accidentally
undoing a change to the transaction state, as the update made to the
transaction inside the `setTimeout` callback uses a reference to
`txMeta` obtained synchronously before the `setTimeout` call. Any
replacement of the `txMeta` between the `setTxStatus` call and the
execution of the timeout would be erased. Luckily the `txMeta` object
is more often than not mutated rather than replaced, which may explain
why we haven't seen this happen yet.
Everything seems to work correctly with the `setTimeout` call removed,
and now the transaction logic is easier to understand.
The unconnected account alert can now be disabled. A "don't show this
again" checkbox has been added to the alert, which prevents that alert
from being shown in the future.
An alert settings page has been added to the settings as well. This
page allows the user to disable or enable any alert.
This controller was not used. It was used by the
`ComputedBalancesController`, which was removed in #7057 (as it was
also unused).
The pending balances calculator was only used by the balances
controller.
The inactive timer was being reset upon any change to the preferences
store. The intent was only to update the timer when the auto-lock
timeout had changed, so the subscription was updated to only update in
those cases.
There are no indications that this had any effect upon the user. It
looks like the preferences store never updates while the extension is
unattended, so in practice this may have been harmless. It was still
pointless however. This also protects against the possibility of the
preferences store being updated while unattended at some point in the
future.
A race condition exists where after adding an unapproved transaction,
it could be mutated and then replaced when the default gas parameters
are set. This happens because the transaction is added to state and
broadcast before the default gas parameters are set, because
calculating the default gas parameters to use takes some time.
Once they've been calculated, the false assumption was made that the
transaction hadn't changed.
The method responsible for setting the default gas now retrieves an
up-to-date copy of `txMeta`, and conditionally sets the defaults only
if they haven't yet been set.
This race condition was introduced in #2962, though that PR also added
a loading screen that avoided this issue by preventing the user from
interacting with the transaction until after the gas had been
estimated. Unfortunately this loading screen was not carried forward to
the new UI.
* Remove `estimatedGas` property from `txMeta`
The `estimatedGas` property was a cache of the gas value estimated for
a transaction when the default gas limit was set. This property wasn't
used anywhere. It may have been useful for debugging purposes, but the
same gas estimate is already stored on the `history` property so it
should be present in state logs regardless.
* Remove `gasLimitSpecified` txMeta property
The `gasLimitSpecified` property of `txMeta` wasn't used for anything.
It might have been useful for debugging purposes, but whether or not
the gas limit was specified can also be determined from looking at the
transaction history, so it's not a huge loss.
* Remove `gasPriceSpecified` txMeta property
The `gasPriceSpecified` property of `txMeta` wasn't used for anything.
It might have been useful for debugging purposes, but whether or not
the gas price was specified can also be determined from looking at the
transaction history, so it's not a huge loss.
* Remove `simpleSend` txMeta property
The `simpleSend` property of `txMeta` was used to ensure a buffer was
not added to the gas limit during gas estimation for simple send
transactions. It was made redundant by #8484, which accomplishes this
without the use of this property.
Previously a transaction would get assigned a default value during the
`addTxGasDefaults` function, after the transaction was added and sent
to the UI.
Instead the transaction is assigned a default value before it gets
added. This flow is simpler to follow, and it avoids the race condition
where the transaction is assigned a value from the UI before this
default is set. In that situation, the UI-assigned value would be
overridden, which is obviously not desired.
`analyzeGasUsage` now returns the results of the analysis rather than
setting them directly on `txMeta`. The caller is now responsible for
mutating `txMeta` instead. Functionally this should be identical to
before.
The simple send gas estimation has been moved out of the gas estimation
module, and into the transaction controller. This was done in an effort
to limit the number of places where `txMeta` is mutated while the
default gas parameters are being set.
The `shift-list-item` component for displaying ShapeShift transactions
has been removed, along with three other components that were used
solely by that component (`copyButton`, `eth-balance`, and
`fiat-value`).
This component hasn't been used in some time, as ShapeShift
transactions no longer exist to display. The controller that ShapeShift
transactions originated from was removed in #8118, and it became
impossible to create new ShapeShift transactions from within MetaMask
in #6746
This state has been removed from the background. It was used for the
old UI, and has been unused for some time. A migration has been added
to delete this state as well.
The action creator responsible for updating this state has been removed
from the UI as well, along with the `callBackgroundThenUpdateNoSpinner`
convenience function, which was only used for this action.
Keyrings are added either through the `getKeyringForDevice` background
method (as part of the hardware wallet connect flow), or via
`importAccountWithStrategy` (when importing an account). The
`addNewKeyring` action and corresponding background method has not been
used in a long time.
* Add popover for informing user about the connected status indicator
* Ensure user only sees connected status info popover once
* Default connectedStatusPopoverHasBeenShown to true and set it to false in a migration
* Add unit test for migration 42
* Initialize AppStateController if it does not exist in migration 42
* Update connect indicator popup locale text
* Code cleanup for connected-indicator-info-popup
* Code cleanup for connected-indicator-info-popup
This method adds the given account to the given origin's list of
exposed accounts. This method is not yet used, but it will be in
subsequent PRs (e.g. #8312)
This method has been added to the background API, and a wrapper action
creator has been written as well.
Now that identities are available synchronously in the permissions
controller, accounts can be validated synchronously as well. Any
account the user wants to give permissions to should already be tracked
as an identity in the preferences controller.
* Fix order of accounts in `eth_accounts` response
The accounts returned by `eth_accounts` were in a fixed order - the
order in which the keyring returned them - rather than ordered with the
selected account first. The accounts returned by the `accountsChanged`
event were ordered with the selected account first, but the same order
wasn't used for `eth_accounts`.
We needed to store additional state in order to determine the correct
account order correctly on all dapps. We had only been storing the
current selected account, but since we also need to determine the
primary account per dapp (i.e. the last "selected" account among the
accounts exposed to that dapp), that wasn't enough.
A `lastSelected` property has been added to each identity in the
preferences controller to keep track of the last selected time. This
property is set to the current time (in milliseconds) whenever a new
selection is made. The accounts returned with `accountsChanged` and by
`eth_accounts` are both ordered by this property.
The `updatePermittedAccounts` function was merged with the internal
methods for responding to account selection, to keep things simpler. It
wasn't called externally anyway, so it wasn't needed in the public API.
* Remove caveat update upon change in selected account
The order of accounts in the caveat isn't meaningful, so the caveat
doesn't need to be updated when the accounts get re-ordered.
* Emit event regardless of account order
Now that we're no longer relying upon the caveat for the account order,
we also have no way of knowing if a particular account selection
resulted in a change in order or not. The notification is now emitted
whenever an exposed account is selected - even if the order stayed the
same.
The inpage provider currently caches the account order, so it can be
relied upon to ignore these redundant events. We were already emiting
redundant `accountsChanged` events in some cases anyway.
Selecting a new account now results in all domains that can view this
change being notified. Previously only the dapp in the active tab was
being notified (though not correctly, as the `origin` was accidentally
set to the MetaMask chrome extension origin).
This handling of account selection has been moved into the background
to minimize the gap between account selection and the notification
being sent out. It's simpler for the UI to not be involved anyway.
Previously all browser globals were allowed to be used anywhere by
ESLint because we had set the `env` property to `browser` in the ESLint
config. This has made it easy to accidentally use browser globals
(e.g. #8338), so it has been removed. Instead we now have a short list
of allowed globals.
All browser globals are now accessed as properties on `window`.
Unfortunately this change resulted in a few different confusing unit
test errors, as some of our unit tests setup assumed that a particular
global would be used via `window` or `global`. In particular,
`window.fetch` didn't work correctly because it wasn't patched by the
AbortController polyfill (only `global.fetch` was being patched).
The `jsdom-global` package we were using complicated matters by setting
all of the JSDOM `window` properties directly on `global`, overwriting
the `AbortController` for example.
The `helpers.js` test setup module has been simplified somewhat by
removing `jsdom-global` and constructing the JSDOM instance manually.
The JSDOM window is set on `window`, and a few properties are set on
`global` as well as needed by various dependencies. `node-fetch` and
the AbortController polyfill/patch now work as expected as well,
though `fetch` is only available on `window` now.
The tests for the detect-tokens controller were nearly all broken. They
have been fixed, and a few improvements were made to controller itself
to help with this.
* The core `detectNewTokens` method has been updated to be async, so
that the caller can know when the operation had completed.
* The part of the function that used `Web3` to check the token balances
has been split into a separate function, so that that part could be
stubbed out in tests. Eventually we should test this using `ganache`
instead, but this was an easier first step.
* The internal `tokenAddresses` array is now initialized on
construction, rather than upon the first Preferences controller update.
The `detectNewTokens` function would have previously failed if it ran
prior to this initialization, so it was failing if called before any
preferences state changes.
Additionally, the `detectTokenBalance` function was removed, as it was
no longer used.
The tests have been updated to ensure they're actually testing the
behavior they purport to be testing. I've simulated a test failure with
each one to check that it'd fail when it should. The preferences
controller instance was updated to set addresses correctly as well.
Any action in the background that would have opened the notification
window will now focus the window instead if it was already open.
Previously it would leave the window unfocused. This was particularly
inconvenient when taking multiple actions in quick succession that all
require confirmations (e.g. triggering multiple transactions).
The notification manager has been refactored to use the extension
platform module instead of using `extensionizer` directly. The
extension platform API presents a more ergonomic API, and it correctly
handles errors (which the old notification manager did not). Methods
that the extension platform lacked have been added.
It has been updated to use `async/await` instead of callbacks as well,
for readability.
The `triggerUI` function has also been updated to use the extension
platform instead of `extensionizer`.
During the initialization of the full-screen or popup UI, we attempted
to close the notification popup (if it was open). This never worked (or
at least hasn't in a long time).
The method used to attempt closing the notification popup was
`closePopup` from the `notificationManager`, which keeps track
internally of the id of the notification popup window, and can close
the window by using this id.
However, this id is only set in the first place if the popup is opened
with this specific instance of the `notificationManager`. The popup is
never opened from the UI in practice; it's only opened from the
background (which has its own instance of `notificationManager`). The
popup id is never set for this `notificationManager` instance in the UI.
It's not entirely clear that we'd always want to close the notification
popup in this circumstance anyway. The user might want to open MetaMask
alongside the popup to check something else.
MetaMask would sometimes get into a state where the notification popup
would never open. This could happen if the notification window was
closed shortly after being opened. After this happened, no popups would
show up until after the extension was reset.
This was happening because the background thought the popup was already
open. The variable it uses to track whether the popup was open or not
was being set to `true` immediately after the background asked the
browser to open a new window, before a handler was attached that could
respond to the window being closed.
Removing this line seems to solve the problem.
This line was added originally in #5437, which dealt with batch
transactions. Batches of transactions seem to work just fine without
this line though (from local testing), and I can't think of why this
would be required.
Closes#7051
* Connect screen popup redesign
* Open permission request in notification instead of tab
* Remove no longer user locales
* Update permissions unit test mock to accout for change of opts passed to permissions controller
* Lint fix
* Inline broken line svg in permission-page-container-content.component.js for faster loading
* Add back button to second screen on connect flow
* Add xOfY locale and use for the page count in the connect flow
* Lint fix for svgs permission-page-container-content.component.js
* Fix rebase error
* Lint fix
* Clean up styles on the connect-screen-into-popup branch
* Use closeCurrentWindow to close window on cancel when in full screen connect flow
* Handle errors in rejectPermissionsRequest
* Full screen styles for connect flow
* Lint fixed in permissions-connect and actions.js
* Redirect screen now shows metamask icon instead of users identicon
* Fix subtitle spacing in permissions-connect-header'
* Use window.close instead of closeCurrentWindow() in cancelPermissionsRequest
* Use permissions-connect-header__subtitle in permissions-connect-header.component
We don't need to store the current UI type as a global. We're already
using the `getEnvironmentType` helper function throughout the UI, so
we'd might as well use that instead of this global state.
The sidebar used to speed up a transaction while it's pending or after
it has failed currently allows editing the gas limit, but that new
limit is ignored. This is especially problematic for transactions that
failed due to a low gas limit, as the problem becomes impossible to fix
by retrying.
The gas limit specified by the user is now used in the speed up
transaction.
Fixes#8156Fixes#7977
Errors without stack traces would break the Sentry error processing,
which assumes the presence of a stack trace. Many errors don't have any
stack trace though, such as uncaught promises.
This breakage resulting in the app state being missing from the error
report, and a console warning.
The `tabId` of the message sender is now added to the middleware
request object. This step is omitted if the `tabId` is not provided.
This is done early in the middleware stack, so the `tabId` should be
available for any subsequent middleware to use.
The Onboarding Middleware has also been modified to get the `tabId`
from the request object, rather than expecting it as a parameter upon
creation.
This refactor will enable further uses of the `tabId`.
Implement `eth_decrypt` and `eth_getEncryptionPublicKey`. This allows decryption backed by the user's private key. The message decryption uses a confirmation flow similar to the messaging signing flow, where the message to be decrypted is also able to be decrypted inline for the user to read directly before confirming.
* Revert "Revert "Update Wyre ETH purchase url" (#7631)"
This reverts commit bc67d1eeca.
* Restrict widget to just debit card payments
Apple Pay apparently only works on Safari.
Any error sent to Sentry will now be marked with the environment they
were sent from. The environment is set at build time, and is set
dependant upon the build flags and CI-related environment variables.
Setting the environment will let us filter error reports in Sentry to
focus specifically upon reports sent from production, release
candidates, PR testing, or whatever else.
These two functions differ slightly in options, but none of those
options are being used by us, so in these cases they're functionally
equivalent. They're even both descendants of the original `debounce`
function from `underscore`.
This was done to reduce the number of direct dependencies we have. It
should not affect bundle size, as we still depend upon the `debounce`
package transitively.
This was done to reduce the number of direct dependencies we have. It
should be functionally equivalent. The bundle size should not change,
as we use `clone` as a transitive dependency in a number of places.
Previously, all errors encountered during testing or production were
sent to the primary `metamask` Sentry project, whereas development
errors were sent to `test-metamask` instead. This change ensures that
errors encountered during tests are sent to `test-metamask` as well.
Update accounts permission history on accountsChanged
Create PermissionsLogController
Fix permissions activity log pruning
Add selectors, background hooks for better UX
Make selected account the first account returned
Use enums for store keys in log controller
Add last selected address history to PreferencesController
* Remove unnecessary `getEnvironmentType` parameter
The default value of the first parameter is `window.location.href`, so
there is no need to pass it in explicitly.
* Remove junk parameter from `getEnvironmentType` invocation
`getEnvironmentType` doesn't need to be passed any parameter, as the
default value is `window.location.href` which is generally what is
wanted. In this case, the variable `location.href` was always
`undefined` anyway. This particular `location` variable is from React
Router, and does not have an `href` property.
* Fix comment for `getEnvironmentType`
One of the possible return values was referred to by the wrong name.
As of #7663, an in-memory store was used in place of local storage
during e2e tests, to facilitate the use of state fixtures. However,
this made it difficult to export state during a test run. The
instructions for exporting state to create fixtures assumed that local
storage was being used.
A new global function has been added to the background context to allow
exporting state. This method is available during testing and
development, and it works with either local storage or the in-memory
store. The fixture instructions have been updated to reference this new
function.
* Specify type before parameter name
Various JSDoc `@param` entries were specified as `name {type}` rather
than `{type} name`.
A couple of `@return` entries have been given types as well.
* Use JSDoc optional syntax rather than Closure syntax
* Use @returns rather than @return
* Use consistent built-in type capitalization
Primitive types are lower-case, and Object is upper-case.
* Separate param/return description with a dash
Typically the fullscreen UI will open upon installation, though this
behaviour was suppressed in development. This was dealt with in the e2e
tests by waiting for it to open, then closing it.
Instead this behaviour is now suppressed for test builds as well.
* Remove unused onboarding stream
* Pass `sender` through to `setupProviderEngine`
The Port `sender` has been passed down a few more layers. This allows
us to get more information from the sender deeper in the stack, but
also simplifies things a bit as well. For example, now the "fake"
URL object with the `metamask` hostname is no longer needed.
* Create onboarding middleware
This middleware intercepts `wallet_registerOnboarding` RPC messages. It
will register the sender as an oboarding initiator if possible, and
otherwise ignores the message.
* Add network store for testing
An alternative persistent state store has been created for use with e2e
tests. Instead of reading state from disk, it tries to load state from
a local fixture server running on port `12345` and serving state from
the path `/state.json`, and returns a blank state otherwise.
* Add e2e test fixture server
A fixture server has been added for serving background state, which the
background will read upon startup as part of restoring persisted state.
The `signature-request` e2e test has been updated to use a fixture to
bypass the registration step. The fixture used (`imported-account`) was
generated by pausing midway through that test run
The connect route now takes a route parameter: the permissions request
id. This id is set whenever the permissions connect screen is opened,
ensuring that that tab is for that specific request alone.
This makes handling of multiple permissions requests a bit more
intuitive. Previously whenever opening multiple permissions requests,
the first one would be shown on each successive tab, whereas you
would expect each tab to show the request that prompted the tab to
open. Users may now address permissions request in whichever order
they'd like to, rather than being forced to deal with them
chronologically.
Attempts to approve or reject a permissions request that is no longer
pending will now emit a warning instead of throwing an exception.
I _think_ this can happen by clicking 'Submit' on the Permission
Connect screen twice, though I've been unable to reproduce that. I know
that it can be done if using multiple windows though. While it is
possible we have a UI bug somewhere (e.g. maybe we're not preventing
'Submit' from being clicked twice), I don't think it's possible to
eliminate the chance of this happening altogether, so we'd best prepare
for it.
* add PermissionsController
remove provider approval controller
integrate rpc-cap
create PermissionsController
move provider approval functionality to permissions controller
add permissions approval ui, settings page
add permissions activity and history
move some functionality to metamask-inpage-provider
rename siteMetadata -> domainMetadata
add accountsChange notification to inpage provider
move functionality to inpage provider
update inpage provider
Remove 'Connections' settings page (#7369)
add hooks for exposing accounts in settings
rename unused messages in non-English locales
Add external extension id to metadata (#7396)
update inpage provider, rpc-cap
add eth_requestAccounts handling to background
prevent notifying connections if extension is locked
update inpage provider
Fix lint errors
add migration
review fixes
transaction controller review updates
removed unused messages
* Login Per Site UI (#7368)
* LoginPerSite original UI changes to keep
* First commit
* Get necessary connected tab info for redirect and icon display for permissioned sites
* Fix up designs and add missing features
* Some lint fixes
* More lint fixes
* Ensures the tx controller + tx-state-manager orders transactions in the order they are received
* Code cleanup for LoginPerSite-ui
* Update e2e tests to use new connection flow
* Fix display of connect screen and app header after login when connect request present
* Update metamask-responsive-ui.spec for new item in accounts dropdown
* Fix approve container by replacing approvedOrigins with domainMetaData
* Adds test/e2e/permissions.spec.js
* Correctly handle cancellation of a permissions request
* Redirect to home after disconnecting all sites / cancelling all permissions
* Fix display of site icons in menu
* Fix height of permissions page container
* Remove unused locale messages
* Set default values for openExternalTabs and tabIdOrigins in account-menu.container
* More code cleanup for LoginPerSite-ui
* Use extensions api to close tab in permissions-connect
* Remove unnecessary change in domIsReady() in contentscript
* Remove unnecessary private function markers and class methods (for background tab info) in metamask-controller.
* Adds getOriginOfCurrentTab selector
* Adds IconWithFallback component and substitutes for appropriate cases
* Add and utilize font mixins
* Remove unused method in disconnect-all.container.js
* Simplify buttonSizeLarge code in page-container-footer.component.js
* Add and utilize getAccountsWithLabels selector
* Remove console.log in ui/app/store/actions.js
* Change last connected time format to yyyy-M-d
* Fix css associated with IconWithFallback change
* Ensure tracked openNonMetamaskTabsIDs are correctly set to inactive on tab changes
* Code cleanup for LoginPerSite-ui
* Use reusable function for modifying openNonMetamaskTabsIDs in background.js
* Enables automatic switching to connected account when connected domain is open
* Prevent exploit of tabIdOriginMap in background.js
* Remove unneeded code from contentscript.js
* Simplify current tab origin and window opener logic using remotePort listener tabs.queryTabs
* Design and styling fixes for LoginPerSite-ui
* Fix permissionHistory and permission logging for eth_requestAccounts and eth_accounts
* Front end changes to support display of lastConnected time in connected and permissions screens
* Fix lint errors
* Refactor structure of permissionsHistory
* Fix default values and object modifications for domain and permissionsHistory related data
* Fix connecting to new accounts from modal
* Replace retweet.svg with connect-white.svg
* Fix signature-request.spec
* Update metamask-inpage-provider version
* Fix permissions e2e tests
* Remove unneeded delay from test/e2e/signature-request.spec.js
* Add delay before attempting to retrieve network id in dapp in ethereum-on=.spec
* Use requestAccountTabIds strategy for determining tab id that opened a given window
* Improve default values for permissions requests
* Add some message descriptions to app/_locales/en/messages.json
* Code clean up in permission controller
* Stopped deep cloning object in mapObjectValues
* Bump metamask-inpage-provider version
* Add missing description in app/_locales/en/messages.json
* Return promises from queryTabs and switchToTab of extension.js
* Remove unused getAllPermissions function
* Use default props in icon-with-fallback.component.js
* Stop passing to permissions controller
* Delete no longer used clear-approved-origins modal code
* Remove duplicate imports in ui/app/components/app/index.scss
* Use URL instead of regex in getOriginFromUrl()
* Add runtime error checking to platform, promise based extension.tab methods
* Support permission requests from external extensions
* Improve font size and colour of the domain origin on the permission confirmation screen
* Add support for toggling permissions
* Ensure getRenderablePermissionsDomains only returns domains with exposedAccount caveat permissions
* Remove unused code from LoginPerSite-ui branch
* Ensure modal closes on Enter press for new-account-modal.component.js
* Lint fix
* fixup! Login Per Site UI (#7368)
* Some code cleanup for LoginPerSite
* Adds UX for connecting to dapps via the connected sites screen (#7593)
* Adds UX for connecting to dapps via the connected sites screen
* Use openMetaMaskTabIds from background.js to determine if current active tab is MetaMask
* Delete unused permissions controller methods
* Fixes two small bugs in the LoginPerSite ui (#7595)
* Restore `providerRequest` message translations (#7600)
This message was removed, but it was replaced with a very similar
message called `likeToConnect`. The only difference is that the new
message has "MetaMask" in it. Preserving these messages without
"MetaMask" is probably better than deleting them, so these messages
have all been restored and renamed to `likeToConnect`.
* Login per site no sitemetadata fix (#7610)
* Support connected sites for which we have no site metadata.
* Change property containing subtitle info often populated by origin to a more accurate of purpose name
* Lint fix
* Improve disconnection modal messages (#7612)
* Improve disconnectAccountModalDescription and disconnectAllModalDescription messages
* Update disconnectAccountModalDescription app/_locales/en/messages.json
Co-Authored-By: Mark Stacey <markjstacey@gmail.com>
* Improve disconnectAccount modal message clarity
* Adds cancel button to the account selection screen of the permissions request flow (#7613)
* Fix eth_accounts permission language & selectability (#7614)
* fix eth_accounts language & selectability
* fix MetaMask capitalization in all messages
* Close sidebar when opening connected sites (#7611)
The 'Connected Sites' button in the accounts details now closes the
sidebar, if it is open. This was accomplished by pulling the click
handler for that button up to the wallet view component, where another
button already followed a similar pattern of closing the sidebar.
It seemed confusing to me that one handler was in the `AccountsDetails`
container component, and one was handed down from above, so I added
PropTypes to the container component.
I'm not sure that the WalletView component is the best place for this
logic, but I've put it there for now to be consistent with the add
token button.
* Reject permissions request upon tab close (#7618)
Permissions requests are now rejected when the page is closed. This
only applies to the full-screen view, as that is the view permission
requests should be handled in. The case where the user deals with the
request through a different view is handled in #7617
* Handle tab update failure (#7619)
`extension.tabs.update` can sometimes fail if the user interacts with
the tabs directly around the same time. The redirect flow has been
updated to ensure that the permissions tab is still closed in that
case. The user is on their own to find the dapp tab again in that case.
* Login per site tab popup fixes (#7617)
* Handle redirect in response to state update in permissions-connect
* Ensure origin is available to permissions-connect subcomponents during redirect
* Hide app bar whenever on redirect route
* Improvements to handling of redirects in permissions-connect
* Ensure permission request id change handling only happens when page is not null
* Lint fix
* Decouple confirm transaction screen from the selected address (#7622)
* Avoid race condtion that could prevent contextual account switching (#7623)
There was a race condition in the logic responsible for switching the
selected account based upon the active tab. It was asynchronously
querying the active tab, then assuming it had been retrieved later.
The active tab info itself was already in the redux store in another
spot, one that is guaranteed to be set before the UI renders. The
race condition was avoided by deleting the duplicate state, and using
the other active tab state.
* Only redirect back to dapp if current tab is active (#7621)
The "redirect back to dapp" behaviour can be disruptive when the
permissions connect tab is not active. The purpose of the redirect was
to maintain context between the dapp and the permissions request, but
if the user has already moved to another tab, that no longer applies.
* Fix JSX style lint errors
* Remove unused state
* Ensures the tx controller + tx-state-manager orders transactions in the order they are received
* Handle transaction ordering in cases where tx ids are off by more than 1 in tx-state-manager
* Add comment to addUnapprovedTransaction explaining calling _determineTransactionCategory after generateTxMeta
* Sort txes by timestamp of creation instead of id
* Add support for one-click onboarding
MetaMask now allows sites to register as onboarding the user, so that
the user is redirected back to the initiating site after onboarding.
This is accomplished through the use of the `metamask-onboarding`
library and the MetaMask forwarder.
At the end of onboarding, a 'snackbar'-stype component will explain to the
user they are about to be moved back to the originating dapp, and it will
show the origin of that dapp. This is intended to help prevent phishing
attempts, as it highlights that a redirect is taking place to an untrusted
third party.
If the onboarding initiator tab is closed when onboarding is finished,
the user is redirected to the onboarding originator as a fallback.
Closes#6161
* Add onboarding button to contract test dapp
The `contract-test` dapp (run with `yarn dapp`, used in e2e tests) now
uses a `Connect` button instead of connecting automatically. This
button also serves as an onboarding button when a MetaMask installation
is not detected.
* Add new static server for test dapp
The `static-server` library we were using for the `contract-test` dapp
didn't allow referencing files outside the server root. This should
have been possible to work around using symlinks, but there was a bug
that resulted in symlinks crashing the server.
Instead it has been replaced with a simple static file server that
will serve paths starting with `node_modules` from the project root.
This will be useful in testing the onboarding library without vendoring
it.
* Add `@metamask/onboarding` and `@metamask/forwarder`
Both libraries used to test onboarding are now included as dev
dependencies, to help with testing. A few convenience scripts
were added to help with this (`yarn forwarder` and `yarn dapp-forwarder`)
Maker has upgraded its Dai token to "Multi-Collateral Dai" (MCD) and requires
all users interacting with Dai migrate their tokens to the new version. Dai
now exclusively refers to Multi-Collateral Dai and what was previouly called
Dai is now Sai (Single Collateral Dai).
In this description, Sai refers to what was (prior to the 2019-11-18) known as Dai.
Dai is the _new_ token.
This changeset:
1. Only affects users who had non-zero Sai at the old contract address
2. Displays a persistent notification for users with Sai
3. Updates the token symbol for users already tracking the Sai token
4. Bumps our direct and indirect eth-contract-metadata dependencies
The notification copy:
> A message from Maker: The new Multi-Collateral Dai token has been released. Your old tokens are now called Sai. Please upgrade your Sai tokens to the new Dai.
The copy is from the Maker team.
The 'reverseResolveAddress' method is intended to return undefined if
unable to reverse resolve the given address. Instead it was throwing an
error, which surfaced in the UI console. This error is now caught.
* Omit MetaMask `extensionId` from site metadata
The site metadata was updated in #7218 to include the extension id of
the extension connecting to MetaMask. This was done to allow external
extensions to connect with MetaMask, so that we could show the id on
the provider approval screen.
Unbeknownst to me at the time, the extension id was being set for all
connections to MetaMask from dapps. The id was set to MetaMask's id,
because the connections are made through MetaMask's contentscript.
This has been updated to only set the id when accepting a connection
from a different extension.
* Fix `siteMetadata` property names
In #7218 a few things were added to the site metadata, so the provider
approval controller was middleware was updated to accept the site
metadata as an object rather than accepting each property as a separate
parameter. Unfortunately we failed to notice that the site name and
icon were named differently in the site metadata than they were in the
provider approval controller, so the names of those properties were
unintentionally changed in the controller state.
The provider approval controller has been updated to restore the
original property names of `siteTitle` and `siteIcon`. An unused prop
that was added to the provider approval page in #7218 has also been
removed.
* ENS Reverse Resolution support
* Save punycode for ENS domains with Unicode characters
* Update SenderToRecipient recipientEns tooltip
* Use cached results when reverse-resolving ENS names
* Display ENS names in tx activity log
* Add estimated time to pending transactions
* add sytles for pending transactions component
* add media queries styling for pending transactions component
* fix lint errors, remove extra spaces
* refactor code to call `fetchBasicGasAndTimeEstimates` method once
* refactor code to call `getgetRenderableTimeEstimate` method once
* fix, correct export to use `transaction-time-remaining-component`
* fix indentation issues after running `yarn lint`
* newBigSigDig in gas-price-chart.utils supports strings
* Code cleanup
* Ensure fetchBasicGasAndTimeEstimates is only called from tx-list if there are pending-txs
* Move gas time estimate utilities into utility file
* Move getTxParams to transaction selector file
* Add feature flag for display of remaining transaction time in tx history list
* Fix circular dependency by removing unused import of transactionSelector in selectors.js
* Use correct feature flag property name transactionTime
* Ensure that tx list component correctly responds to turning tx time feature on
* Prevent precision errors in newBigSigDig
* Code clean up for pending transaction times
* Update transaction-time-remaining feature to count down seconds, countdown seconds and show '< 30'
* Code clean up for transaction-time-remaining feature
* tests - create tests for pending middlewares
* transactions - add r,s,v values to the txMeta to match the JSON rpc response
* network - add new middleware for eth_getTransactionByHash that the checks pending tx's for a response value
* transactions/pending - use getTransactionReceipt for checking if tx is in a block
* meta - file rename
If the extension ID is set, an alternate title and subtitle are used
for the Connect Request screen. The title is always `External
Extension`, and the subtitle is `Extension ID: [id]` instead of the
origin (which would just be `[extension-scheme]://[id]` anyway).
The hostname for the site is used as a fallback in case it has no
title.
The artificial hostname set for internal connections has been renamed
from 'MetaMask' to 'metamask' because URL objects automatically
normalize hostnames to be all lower-case, and it was more convenient to
use a URL object so that the parameter would be the same type as used
for an untrusted connection.