From 81fb9c0feb709ab8f8c19fcacbeb6330b9e9d6b4 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Mon, 29 Jul 2024 17:06:47 +0200 Subject: [PATCH] feat: always use snaps to resolve domains; include preinstalled ENS resolver snap fixes https://github.com/MetaMask/MetaMask-planning/issues/2403 Signed-off-by: Mircea Nistor --- .../metamask-controller.actions.test.js | 2 +- app/scripts/snaps/preinstalled-snaps.ts | 2 + package.json | 2 +- ui/ducks/domains.js | 69 ++++------------ .../add-recipient/domain-input.container.js | 2 +- yarn.lock | 80 ++++++++++++++++--- 6 files changed, 90 insertions(+), 67 deletions(-) diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index 33fa8c9baa8a..68029a72c1b5 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -70,7 +70,7 @@ describe('MetaMaskController', function () { const noop = () => undefined; beforeAll(async function () { - await ganacheServer.start(); + await ganacheServer.start({ port: 32545 }); }); beforeEach(function () { diff --git a/app/scripts/snaps/preinstalled-snaps.ts b/app/scripts/snaps/preinstalled-snaps.ts index ee3bb06c6242..4c0dd93ac39d 100644 --- a/app/scripts/snaps/preinstalled-snaps.ts +++ b/app/scripts/snaps/preinstalled-snaps.ts @@ -2,12 +2,14 @@ import type { PreinstalledSnap } from '@metamask/snaps-controllers'; import MessageSigningSnap from '@metamask/message-signing-snap/dist/preinstalled-snap.json'; ///: BEGIN:ONLY_INCLUDE_IF(build-flask) import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json'; +import EnsResolverSnap from '@metamask/ens-resolver-snap/dist/preinstalled-snap.json'; ///: END:ONLY_INCLUDE_IF const PREINSTALLED_SNAPS: readonly PreinstalledSnap[] = Object.freeze([ MessageSigningSnap as PreinstalledSnap, ///: BEGIN:ONLY_INCLUDE_IF(build-flask) BitcoinWalletSnap as PreinstalledSnap, + EnsResolverSnap as PreinstalledSnap, ///: END:ONLY_INCLUDE_IF ]); diff --git a/package.json b/package.json index 71e7217982cd..12d404d07228 100644 --- a/package.json +++ b/package.json @@ -299,6 +299,7 @@ "@metamask/controller-utils": "^10.0.0", "@metamask/design-tokens": "^4.0.0", "@metamask/ens-controller": "^12.0.0", + "@metamask/ens-resolver-snap": "^0.1.0", "@metamask/eth-json-rpc-filters": "^7.0.0", "@metamask/eth-json-rpc-middleware": "^12.1.1", "@metamask/eth-ledger-bridge-keyring": "patch:@metamask/eth-ledger-bridge-keyring@npm%3A2.0.1#~/.yarn/patches/@metamask-eth-ledger-bridge-keyring-npm-2.0.1-7a5d815b2d.patch", @@ -378,7 +379,6 @@ "eth-lattice-keyring": "^0.12.4", "eth-method-registry": "^4.0.0", "eth-rpc-errors": "^4.0.2", - "ethereum-ens-network-map": "^1.0.2", "ethereumjs-util": "^7.0.10", "extension-port-stream": "^3.0.0", "fast-json-patch": "^3.1.1", diff --git a/ui/ducks/domains.js b/ui/ducks/domains.js index d8635a8d23ed..33b661015afb 100644 --- a/ui/ducks/domains.js +++ b/ui/ducks/domains.js @@ -1,9 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; import log from 'loglevel'; -import ensNetworkMap from 'ethereum-ens-network-map'; import { isConfusing } from 'unicode-confusables'; import { isHexString } from 'ethereumjs-util'; -import { Web3Provider } from '@ethersproject/providers'; import { getChainIdsCaveat, @@ -17,10 +15,7 @@ import { getSnapMetadata, } from '../selectors'; import { handleSnapRequest } from '../store/actions'; -import { - CHAIN_IDS, - CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP, -} from '../../shared/constants/network'; +import { CHAIN_IDS } from '../../shared/constants/network'; import { CONFUSING_ENS_ERROR, ENS_ILLEGAL_CHARACTER, @@ -57,8 +52,6 @@ export const domainInitialState = initialState; const name = 'DNS'; -let web3Provider = null; - const slice = createSlice({ name, initialState, @@ -145,7 +138,6 @@ const slice = createSlice({ builder.addCase(CHAIN_CHANGED, (state, action) => { if (action.payload !== state.chainId) { state.stage = 'UNINITIALIZED'; - web3Provider = null; } }); }, @@ -167,19 +159,6 @@ export function initializeDomainSlice() { return (dispatch, getState) => { const state = getState(); const chainId = getCurrentChainId(state); - const networkName = CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP[chainId]; - const chainIdInt = parseInt(chainId, 16); - const ensAddress = ensNetworkMap[chainIdInt.toString()]; - const networkIsSupported = Boolean(ensAddress); - if (networkIsSupported) { - web3Provider = new Web3Provider(global.ethereumProvider, { - chainId: chainIdInt, - name: networkName, - ensAddress, - }); - } else { - web3Provider = null; - } dispatch(enableDomainLookup(chainId)); }; } @@ -282,37 +261,19 @@ export function lookupDomainName(domainName) { } else { await dispatch(lookupStart(trimmedDomainName)); log.info(`Resolvers attempting to resolve name: ${trimmedDomainName}`); - let resolutions = []; - let fetchedResolutions; + const resolutions = []; let hasSnapResolution = false; - let error; - let address; - try { - address = await web3Provider?.resolveName(trimmedDomainName); - } catch (err) { - error = err; - } const chainId = getCurrentChainId(state); const chainIdInt = parseInt(chainId, 16); - if (address) { - resolutions = [ - { - resolvedAddress: address, - protocol: 'Ethereum Name Service', - addressBookEntryName: getAddressBookEntry(state, address)?.name, - domainName: trimmedDomainName, - }, - ]; - } else { - fetchedResolutions = await fetchResolutions({ - domain: trimmedDomainName, - chainId: `eip155:${chainIdInt}`, - state, - }); - hasSnapResolution = fetchedResolutions.length > 0; - if (hasSnapResolution) { - resolutions = fetchedResolutions; - } + + const fetchedResolutions = await fetchResolutions({ + domain: trimmedDomainName, + chainId: `eip155:${chainIdInt}`, + state, + }); + hasSnapResolution = fetchedResolutions.length > 0; + if (hasSnapResolution) { + resolutions.push(...fetchedResolutions); } // Due to the asynchronous nature of looking up domains, we could reach this point @@ -325,13 +286,11 @@ export function lookupDomainName(domainName) { await dispatch( lookupEnd({ resolutions, - error, + // TODO: get error(s) from snap(s) + error: undefined, chainId, network: chainIdInt, - domainType: - hasSnapResolution || (!hasSnapResolution && !address) - ? 'Other' - : ENS, + domainType: 'Other', domainName: trimmedDomainName, }), ); diff --git a/ui/pages/confirmations/send/send-content/add-recipient/domain-input.container.js b/ui/pages/confirmations/send/send-content/add-recipient/domain-input.container.js index baacc6e3d63b..cbf7c884a8c7 100644 --- a/ui/pages/confirmations/send/send-content/add-recipient/domain-input.container.js +++ b/ui/pages/confirmations/send/send-content/add-recipient/domain-input.container.js @@ -17,7 +17,7 @@ function mapDispatchToProps(dispatch) { return { lookupDomainName: debounce( (domainName) => dispatch(lookupDomainName(domainName)), - 150, + 450, ), initializeDomainSlice: () => dispatch(initializeDomainSlice()), resetDomainResolution: debounce( diff --git a/yarn.lock b/yarn.lock index 00e3564771cf..33e9e4a8cab6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -50,6 +50,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:1.10.1": + version: 1.10.1 + resolution: "@adraffy/ens-normalize@npm:1.10.1" + checksum: 10/4cb938c4abb88a346d50cb0ea44243ab3574330c81d4f5aaaf9dfee584b96189d0faa404de0fcbef5a1b73909ea4ebc3e63d84bd23f9949e5c8d4085207a5091 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.2.1 resolution: "@ampproject/remapping@npm:2.2.1" @@ -5049,6 +5056,16 @@ __metadata: languageName: node linkType: hard +"@metamask/ens-resolver-snap@npm:^0.1.0": + version: 0.1.0 + resolution: "@metamask/ens-resolver-snap@npm:0.1.0" + dependencies: + "@metamask/snaps-sdk": "npm:^6.0.0" + ethers: "npm:^6.13.1" + checksum: 10/d5840837dd7d687b509ad816df4d7782641532e837cca0ad44a34278a7f083de7784595777cb42f901c0727abad9f3546b205e7d1b520b2a7f0209d140464ef8 + languageName: node + linkType: hard + "@metamask/eslint-config-jest@npm:^9.0.0": version: 9.0.0 resolution: "@metamask/eslint-config-jest@npm:9.0.0" @@ -6639,6 +6656,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.2.0": + version: 1.2.0 + resolution: "@noble/curves@npm:1.2.0" + dependencies: + "@noble/hashes": "npm:1.3.2" + checksum: 10/94e02e9571a9fd42a3263362451849d2f54405cb3ce9fa7c45bc6b9b36dcd7d1d20e2e1e14cfded24937a13d82f1e60eefc4d7a14982ce0bc219a9fc0f51d1f9 + languageName: node + linkType: hard + "@noble/curves@npm:1.3.0, @noble/curves@npm:~1.3.0": version: 1.3.0 resolution: "@noble/curves@npm:1.3.0" @@ -6664,6 +6690,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.3.2": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: 10/685f59d2d44d88e738114b71011d343a9f7dce9dfb0a121f1489132f9247baa60bc985e5ec6f3213d114fbd1e1168e7294644e46cbd0ce2eba37994f28eeb51b + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.3, @noble/hashes@npm:~1.3.2": version: 1.3.3 resolution: "@noble/hashes@npm:1.3.3" @@ -10433,6 +10466,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:18.15.13": + version: 18.15.13 + resolution: "@types/node@npm:18.15.13" + checksum: 10/b9bbe923573797ef7c5fd2641a6793489e25d9369c32aeadcaa5c7c175c85b42eb12d6fe173f6781ab6f42eaa1ebd9576a419eeaa2a1ec810094adb8adaa9a54 + languageName: node + linkType: hard + "@types/node@npm:^12.12.54": version: 12.20.55 resolution: "@types/node@npm:12.20.55" @@ -11841,6 +11881,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:4.0.0-beta.5": + version: 4.0.0-beta.5 + resolution: "aes-js@npm:4.0.0-beta.5" + checksum: 10/8f745da2e8fb38e91297a8ec13c2febe3219f8383303cd4ed4660ca67190242ccfd5fdc2f0d1642fd1ea934818fb871cd4cc28d3f28e812e3dc6c3d0f1f97c24 + languageName: node + linkType: hard + "aes-js@npm:^3.1.1, aes-js@npm:^3.1.2": version: 3.1.2 resolution: "aes-js@npm:3.1.2" @@ -18017,13 +18064,6 @@ __metadata: languageName: node linkType: hard -"ethereum-ens-network-map@npm:^1.0.2": - version: 1.0.2 - resolution: "ethereum-ens-network-map@npm:1.0.2" - checksum: 10/34fa160f2b1ee8ec31bfe3dcec7b4becd4a6110acde171f43b9c28e0adc126dbded9dc6747d03088b6c99f04582887e6a23cb24b718321712c85208965835ea1 - languageName: node - linkType: hard - "ethereumjs-util@npm:7.1.5, ethereumjs-util@npm:^7.1.2": version: 7.1.5 resolution: "ethereumjs-util@npm:7.1.5" @@ -18104,6 +18144,21 @@ __metadata: languageName: node linkType: hard +"ethers@npm:^6.13.1": + version: 6.13.2 + resolution: "ethers@npm:6.13.2" + dependencies: + "@adraffy/ens-normalize": "npm:1.10.1" + "@noble/curves": "npm:1.2.0" + "@noble/hashes": "npm:1.3.2" + "@types/node": "npm:18.15.13" + aes-js: "npm:4.0.0-beta.5" + tslib: "npm:2.4.0" + ws: "npm:8.17.1" + checksum: 10/e611c2e2c5340982dfd1f004895f55abda11748a7edec9e6315226dec42d58aa61b827dd389ec904db5f9a244c475ae795e528da579251fdf62e914bde12809e + languageName: node + linkType: hard + "ethjs-abi@npm:0.2.1, ethjs-abi@npm:^0.2.0": version: 0.2.1 resolution: "ethjs-abi@npm:0.2.1" @@ -25254,6 +25309,7 @@ __metadata: "@metamask/controller-utils": "npm:^10.0.0" "@metamask/design-tokens": "npm:^4.0.0" "@metamask/ens-controller": "npm:^12.0.0" + "@metamask/ens-resolver-snap": "npm:^0.1.0" "@metamask/eslint-config": "npm:^9.0.0" "@metamask/eslint-config-jest": "npm:^9.0.0" "@metamask/eslint-config-mocha": "npm:^9.0.0" @@ -25442,7 +25498,6 @@ __metadata: eth-lattice-keyring: "npm:^0.12.4" eth-method-registry: "npm:^4.0.0" eth-rpc-errors: "npm:^4.0.2" - ethereum-ens-network-map: "npm:^1.0.2" ethereumjs-util: "npm:^7.0.10" extension-port-stream: "npm:^3.0.0" fake-indexeddb: "npm:^4.0.1" @@ -33998,6 +34053,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.4.0": + version: 2.4.0 + resolution: "tslib@npm:2.4.0" + checksum: 10/d8379e68b36caf082c1905ec25d17df8261e1d68ddc1abfd6c91158a064f6e4402039ae7c02cf4c81d12e3a2a2c7cd8ea2f57b233eb80136a2e3e7279daf2911 + languageName: node + linkType: hard + "tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -35995,7 +36057,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:>=8.14.2, ws@npm:^8.0.0, ws@npm:^8.11.0, ws@npm:^8.16.0, ws@npm:^8.17.1, ws@npm:^8.2.3, ws@npm:^8.5.0, ws@npm:^8.8.0": +"ws@npm:*, ws@npm:8.17.1, ws@npm:>=8.14.2, ws@npm:^8.0.0, ws@npm:^8.11.0, ws@npm:^8.16.0, ws@npm:^8.17.1, ws@npm:^8.2.3, ws@npm:^8.5.0, ws@npm:^8.8.0": version: 8.17.1 resolution: "ws@npm:8.17.1" peerDependencies: