diff --git a/.yarn/patches/lavamoat-core-npm-14.2.0-c453f4f755.patch b/.yarn/patches/lavamoat-core-npm-14.4.1-c4e8bbb016.patch similarity index 100% rename from .yarn/patches/lavamoat-core-npm-14.2.0-c453f4f755.patch rename to .yarn/patches/lavamoat-core-npm-14.4.1-c4e8bbb016.patch diff --git a/app/scripts/controllers/mmi-controller.js b/app/scripts/controllers/mmi-controller.js index 1b259d9f6dd9..d6e980e1be95 100644 --- a/app/scripts/controllers/mmi-controller.js +++ b/app/scripts/controllers/mmi-controller.js @@ -345,7 +345,7 @@ export default class MMIController extends EventEmitter { // FIXME: status maps are not a thing anymore this.custodyController.storeCustodyStatusMap( - custodian.name, + custodian.envName, keyring.getStatusMap(), ); diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index 77052b05e483..be997cdf1e98 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -58,18 +58,21 @@ export default function setupEnsIpfsResolver({ const ipfsGateway = getIpfsGateway(); const useAddressBarEnsResolution = getUseAddressBarEnsResolution(); - if (!useAddressBarEnsResolution || ipfsGateway === '') { - return; - } + const ensSiteUrl = `https://app.ens.domains/name/${name}`; - browser.tabs.update(tabId, { url: `loading.html` }); + // We cannot show this if useAddressBarEnsResolution is off... + if (useAddressBarEnsResolution && ipfsGateway) { + browser.tabs.update(tabId, { url: 'loading.html' }); + } - let url = `https://app.ens.domains/name/${name}`; + let url = ensSiteUrl; // If we're testing ENS domain resolution support, // we assume the ENS domains URL if (process.env.IN_TEST) { - browser.tabs.update(tabId, { url }); + if (useAddressBarEnsResolution || ipfsGateway) { + browser.tabs.update(tabId, { url }); + } return; } @@ -79,6 +82,12 @@ export default function setupEnsIpfsResolver({ name, }); if (type === 'ipfs-ns' || type === 'ipns-ns') { + // If the ENS is via IPFS and that setting is disabled, + // Do not resolve the ENS + if (ipfsGateway === '') { + url = null; + return; + } const resolvedUrl = `https://${hash}.${type.slice( 0, 4, @@ -121,7 +130,15 @@ export default function setupEnsIpfsResolver({ } catch (err) { console.warn(err); } finally { - browser.tabs.update(tabId, { url }); + // Only forward to destination URL if a URL exists and + // useAddressBarEnsResolution is properly + if ( + url && + (useAddressBarEnsResolution || + (!useAddressBarEnsResolution && url !== ensSiteUrl)) + ) { + browser.tabs.update(tabId, { url }); + } } } } diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 86e66c5feecd..0d117f87e475 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -115,6 +115,9 @@ export const SENTRY_BACKGROUND_STATE = { keyrings: false, keyringTypes: false, }, + LoggingController: { + logs: false, + }, MetaMetricsController: { eventsBeforeMetricsOptIn: false, fragments: false, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 76cf19085ea4..c6e13786de92 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -57,12 +57,12 @@ import { SelectedNetworkController, createSelectedNetworkMiddleware, } from '@metamask/selected-network-controller'; +import { LoggingController } from '@metamask/logging-controller'; ///: BEGIN:ONLY_INCLUDE_IN(snaps) import { encrypt, decrypt } from '@metamask/browser-passworder'; import { RateLimitController } from '@metamask/rate-limit-controller'; import { NotificationController } from '@metamask/notification-controller'; - import { CronjobController, JsonSnapsRegistry, @@ -347,6 +347,13 @@ export default class MetamaskController extends EventEmitter { ], }); + this.loggingController = new LoggingController({ + messenger: this.controllerMessenger.getRestricted({ + name: 'LoggingController', + }), + state: initState.LoggingController, + }); + ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) this.mmiConfigurationController = new MmiConfigurationController({ initState: initState.MmiConfigurationController, @@ -369,23 +376,22 @@ export default class MetamaskController extends EventEmitter { if (initState.NetworkController) { initialNetworkControllerState = initState.NetworkController; } else if (process.env.IN_TEST) { + const networkConfig = { + chainId: CHAIN_IDS.LOCALHOST, + nickname: 'Localhost 8545', + rpcPrefs: {}, + rpcUrl: 'http://localhost:8545', + ticker: 'ETH', + id: 'networkConfigurationId', + }; initialNetworkControllerState = { providerConfig: { - chainId: CHAIN_IDS.LOCALHOST, - nickname: 'Localhost 8545', - rpcPrefs: {}, - rpcUrl: 'http://localhost:8545', - ticker: 'ETH', + ...networkConfig, type: 'rpc', }, networkConfigurations: { networkConfigurationId: { - chainId: CHAIN_IDS.LOCALHOST, - nickname: 'Localhost 8545', - rpcPrefs: {}, - rpcUrl: 'http://localhost:8545', - ticker: 'ETH', - networkConfigurationId: 'networkConfigurationId', + ...networkConfig, }, }, }; @@ -1103,6 +1109,8 @@ export default class MetamaskController extends EventEmitter { 'SnapController:snapInstalled', 'SnapController:snapUpdated', 'SnapController:snapRemoved', + 'SnapController:snapEnabled', + 'SnapController:snapDisabled', ], allowedActions: [ `${this.permissionController.name}:getPermissions`, @@ -1720,6 +1728,7 @@ export default class MetamaskController extends EventEmitter { NftController: this.nftController, PhishingController: this.phishingController, SelectedNetworkController: this.selectedNetworkController, + LoggingController: this.loggingController, ///: BEGIN:ONLY_INCLUDE_IN(snaps) SnapController: this.snapController, CronjobController: this.cronjobController, @@ -1768,6 +1777,7 @@ export default class MetamaskController extends EventEmitter { SmartTransactionsController: this.smartTransactionsController, NftController: this.nftController, SelectedNetworkController: this.selectedNetworkController, + LoggingController: this.loggingController, ///: BEGIN:ONLY_INCLUDE_IN(snaps) SnapController: this.snapController, CronjobController: this.cronjobController, @@ -2716,6 +2726,7 @@ export default class MetamaskController extends EventEmitter { ), dismissNotifications: this.dismissNotifications.bind(this), markNotificationsAsRead: this.markNotificationsAsRead.bind(this), + updateCaveat: this.updateCaveat.bind(this), ///: END:ONLY_INCLUDE_IN ///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps) updateSnapRegistry: this.preferencesController.updateSnapRegistry.bind( diff --git a/builds.yml b/builds.yml index 70ec3ffe77d2..f1d5e8144d7a 100644 --- a/builds.yml +++ b/builds.yml @@ -58,7 +58,7 @@ buildTypes: - SEGMENT_FLASK_WRITE_KEY - ALLOW_LOCAL_SNAPS: true - REQUIRE_SNAPS_ALLOWLIST: false - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.consensys.io/0.38.3-flask.1/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.consensys.io/0.39.0-flask.1/index.html - SUPPORT_LINK: https://metamask-flask.zendesk.com/hc - SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new - INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID @@ -77,7 +77,7 @@ buildTypes: - SEGMENT_FLASK_WRITE_KEY - ALLOW_LOCAL_SNAPS: true - REQUIRE_SNAPS_ALLOWLIST: false - - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.consensys.io/0.38.3-flask.1/index.html + - IFRAME_EXECUTION_ENVIRONMENT_URL: https://execution.consensys.io/0.39.0-flask.1/index.html - SUPPORT_LINK: https://metamask-flask.zendesk.com/hc - SUPPORT_REQUEST_LINK: https://metamask-flask.zendesk.com/hc/en-us/requests/new - INFURA_ENV_KEY_REF: INFURA_FLASK_PROJECT_ID diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 892374ab6499..a6eca099ed40 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -922,25 +922,39 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, "@metamask/eth-json-rpc-middleware>clone": true, "@metamask/eth-json-rpc-middleware>pify": true, "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true } }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true, + "bn.js": true, + "browserify>buffer": true, + "eth-sig-util>ethereumjs-util>ethjs-util": true, + "eth-sig-util>tweetnacl": true, + "eth-sig-util>tweetnacl-util": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": { "globals": { "TextDecoder": true, - "TextEncoder": true + "crypto": true }, "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, "@metamask/eth-json-rpc-middleware>clone": { @@ -1614,6 +1628,12 @@ "ethereumjs-util>rlp": true } }, + "@metamask/logging-controller": { + "packages": { + "@metamask/base-controller": true, + "uuid": true + } + }, "@metamask/logo": { "globals": { "addEventListener": true, diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index b26b2be02723..bede398269d4 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -993,25 +993,39 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, "@metamask/eth-json-rpc-middleware>clone": true, "@metamask/eth-json-rpc-middleware>pify": true, "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true } }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true, + "bn.js": true, + "browserify>buffer": true, + "eth-sig-util>ethereumjs-util>ethjs-util": true, + "eth-sig-util>tweetnacl": true, + "eth-sig-util>tweetnacl-util": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": { "globals": { "TextDecoder": true, - "TextEncoder": true + "crypto": true }, "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, "@metamask/eth-json-rpc-middleware>clone": { @@ -1765,6 +1779,12 @@ "ethereumjs-util>rlp": true } }, + "@metamask/logging-controller": { + "packages": { + "@metamask/base-controller": true, + "uuid": true + } + }, "@metamask/logo": { "globals": { "addEventListener": true, @@ -2053,20 +2073,7 @@ }, "@metamask/rpc-methods-flask>@metamask/snaps-ui": { "packages": { - "@metamask/rpc-methods-flask>@metamask/snaps-ui>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/rpc-methods-flask>@metamask/snaps-ui>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, + "@metamask/rpc-methods-flask>@metamask/utils": true, "superstruct": true } }, @@ -2211,6 +2218,7 @@ "@metamask/providers>@metamask/object-multiplex": true, "@metamask/snaps-controllers-flask>@metamask/post-message-stream": true, "@metamask/snaps-controllers-flask>@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-registry": true, "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, "@metamask/snaps-controllers-flask>@metamask/utils": true, "@metamask/snaps-controllers-flask>concat-stream": true, @@ -2219,11 +2227,10 @@ "@metamask/snaps-controllers>gunzip-maybe": true, "@metamask/snaps-controllers>readable-web-to-node-stream": true, "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, "eth-rpc-errors": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, - "pump": true + "stream-browserify": true } }, "@metamask/snaps-controllers-flask>@metamask/post-message-stream": { @@ -2268,20 +2275,14 @@ }, "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui": { "packages": { - "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui>@metamask/utils": true, + "@metamask/snaps-controllers-flask>@metamask/utils": true, "superstruct": true } }, - "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/snaps-controllers-flask>@metamask/snaps-registry": { "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, + "@metamask/key-tree>@noble/secp256k1": true, + "@metamask/snaps-controllers-flask>@metamask/utils": true, "superstruct": true } }, @@ -2553,26 +2554,6 @@ "@metamask/snaps-utils-flask>is-svg>fast-xml-parser>strnum": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { - "packages": { - "@metamask/key-tree>@noble/secp256k1": true, - "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/snaps-utils>cron-parser": { "packages": { "browserify>browser-resolve": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 87616d548685..873139ec3333 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -993,25 +993,39 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, "@metamask/eth-json-rpc-middleware>clone": true, "@metamask/eth-json-rpc-middleware>pify": true, "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true } }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true, + "bn.js": true, + "browserify>buffer": true, + "eth-sig-util>ethereumjs-util>ethjs-util": true, + "eth-sig-util>tweetnacl": true, + "eth-sig-util>tweetnacl-util": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": { "globals": { "TextDecoder": true, - "TextEncoder": true + "crypto": true }, "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, "@metamask/eth-json-rpc-middleware>clone": { @@ -1765,6 +1779,12 @@ "ethereumjs-util>rlp": true } }, + "@metamask/logging-controller": { + "packages": { + "@metamask/base-controller": true, + "uuid": true + } + }, "@metamask/logo": { "globals": { "addEventListener": true, @@ -2069,20 +2089,7 @@ }, "@metamask/rpc-methods-flask>@metamask/snaps-ui": { "packages": { - "@metamask/rpc-methods-flask>@metamask/snaps-ui>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/rpc-methods-flask>@metamask/snaps-ui>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, + "@metamask/rpc-methods-flask>@metamask/utils": true, "superstruct": true } }, @@ -2227,6 +2234,7 @@ "@metamask/providers>@metamask/object-multiplex": true, "@metamask/snaps-controllers-flask>@metamask/post-message-stream": true, "@metamask/snaps-controllers-flask>@metamask/rpc-methods": true, + "@metamask/snaps-controllers-flask>@metamask/snaps-registry": true, "@metamask/snaps-controllers-flask>@metamask/snaps-utils": true, "@metamask/snaps-controllers-flask>@metamask/utils": true, "@metamask/snaps-controllers-flask>concat-stream": true, @@ -2235,11 +2243,10 @@ "@metamask/snaps-controllers>gunzip-maybe": true, "@metamask/snaps-controllers>readable-web-to-node-stream": true, "@metamask/snaps-controllers>tar-stream": true, - "@metamask/snaps-utils>@metamask/snaps-registry": true, "eth-rpc-errors": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, - "pump": true + "stream-browserify": true } }, "@metamask/snaps-controllers-flask>@metamask/post-message-stream": { @@ -2284,20 +2291,14 @@ }, "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui": { "packages": { - "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui>@metamask/utils": true, + "@metamask/snaps-controllers-flask>@metamask/utils": true, "superstruct": true } }, - "@metamask/snaps-controllers-flask>@metamask/rpc-methods>@metamask/snaps-ui>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, + "@metamask/snaps-controllers-flask>@metamask/snaps-registry": { "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, + "@metamask/key-tree>@noble/secp256k1": true, + "@metamask/snaps-controllers-flask>@metamask/utils": true, "superstruct": true } }, @@ -2569,26 +2570,6 @@ "@metamask/snaps-utils-flask>is-svg>fast-xml-parser>strnum": true } }, - "@metamask/snaps-utils>@metamask/snaps-registry": { - "packages": { - "@metamask/key-tree>@noble/secp256k1": true, - "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/snaps-utils>@metamask/snaps-registry>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/snaps-utils>cron-parser": { "packages": { "browserify>browser-resolve": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 76635c854c9f..b338c1e8f697 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -922,25 +922,39 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, "@metamask/eth-json-rpc-middleware>clone": true, "@metamask/eth-json-rpc-middleware>pify": true, "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true } }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true, + "bn.js": true, + "browserify>buffer": true, + "eth-sig-util>ethereumjs-util>ethjs-util": true, + "eth-sig-util>tweetnacl": true, + "eth-sig-util>tweetnacl-util": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": { "globals": { "TextDecoder": true, - "TextEncoder": true + "crypto": true }, "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, "@metamask/eth-json-rpc-middleware>clone": { @@ -1614,6 +1628,12 @@ "ethereumjs-util>rlp": true } }, + "@metamask/logging-controller": { + "packages": { + "@metamask/base-controller": true, + "uuid": true + } + }, "@metamask/logo": { "globals": { "addEventListener": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 26fbe0e3e7eb..99beea63a6c4 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1062,25 +1062,39 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-middleware>@metamask/utils": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": true, "@metamask/eth-json-rpc-middleware>clone": true, "@metamask/eth-json-rpc-middleware>pify": true, "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, - "@metamask/eth-snap-keyring>@metamask/eth-sig-util": true, + "@metamask/utils": true, "eth-rpc-errors": true, "json-rpc-engine": true } }, - "@metamask/eth-json-rpc-middleware>@metamask/utils": { + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util": { + "packages": { + "@ethereumjs/tx>@ethereumjs/util": true, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": true, + "bn.js": true, + "browserify>buffer": true, + "eth-sig-util>ethereumjs-util>ethjs-util": true, + "eth-sig-util>tweetnacl": true, + "eth-sig-util>tweetnacl-util": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography": { "globals": { "TextDecoder": true, - "TextEncoder": true + "crypto": true }, "packages": { - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true + } + }, + "@metamask/eth-json-rpc-middleware>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { + "globals": { + "TextEncoder": true, + "crypto": true } }, "@metamask/eth-json-rpc-middleware>clone": { @@ -1754,6 +1768,12 @@ "ethereumjs-util>rlp": true } }, + "@metamask/logging-controller": { + "packages": { + "@metamask/base-controller": true, + "uuid": true + } + }, "@metamask/logo": { "globals": { "addEventListener": true, diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index ed581042a3e6..baf15bfb8aa7 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -1049,6 +1049,7 @@ "globals": { "__dirname": true, "__filename.slice": true, + "console.error": true, "console.warn": true, "process.cwd": true, "setTimeout": true @@ -1059,6 +1060,7 @@ "@lavamoat/lavapack>readable-stream": true, "@lavamoat/lavapack>umd": true, "browserify>JSONStream": true, + "eslint>espree": true, "lavamoat>json-stable-stringify": true, "lavamoat>lavamoat-core": true, "through2": true @@ -6306,14 +6308,10 @@ "lavamoat>@lavamoat/aa": { "builtin": { "fs.readFileSync": true, - "fs.statSync": true, "path.dirname": true, "path.join": true, "path.relative": true }, - "globals": { - "performantResolve": true - }, "packages": { "brfs>resolve": true } diff --git a/package.json b/package.json index 6e4c8291fdbd..b3902602b561 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "request@^2.83.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", "request@^2.88.2": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", "request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", - "lavamoat-core@^14.2.0": "patch:lavamoat-core@npm%3A14.2.0#./.yarn/patches/lavamoat-core-npm-14.2.0-c453f4f755.patch", + "lavamoat-core@npm:^14.4.1": "patch:lavamoat-core@npm%3A14.4.1#~/.yarn/patches/lavamoat-core-npm-14.4.1-c4e8bbb016.patch", "@metamask/keyring-controller@^7.4.0": "patch:@metamask/keyring-controller@npm%3A7.4.0#~/.yarn/patches/@metamask-keyring-controller-npm-7.4.0-5dd5df31c7.patch", "@metamask/signature-controller@^5.3.0": "patch:@metamask/signature-controller@npm%3A5.3.0#./.yarn/patches/@metamask-signature-controller-npm-5.3.0-225628460b.patch", "semver@7.3.7": "^7.5.4", @@ -226,7 +226,7 @@ "@lavamoat/snow": "^1.5.0", "@material-ui/core": "^4.11.0", "@metamask-institutional/custody-controller": "^0.2.12", - "@metamask-institutional/custody-keyring": "^1.0.1", + "@metamask-institutional/custody-keyring": "^1.0.2", "@metamask-institutional/extension": "^0.3.5", "@metamask-institutional/institutional-features": "^1.2.4", "@metamask-institutional/portfolio-dashboard": "^1.4.0", @@ -254,11 +254,12 @@ "@metamask/jazzicon": "^2.0.0", "@metamask/key-tree": "^9.0.0", "@metamask/keyring-controller": "^7.4.0", + "@metamask/logging-controller": "^1.0.1", "@metamask/logo": "^3.1.1", "@metamask/message-manager": "^7.3.0", "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/name-controller": "^1.0.0", - "@metamask/network-controller": "^12.1.1", + "@metamask/network-controller": "^12.2.0", "@metamask/notification-controller": "^3.0.0", "@metamask/obs-store": "^8.1.0", "@metamask/permission-controller": "^4.0.0", @@ -268,7 +269,7 @@ "@metamask/providers": "^11.1.0", "@metamask/rate-limit-controller": "^3.0.0", "@metamask/rpc-methods": "^1.0.2", - "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.38.2-flask.1", + "@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.38.3-flask.1", "@metamask/safe-event-emitter": "^2.0.0", "@metamask/scure-bip39": "^2.0.3", "@metamask/selected-network-controller": "^1.0.0", @@ -276,11 +277,11 @@ "@metamask/slip44": "^3.0.0", "@metamask/smart-transactions-controller": "^4.0.0", "@metamask/snaps-controllers": "^1.0.2", - "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.38.3-flask.1", + "@metamask/snaps-controllers-flask": "npm:@metamask/snaps-controllers@0.39.0-flask.1", "@metamask/snaps-ui": "^1.0.2", - "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.37.4-flask.1", + "@metamask/snaps-ui-flask": "npm:@metamask/snaps-ui@0.37.5-flask.1", "@metamask/snaps-utils": "^1.0.2", - "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.38.3-flask.1", + "@metamask/snaps-utils-flask": "npm:@metamask/snaps-utils@0.38.4-flask.1", "@metamask/subject-metadata-controller": "^2.0.0", "@metamask/utils": "^5.0.0", "@ngraveio/bc-ur": "^1.1.6", @@ -364,7 +365,7 @@ "redux-thunk": "^2.3.0", "remove-trailing-slash": "^0.1.1", "reselect": "^3.0.1", - "ses": "^0.18.7", + "ses": "^0.18.8", "single-call-balance-checker-abi": "^1.0.0", "unicode-confusables": "^0.1.1", "uuid": "^8.3.2", @@ -384,7 +385,7 @@ "@babel/register": "^7.5.5", "@ethersproject/bignumber": "^5.7.0", "@lavamoat/allow-scripts": "^2.3.1", - "@lavamoat/lavapack": "^5.2.0", + "@lavamoat/lavapack": "^5.2.4", "@metamask/auto-changelog": "^2.1.0", "@metamask/eslint-config": "^9.0.0", "@metamask/eslint-config-jest": "^9.0.0", @@ -508,9 +509,9 @@ "jsdom": "^16.7.0", "junit-report-merger": "^4.0.0", "koa": "^2.7.0", - "lavamoat": "^7.1.0", - "lavamoat-browserify": "^15.7.0", - "lavamoat-viz": "^6.0.9", + "lavamoat": "^7.1.2", + "lavamoat-browserify": "^15.7.4", + "lavamoat-viz": "^6.0.11", "lockfile-lint": "^4.10.6", "loose-envify": "^1.4.0", "madge": "^6.1.0", diff --git a/test/e2e/tests/ipfs-ens-resolution.spec.js b/test/e2e/tests/ipfs-ens-resolution.spec.js index 73b2f70d66b8..ba7a1357d283 100644 --- a/test/e2e/tests/ipfs-ens-resolution.spec.js +++ b/test/e2e/tests/ipfs-ens-resolution.spec.js @@ -31,7 +31,7 @@ describe('Settings', function () { await driver.quit(); }); - it('Does not lookup IPFS data for ENS Domain when switched off', async function () { + it('Does not fetch ENS data for ENS Domain when ENS and IPFS switched off', async function () { let server; await withFixtures( @@ -54,7 +54,10 @@ describe('Settings', function () { await driver.clickElement({ text: 'Settings', tag: 'div' }); await driver.clickElement({ text: 'Security & privacy', tag: 'div' }); - // turns off IPFS domain resolution + // turns off IPFS setting + await driver.clickElement('[data-testid="ipfsToggle"] .toggle-button'); + + // turns off ENS domain resolution await driver.clickElement( '[data-testid="ipfs-gateway-resolution-container"] .toggle-button', ); diff --git a/test/e2e/tests/ipfs-toggle.spec.js b/test/e2e/tests/ipfs-toggle.spec.js index 0fc6392e57fd..9a7a537dbaf5 100644 --- a/test/e2e/tests/ipfs-toggle.spec.js +++ b/test/e2e/tests/ipfs-toggle.spec.js @@ -59,7 +59,9 @@ describe('Settings', function () { }); // should render image now - const nftImage = await driver.findElement('[data-testid="nft-image"]'); + const nftImage = await driver.findVisibleElement( + '[data-testid="nft-image"]', + ); assert.equal(await nftImage.isDisplayed(), true); }, ); diff --git a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json index c53998494f8b..6325ba3e6376 100644 --- a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json @@ -71,6 +71,9 @@ "keyringTypes": "object", "keyrings": "object" }, + "LoggingController": { + "logs": "object" + }, "MetaMetricsController": { "participateInMetaMetrics": true, "metaMetricsId": "fake-metrics-id", diff --git a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json index f598c876d217..31aa72b082ee 100644 --- a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -193,7 +193,8 @@ "ensResolutionsByAddress": "object", "pendingApprovals": "object", "pendingApprovalCount": "number", - "approvalFlows": "object" + "approvalFlows": "object", + "logs": "object" }, "send": "object", "swaps": "object", diff --git a/ui/components/app/asset-list/asset-list.js b/ui/components/app/asset-list/asset-list.js index 0cb8e636ced3..efe57253ec6e 100644 --- a/ui/components/app/asset-list/asset-list.js +++ b/ui/components/app/asset-list/asset-list.js @@ -69,6 +69,13 @@ const AssetList = ({ onClickAsset }) => { return ( <> {process.env.MULTICHAIN ? : null} + {detectedTokens.length > 0 && + !isTokenDetectionInactiveOnNonMainnetSupportedNetwork && ( + setShowDetectedTokens(true)} + margin={4} + /> + )} onClickAsset(nativeCurrency)} title={nativeCurrency} @@ -92,13 +99,6 @@ const AssetList = ({ onClickAsset }) => { }); }} /> - {detectedTokens.length > 0 && - !isTokenDetectionInactiveOnNonMainnetSupportedNetwork ? ( - setShowDetectedTokens(true)} - margin={4} - /> - ) : null} 0 ? 0 : 4}> diff --git a/ui/components/app/nft-default-image/nft-default-image.js b/ui/components/app/nft-default-image/nft-default-image.js index 9d70df63fe2c..c85b0cabab27 100644 --- a/ui/components/app/nft-default-image/nft-default-image.js +++ b/ui/components/app/nft-default-image/nft-default-image.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { Display, AlignItems, @@ -11,12 +11,10 @@ import { import { useI18nContext } from '../../../hooks/useI18nContext'; import { ButtonLink, Box } from '../../component-library'; import { showIpfsModal } from '../../../store/actions'; -import { getIpfsGateway } from '../../../selectors'; export default function NftDefaultImage({ className, clickable }) { const t = useI18nContext(); const dispatch = useDispatch(); - const isIpfsEnabled = useSelector(getIpfsGateway); return ( - {!isIpfsEnabled && ( + {clickable && ( ( +const Template = (args) => (
); -DefaultStory.storyName = 'Default'; +export const DefaultStory = Template.bind({}); + +export const WithShowButton = Template.bind({}); +WithShowButton.args = { + clickable: true, +}; diff --git a/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap b/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap index 947973a70e0d..8b1a3aff08da 100644 --- a/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap +++ b/ui/components/app/nft-details/__snapshots__/nft-details.test.js.snap @@ -50,13 +50,13 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = ` data-testid="nft-item" >
MUNK #1 1
{ if ( @@ -90,6 +92,21 @@ export default function NftsItems({ const history = useHistory(); const renderCollectionImage = (collectionImage, collectionName) => { + if (collectionImage?.startsWith('ipfs') && !ipfsGateway) { + return ( +
+ {collectionName?.[0]?.toUpperCase() ?? null} +
+ ); + } + if (!openSeaEnabled && !collectionImage?.startsWith('ipfs')) { + return ( +
+ {collectionName?.[0]?.toUpperCase() ?? null} +
+ ); + } + if (collectionImage) { return ( {nfts.map((nft, i) => { const { image, address, tokenId, name, imageOriginal } = nft; - const nftImage = getAssetImageURL(imageOriginal, ipfsGateway); + const nftImage = getAssetImageURL( + imageOriginal ?? image, + ipfsGateway, + ); const nftImageAlt = getNftImageAlt(nft); - const nftImageURL = imageOriginal?.includes('ipfs') + const isImageHosted = image.startsWith('https:'); + const nftImageURL = imageOriginal?.startsWith('ipfs') ? nftImage : image; @@ -188,7 +209,7 @@ export default function NftsItems({ { className="import-tokens-modal__autodetect" onClick={() => { history.push( - `${SECURITY_ROUTE}#advanced-settings-autodetect-tokens`, + `${SECURITY_ROUTE}#auto-detect-tokens`, ); onClose(); }} @@ -505,11 +505,12 @@ export const ImportTokensModal = ({ onClose }) => { + onClick={() => { history.push( - `${SECURITY_ROUTE}#advanced-settings-autodetect-tokens`, - ) - } + `${SECURITY_ROUTE}#auto-detect-tokens`, + ); + onClose(); + }} > {t('inYourSettings')} , diff --git a/ui/components/multichain/nft-item/nft-item.js b/ui/components/multichain/nft-item/nft-item.js index a0fc767ef3f5..cbf6251bf2ec 100644 --- a/ui/components/multichain/nft-item/nft-item.js +++ b/ui/components/multichain/nft-item/nft-item.js @@ -34,6 +34,25 @@ export const NftItem = ({ const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor); const isIpfsEnabled = useSelector(getIpfsGateway); const isIpfsURL = nftImageURL?.includes('ipfs:'); + const renderNftBasedonSrc = src ? ( + + ) : ( + + ); + return ( {isIpfsEnabled ? ( - + <>{renderNftBasedonSrc} ) : ( <> {isIpfsURL ? ( @@ -85,15 +96,7 @@ export const NftItem = ({ clickable={clickable} /> ) : ( - + <>{renderNftBasedonSrc} )} )} diff --git a/ui/components/ui/pulse-loader/pulse-loader.js b/ui/components/ui/pulse-loader/pulse-loader.js index d4d542d71c16..227a07e49475 100644 --- a/ui/components/ui/pulse-loader/pulse-loader.js +++ b/ui/components/ui/pulse-loader/pulse-loader.js @@ -2,7 +2,7 @@ import React from 'react'; export default function PulseLoader() { return ( -
+
diff --git a/ui/helpers/utils/institutional/find-by-custodian-name.ts b/ui/helpers/utils/institutional/find-by-custodian-name.ts index 52a05b3b7b27..bdd58d0cbcd2 100644 --- a/ui/helpers/utils/institutional/find-by-custodian-name.ts +++ b/ui/helpers/utils/institutional/find-by-custodian-name.ts @@ -24,7 +24,7 @@ export function findCustodianByDisplayName( } for (const custodian of custodians) { - const custodianName = custodian.name.toLowerCase(); + const custodianName = custodian.envName.toLowerCase(); if (formatedDisplayName.includes(custodianName)) { return custodian; diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js index 678bbf4540f3..882d32dc4dd9 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js @@ -228,7 +228,7 @@ describe('Confirm Transaction Base', () => { mockedStore.metamask.mmiConfiguration = { custodians: [ { - name: 'saturn-dev', + envName: 'saturn-dev', displayName: 'Saturn Custody', isNoteToTraderSupported: true, }, diff --git a/ui/pages/institutional/confirm-connect-custodian-modal/confirm-connect-custodian-modal.js b/ui/pages/institutional/confirm-connect-custodian-modal/confirm-connect-custodian-modal.js index b3269b2ad607..d08e07d7fe1a 100644 --- a/ui/pages/institutional/confirm-connect-custodian-modal/confirm-connect-custodian-modal.js +++ b/ui/pages/institutional/confirm-connect-custodian-modal/confirm-connect-custodian-modal.js @@ -10,7 +10,7 @@ import { import { I18nContext } from '../../../contexts/i18n'; import { Button, - BUTTON_VARIANT, + ButtonVariant, Box, Text, Modal, @@ -78,7 +78,7 @@ const ConfirmConnectCustodianModal = ({
-
-`; - -exports[`CustodyPage renders CustodyPage 2`] = ` -
- -
-
- -

- Back -

-
-

- Custodial Accounts -

-
+

- Please choose the custodian you want to connect in order to add or refresh a token. -

-
+
+ +
+
+
+

-

    -
    -
    - Saturn Custody -

    - Saturn Custody -

    -
    - -
    -
-
+ Saturn Custody C +

- +
-
+ `; - -exports[`CustodyPage renders CustodyPage 3`] = `
`; diff --git a/ui/pages/institutional/custody/custody.js b/ui/pages/institutional/custody/custody.js index 5d078b03b5b5..094d0a5f6016 100644 --- a/ui/pages/institutional/custody/custody.js +++ b/ui/pages/institutional/custody/custody.js @@ -7,7 +7,6 @@ import React, { } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; -import { v4 as uuidv4 } from 'uuid'; import { isEqual } from 'lodash'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { mmiActionsFactory } from '../../../store/institutional/institution-background'; @@ -18,8 +17,8 @@ import { Label, IconName, IconSize, - BUTTON_SIZES, - BUTTON_VARIANT, + ButtonSize, + ButtonVariant, Box, Text, } from '../../../components/component-library'; @@ -55,6 +54,8 @@ import PulseLoader from '../../../components/ui/pulse-loader/pulse-loader'; import ConfirmConnectCustodianModal from '../confirm-connect-custodian-modal'; import { findCustodianByDisplayName } from '../../../helpers/utils/institutional/find-by-custodian-name'; +const GK8_DISPLAY_NAME = 'gk8'; + const CustodyPage = () => { const t = useI18nContext(); const history = useHistory(); @@ -88,26 +89,18 @@ const CustodyPage = () => { const [accounts, setAccounts] = useState(); const address = useSelector(getSelectedAddress); const connectRequest = connectRequests ? connectRequests[0] : undefined; + const isCheckBoxSelected = + accounts && Object.keys(selectedAccounts).length === accounts.length; const custodianButtons = useMemo(() => { const custodianItems = []; - const sortedCustodians = [...custodians].sort(function (a, b) { - const nameA = a.name.toLowerCase(); - const nameB = b.name.toLowerCase(); - - if (nameA < nameB) { - return -1; - } - if (nameA > nameB) { - return 1; - } - return 0; - }); + const sortedCustodians = [...custodians].sort((a, b) => + a.envName.toLowerCase().localeCompare(b.envName.toLowerCase()), + ); function shouldShowInProduction(custodian) { return ( - custodian && 'production' in custodian && !custodian.production && process.env.METAMASK_ENVIRONMENT === 'production' @@ -115,19 +108,59 @@ const CustodyPage = () => { } function isHidden(custodian) { - return custodian && 'hidden' in custodian && custodian.hidden; + return 'hidden' in custodian && custodian.hidden; } function isNotSelectedCustodian(custodian) { return ( - custodian && - 'name' in custodian && + 'envName' in custodian && connectRequest && Object.keys(connectRequest).length && - custodian.name !== selectedCustodianName + custodian.envName !== selectedCustodianName ); } + async function handleButtonClick(custodian) { + try { + const custodianByDisplayName = findCustodianByDisplayName( + custodian.displayName, + custodians, + ); + + const jwtListValue = await dispatch( + mmiActions.getCustodianJWTList(custodian.envName), + ); + + setSelectedCustodianName(custodian.envName); + setSelectedCustodianDisplayName(custodian.displayName); + setSelectedCustodianImage(custodian.iconUrl); + setApiUrl(custodian.apiUrl); + setCurrentJwt(jwtListValue[0] || ''); + setJwtList(jwtListValue); + + // open confirm Connect Custodian modal except for gk8 + if ( + custodianByDisplayName?.displayName?.toLocaleLowerCase() === + GK8_DISPLAY_NAME + ) { + setSelectedCustodianType(custodian.type); + } else { + setMatchedCustodian(custodianByDisplayName); + setIsConfirmConnectCustodianModalVisible(true); + } + + trackEvent({ + category: MetaMetricsEventCategory.MMI, + event: MetaMetricsEventName.CustodianSelected, + properties: { + custodian: custodian.envName, + }, + }); + } catch (error) { + console.error('Error:', error); + } + } + sortedCustodians.forEach((custodian) => { if ( shouldShowInProduction(custodian) || @@ -139,7 +172,7 @@ const CustodyPage = () => { custodianItems.push( { @@ -222,25 +218,27 @@ const CustodyPage = () => { const handleConnectError = useCallback( (e) => { - let errorMessage; - const detailedError = e.message.split(':'); - - if (detailedError.length > 1 && !isNaN(parseInt(detailedError[0], 10))) { - if (parseInt(detailedError[0], 10) === 401) { - // Authentication Error - errorMessage = - 'Authentication error. Please ensure you have entered the correct token'; + const getErrorMessage = (error) => { + const detailedError = error.message.split(':'); + const errorCode = parseInt(detailedError[0], 10); + + if (detailedError.length > 1 && !isNaN(errorCode)) { + switch (errorCode) { + case 401: + return 'Authentication error. Please ensure you have entered the correct token'; + default: + return null; + } } - } - if (/Network Error/u.test(e.message)) { - errorMessage = - 'Network error. Please ensure you have entered the correct API URL'; - } + if (/Network Error/u.test(error.message)) { + return 'Network error. Please ensure you have entered the correct API URL'; + } - if (!errorMessage) { - errorMessage = e.message; - } + return error.message; + }; + + const errorMessage = getErrorMessage(e); setConnectError( `Something went wrong connecting your custodian account. Error details: ${errorMessage}`, @@ -382,7 +380,12 @@ const CustodyPage = () => { return ( {connectError && ( - + {connectError} )} @@ -391,8 +394,10 @@ const CustodyPage = () => { {selectError} )} + {!accounts && !selectedCustodianType && ( { marginTop={4} > { ) : (