From cfc0a868a43089b88fcd9711f89b2fa5c04fb1c3 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Mon, 10 May 2021 14:14:21 -0500 Subject: [PATCH] rough in switchEthereumChain (#10905) --- .../rpc-method-middleware/handlers/index.js | 2 + .../handlers/switch-ethereum-chain.js | 92 +++++++++++++++++++ shared/constants/app.js | 2 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js diff --git a/app/scripts/lib/rpc-method-middleware/handlers/index.js b/app/scripts/lib/rpc-method-middleware/handlers/index.js index 541256a1c..fb0c1ef8f 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/index.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/index.js @@ -1,10 +1,12 @@ import addEthereumChain from './add-ethereum-chain'; +import switchEthereumChain from './switch-ethereum-chain'; import getProviderState from './get-provider-state'; import logWeb3ShimUsage from './log-web3-shim-usage'; import watchAsset from './watch-asset'; const handlers = [ addEthereumChain, + switchEthereumChain, getProviderState, logWeb3ShimUsage, watchAsset, diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js new file mode 100644 index 000000000..b52deb232 --- /dev/null +++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js @@ -0,0 +1,92 @@ +import { ethErrors } from 'eth-rpc-errors'; +import { omit } from 'lodash'; +import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; +import { + isPrefixedFormattedHexString, + isSafeChainId, +} from '../../../../../shared/modules/network.utils'; + +const switchEthereumChain = { + methodNames: [MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN], + implementation: switchEthereumChainHandler, +}; +export default switchEthereumChain; + +async function switchEthereumChainHandler( + req, + res, + _next, + end, + { getCurrentChainId, findCustomRpcBy, updateRpcTarget, requestUserApproval }, +) { + if (!req.params?.[0] || typeof req.params[0] !== 'object') { + return end( + ethErrors.rpc.invalidParams({ + message: `Expected single, object parameter. Received:\n${JSON.stringify( + req.params, + )}`, + }), + ); + } + + const { origin } = req; + + const { chainId } = req.params[0]; + + const otherKeys = Object.keys(omit(req.params[0], ['chainId'])); + + if (otherKeys.length > 0) { + return end( + ethErrors.rpc.invalidParams({ + message: `Received unexpected keys on object parameter. Unsupported keys:\n${otherKeys}`, + }), + ); + } + + const _chainId = typeof chainId === 'string' && chainId.toLowerCase(); + + if (!isPrefixedFormattedHexString(_chainId)) { + return end( + ethErrors.rpc.invalidParams({ + message: `Expected 0x-prefixed, unpadded, non-zero hexadecimal string 'chainId'. Received:\n${chainId}`, + }), + ); + } + + if (!isSafeChainId(parseInt(_chainId, 16))) { + return end( + ethErrors.rpc.invalidParams({ + message: `Invalid chain ID "${_chainId}": numerical value greater than max safe value. Received:\n${chainId}`, + }), + ); + } + + const existingNetwork = findCustomRpcBy({ chainId: _chainId }); + + if (existingNetwork !== null) { + const currentChainId = getCurrentChainId(); + if (currentChainId === _chainId) { + res.result = null; + return end(); + } + try { + await updateRpcTarget( + await requestUserApproval({ + origin, + type: MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN, + requestData: { + rpcUrl: existingNetwork.rpcUrl, + chainId: existingNetwork.chainId, + nickname: existingNetwork.nickname, + ticker: existingNetwork.ticker, + }, + }), + ); + res.result = null; + } catch (error) { + return end(error); + } + return end(); + } + return end(ethErrors.provider.userRejectedRequest()); +} diff --git a/shared/constants/app.js b/shared/constants/app.js index 93c843846..7e1b66572 100644 --- a/shared/constants/app.js +++ b/shared/constants/app.js @@ -28,5 +28,5 @@ export const MESSAGE_TYPE = { WATCH_ASSET: 'wallet_watchAsset', WATCH_ASSET_LEGACY: 'metamask_watchAsset', ADD_ETHEREUM_CHAIN: 'wallet_addEthereumChain', - SWITCH_ETHEREUM_CHAIN: 'metamask_switchEthereumChain', + SWITCH_ETHEREUM_CHAIN: 'wallet_switchEthereumChain', };