From 85fe12d3f5a3a6d640485da1a340208819162752 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 22 Oct 2024 14:30:23 -0700 Subject: [PATCH 01/50] bump asset controllers to 39 --- ...s-controllers-npm-39.0.0-57b3d695bb.patch} | 0 ...ntroller-utils-npm-11.3.0-7971498570.patch | 226 ++++++++++++++++++ app/scripts/metamask-controller.js | 7 +- package.json | 11 +- ui/hooks/useCurrencyRatePolling.ts | 5 +- ui/hooks/useGasFeeEstimates.js | 5 +- ui/hooks/usePolling.ts | 30 +-- ui/store/actions.ts | 4 +- yarn.lock | 55 +++-- 9 files changed, 289 insertions(+), 54 deletions(-) rename .yarn/patches/{@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch => @metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch} (100%) create mode 100644 .yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch diff --git a/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch b/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch similarity index 100% rename from .yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch rename to .yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch diff --git a/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch b/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch new file mode 100644 index 000000000000..78dcfa1e8ead --- /dev/null +++ b/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch @@ -0,0 +1,226 @@ +diff --git a/dist/index.cjs b/dist/index.cjs +index bd9e58b1c07c1fecd36c934efd75312b1effa3cf..aa3a692fc23fbb7c50e38b17b6129545c604ae89 100644 +--- a/dist/index.cjs ++++ b/dist/index.cjs +@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); +-exports.weiHexToGweiDec = exports.toHex = exports.toChecksumHexAddress = exports.timeoutFetch = exports.successfulFetch = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.query = exports.normalizeEnsName = exports.isValidHexAddress = exports.isValidJson = exports.isSmartContractCode = exports.isSafeDynamicKey = exports.isSafeChainId = exports.isPlainObject = exports.isNonEmptyArray = exports.hexToText = exports.hexToBN = exports.handleFetch = exports.gweiDecToWEIBN = exports.getBuyURL = exports.fromHex = exports.fractionBN = exports.fetchWithErrorHandling = exports.convertHexToDecimal = exports.BNToHex = void 0; ++exports.isEqualCaseInsensitive = exports.weiHexToGweiDec = exports.toHex = exports.toChecksumHexAddress = exports.timeoutFetch = exports.successfulFetch = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.query = exports.normalizeEnsName = exports.isValidHexAddress = exports.isValidJson = exports.isSmartContractCode = exports.isSafeDynamicKey = exports.isSafeChainId = exports.isPlainObject = exports.isNonEmptyArray = exports.hexToText = exports.hexToBN = exports.handleFetch = exports.gweiDecToWEIBN = exports.getBuyURL = exports.fromHex = exports.fractionBN = exports.fetchWithErrorHandling = exports.convertHexToDecimal = exports.BNToHex = void 0; + __exportStar(require("./constants.cjs"), exports); + var util_1 = require("./util.cjs"); + Object.defineProperty(exports, "BNToHex", { enumerable: true, get: function () { return util_1.BNToHex; } }); +@@ -43,6 +43,7 @@ Object.defineProperty(exports, "timeoutFetch", { enumerable: true, get: function + Object.defineProperty(exports, "toChecksumHexAddress", { enumerable: true, get: function () { return util_1.toChecksumHexAddress; } }); + Object.defineProperty(exports, "toHex", { enumerable: true, get: function () { return util_1.toHex; } }); + Object.defineProperty(exports, "weiHexToGweiDec", { enumerable: true, get: function () { return util_1.weiHexToGweiDec; } }); ++Object.defineProperty(exports, "isEqualCaseInsensitive", { enumerable: true, get: function () { return util_1.isEqualCaseInsensitive; } }); + __exportStar(require("./types.cjs"), exports); + __exportStar(require("./siwe.cjs"), exports); + //# sourceMappingURL=index.cjs.map +\ No newline at end of file +diff --git a/dist/index.cjs.map b/dist/index.cjs.map +index 9218cac8330ea42f34c55dd162474cde48b653a8..27e5950afdbe30485f68e07b26d4046c2150ac9b 100644 +--- a/dist/index.cjs.map ++++ b/dist/index.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,mCA2BgB;AA1Bd,+FAAA,OAAO,OAAA;AACP,2GAAA,mBAAmB,OAAA;AACnB,8GAAA,sBAAsB,OAAA;AACtB,kGAAA,UAAU,OAAA;AACV,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,sGAAA,cAAc,OAAA;AACd,mGAAA,WAAW,OAAA;AACX,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,qGAAA,aAAa,OAAA;AACb,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,mGAAA,WAAW,OAAA;AACX,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,6FAAA,KAAK,OAAA;AACL,qGAAA,aAAa,OAAA;AACb,gHAAA,wBAAwB,OAAA;AACxB,uGAAA,eAAe,OAAA;AACf,oGAAA,YAAY,OAAA;AACZ,4GAAA,oBAAoB,OAAA;AACpB,6FAAA,KAAK,OAAA;AACL,uGAAA,eAAe,OAAA;AAEjB,8CAAwB;AACxB,6CAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} +\ No newline at end of file ++{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,mCA4BgB;AA3Bd,+FAAA,OAAO,OAAA;AACP,2GAAA,mBAAmB,OAAA;AACnB,8GAAA,sBAAsB,OAAA;AACtB,kGAAA,UAAU,OAAA;AACV,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,sGAAA,cAAc,OAAA;AACd,mGAAA,WAAW,OAAA;AACX,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,qGAAA,aAAa,OAAA;AACb,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,mGAAA,WAAW,OAAA;AACX,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,6FAAA,KAAK,OAAA;AACL,qGAAA,aAAa,OAAA;AACb,gHAAA,wBAAwB,OAAA;AACxB,uGAAA,eAAe,OAAA;AACf,oGAAA,YAAY,OAAA;AACZ,4GAAA,oBAAoB,OAAA;AACpB,6FAAA,KAAK,OAAA;AACL,uGAAA,eAAe,OAAA;AACf,8GAAA,sBAAsB,OAAA;AAExB,8CAAwB;AACxB,6CAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n isEqualCaseInsensitive,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} +\ No newline at end of file +diff --git a/dist/index.d.cts b/dist/index.d.cts +index 4ebb06e58295d0c7a2de2c362808d8168b4d735f..942079412efbe12306a8c3957e29fb08b86f09aa 100644 +--- a/dist/index.d.cts ++++ b/dist/index.d.cts +@@ -1,6 +1,6 @@ + export * from "./constants.cjs"; + export type { NonEmptyArray } from "./util.cjs"; +-export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, } from "./util.cjs"; ++export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive, } from "./util.cjs"; + export * from "./types.cjs"; + export * from "./siwe.cjs"; + //# sourceMappingURL=index.d.cts.map +\ No newline at end of file +diff --git a/dist/index.d.cts.map b/dist/index.d.cts.map +index ecad0fd2b254b4b126848b441424bf3779ed166d..f8f143c8bf591347106fbd0109a11a57cae81835 100644 +--- a/dist/index.d.cts.map ++++ b/dist/index.d.cts.map +@@ -1 +1 @@ +-{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,GAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} +\ No newline at end of file ++{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,GACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} +\ No newline at end of file +diff --git a/dist/index.d.mts b/dist/index.d.mts +index 969a616c848ca98a666a8adfdcb3e5414e4dbb59..7be5be08a6fe001bcf5ab7691fab805159c60218 100644 +--- a/dist/index.d.mts ++++ b/dist/index.d.mts +@@ -1,6 +1,6 @@ + export * from "./constants.mjs"; + export type { NonEmptyArray } from "./util.mjs"; +-export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, } from "./util.mjs"; ++export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive, } from "./util.mjs"; + export * from "./types.mjs"; + export * from "./siwe.mjs"; + //# sourceMappingURL=index.d.mts.map +\ No newline at end of file +diff --git a/dist/index.d.mts.map b/dist/index.d.mts.map +index d804348b55cf9029429d3d7826607de38590acb0..448e9ed5d48d572266602973303bbc7f6a26b84d 100644 +--- a/dist/index.d.mts.map ++++ b/dist/index.d.mts.map +@@ -1 +1 @@ +-{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,GAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} +\ No newline at end of file ++{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,GACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} +\ No newline at end of file +diff --git a/dist/index.mjs b/dist/index.mjs +index 4f050229eac5f177f3b3b9891e074bd6355019f3..7ca1bba9c2483959391ffee83c427cfa813266fc 100644 +--- a/dist/index.mjs ++++ b/dist/index.mjs +@@ -1,5 +1,5 @@ + export * from "./constants.mjs"; +-export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec } from "./util.mjs"; ++export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive } from "./util.mjs"; + export * from "./types.mjs"; + export * from "./siwe.mjs"; + //# sourceMappingURL=index.mjs.map +\ No newline at end of file +diff --git a/dist/index.mjs.map b/dist/index.mjs.map +index f277eca2f54a81efe5b8c0e2158fa5d6588064df..4fcb2a9ad7fadd8ee352976e7957ae4a23c588b5 100644 +--- a/dist/index.mjs.map ++++ b/dist/index.mjs.map +@@ -1 +1 @@ +-{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAE5B,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} +\ No newline at end of file ++{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAE5B,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,EACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n isEqualCaseInsensitive,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} +\ No newline at end of file +diff --git a/dist/util.cjs b/dist/util.cjs +index 9033310b086b5c6795ba96b1f7b2a83d6e5eb1cf..e2cbb26c2b805a2be1d3380281044f8d699f1873 100644 +--- a/dist/util.cjs ++++ b/dist/util.cjs +@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(exports, "__esModule", { value: true }); +-exports.isValidJson = exports.isNonEmptyArray = exports.isPlainObject = exports.convertHexToDecimal = exports.query = exports.normalizeEnsName = exports.timeoutFetch = exports.fetchWithErrorHandling = exports.handleFetch = exports.successfulFetch = exports.isSmartContractCode = exports.isValidHexAddress = exports.toChecksumHexAddress = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.toHex = exports.fromHex = exports.hexToText = exports.hexToBN = exports.getBuyURL = exports.weiHexToGweiDec = exports.gweiDecToWEIBN = exports.fractionBN = exports.BNToHex = exports.isSafeChainId = exports.isSafeDynamicKey = exports.PROTOTYPE_POLLUTION_BLOCKLIST = void 0; ++exports.isEqualCaseInsensitive = exports.isValidJson = exports.isNonEmptyArray = exports.isPlainObject = exports.convertHexToDecimal = exports.query = exports.normalizeEnsName = exports.timeoutFetch = exports.fetchWithErrorHandling = exports.handleFetch = exports.successfulFetch = exports.isSmartContractCode = exports.isValidHexAddress = exports.toChecksumHexAddress = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.toHex = exports.fromHex = exports.hexToText = exports.hexToBN = exports.getBuyURL = exports.weiHexToGweiDec = exports.gweiDecToWEIBN = exports.fractionBN = exports.BNToHex = exports.isSafeChainId = exports.isSafeDynamicKey = exports.PROTOTYPE_POLLUTION_BLOCKLIST = void 0; + const util_1 = require("@ethereumjs/util"); + const ethjs_unit_1 = require("@metamask/ethjs-unit"); + const utils_1 = require("@metamask/utils"); +@@ -509,4 +509,18 @@ function logOrRethrowError(error, codesToCatch = []) { + throw error; + } + } ++/** ++ * Checks if two strings are equal, ignoring case. ++ * ++ * @param value1 - The first string to compare. ++ * @param value2 - The second string to compare. ++ * @returns `true` if the strings are equal, ignoring case; otherwise, `false`. ++ */ ++function isEqualCaseInsensitive(value1, value2) { ++ if (typeof value1 !== 'string' || typeof value2 !== 'string') { ++ return false; ++ } ++ return value1.toLowerCase() === value2.toLowerCase(); ++} ++exports.isEqualCaseInsensitive = isEqualCaseInsensitive; + //# sourceMappingURL=util.cjs.map +\ No newline at end of file +diff --git a/dist/util.cjs.map b/dist/util.cjs.map +index a01b63e991d4b961483a57dbc19440671ab031c8..39f4c32d605f042606c81e46fcc8ab212d493bf4 100644 +--- a/dist/util.cjs.map ++++ b/dist/util.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"util.cjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"util.cjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n\n/**\n * Checks if two strings are equal, ignoring case.\n *\n * @param value1 - The first string to compare.\n * @param value2 - The second string to compare.\n * @returns `true` if the strings are equal, ignoring case; otherwise, `false`.\n */\nexport function isEqualCaseInsensitive(\n value1: string,\n value2: string,\n): boolean {\n if (typeof value1 !== 'string' || typeof value2 !== 'string') {\n return false;\n }\n return value1.toLowerCase() === value2.toLowerCase();\n}\n"]} +\ No newline at end of file +diff --git a/dist/util.d.cts b/dist/util.d.cts +index fba6d2b047ba9a9a53c683fdf1ae41f3528581b1..0d3418f8c99fda0da1d047d9ba89a7e878935530 100644 +--- a/dist/util.d.cts ++++ b/dist/util.d.cts +@@ -239,5 +239,13 @@ export declare function isNonEmptyArray(value: T[]): value is NonEmptyArray(value: T[]): value is NonEmptyArray key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"util.mjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;;;;;;AAEA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,6BAA6B;AAEtD,OAAO,EACL,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACT,wBAAwB;AACzB,OAAO,GAAE,cAAc;;AACvB,OAAO,YAAW,yBAAyB;;AAC3C,OAAO,UAAS,wBAAwB;;AAExC,OAAO,EAAE,iBAAiB,EAAE,wBAAoB;AAEhD,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,WAAW;IACX,aAAa;IACb,WAAW;CACH,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC,CACxE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAY;IACxC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;QACzB,OAAO,KAAK,CAAC;KACd;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CACpC,OAAO,EACP,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CACrC,CAAC;IACF,OAAO,CACL,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC;QACpC,cAAc,GAAG,CAAC;QAClB,cAAc,IAAI,iBAAiB,CACpC,CAAC;AACJ,CAAC;AACD;;;;;GAKG;AACH,gFAAgF;AAChF,gEAAgE;AAChE,MAAM,UAAU,OAAO,CAAC,OAAW;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,QAAY,EACZ,SAA0B,EAC1B,WAA4B;IAE5B,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,CAAkB;IAC/C,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACnB,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;KAClB;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAClC,IAAI,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEjC,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACjC;IAED,IAAI,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE;QAC3B,OAAO,KAAK,CAAC,GAAG,SAAS,IAAI,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;KACrD;IAED,MAAM,mBAAmB,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAEpD,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,SAAS,IAAI,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;IAEvD,IAAI,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE;QACrC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KAC1B;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,WAAW,GAAG,GAAG,EACjB,OAAgB,EAChB,MAAM,GAAG,CAAC;IAEV,QAAQ,WAAW,EAAE;QACnB,KAAK,GAAG;YACN,gFAAgF;YAChF,4EAA4E;YAC5E,OAAO,8EAA8E,MAAM,YAAY,OAAO,sBAAsB,CAAC;QACvI,KAAK,GAAG;YACN,OAAO,iCAAiC,CAAC;QAC3C,KAAK,UAAU;YACb,OAAO,4BAA4B,CAAC;QACtC;YACE,OAAO,SAAS,CAAC;KACpB;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,QAAgB;IACtC,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI;QACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KAC9B;IAAC,OAAO,CAAC,EAAE;QACV,0BAA0B;QAC1B,OAAO,GAAG,CAAC;KACZ;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAkB;IACxC,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QAClB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,KAAoC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE;QACzD,OAAO,KAAK,CAAC;KACd;IACD,MAAM,SAAS,GACb,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ;QACzC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpB,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,KAAK,SAAS,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAgC,EAChC,QAAQ,GAAG,KAAK;IAEhB,IAAI;QACF,OAAO,MAAM,SAAS,EAAE,CAAC;KAC1B;IAAC,OAAO,KAAK,EAAE;QACd,0BAA0B;QAC1B,IAAI,QAAQ,EAAE;YACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACtB;QACD,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,SAAgC,EAChC,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,GAAG;IAEb,IAAI;QACF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACxB,SAAS,EAAE;YACX,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,CAAC,aAAa,CAAC,CAAC;YACxB,CAAC,EAAE,OAAO,CAAC,CACZ;SACF,CAAC,CAAC;KACJ;IAAC,OAAO,KAAK,EAAE;QACd,0BAA0B;QAC1B,IAAI,QAAQ,EAAE;YACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACtB;QACD,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAyBD,8EAA8E;AAC9E,+CAA+C;AAC/C,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,sEAAsE;QACtE,6DAA6D;QAC7D,OAAO,OAAO,CAAC;KAChB;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAEnC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE;QAC7B,yEAAyE;QACzE,2EAA2E;QAC3E,0EAA0E;QAC1E,wCAAwC;QACxC,OAAO,WAAW,CAAC;KACpB;IAED,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,eAAuB,EACvB,EAAE,gBAAgB,GAAG,IAAI,EAAE,GAAG,EAAE;IAEhC,MAAM,cAAc,GAAG,gBAAgB;QACrC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;QACxB,CAAC,CAAC,eAAe,CAAC;IACpB,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAAE;QACtC,OAAO,KAAK,CAAC;KACd;IAED,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,wBAAwB;IACxB,IAAI,CAAC,IAAI,EAAE;QACT,OAAO,KAAK,CAAC;KACd;IACD,mEAAmE;IACnE,MAAM,iBAAiB,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC;IAC1D,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA0B,EAC1B,OAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,IAAI,KAAK,CACb,6BAA6B,QAAQ,CAAC,MAAM,kBAAkB,MAAM,CAClE,OAAO,CACR,GAAG,CACL,CAAC;KACH;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAA0B,EAC1B,OAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,GAAG,EACH,OAAO,EACP,OAAO,EACP,iBAAiB,GAMlB;IACC,IAAI,MAAM,CAAC;IACX,IAAI;QACF,IAAI,OAAO,EAAE;YACX,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;gBACpB,MAAM,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC;gBAC/B,IAAI,OAAO,CAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAClC,UAAU,CAAC,GAAG,EAAE;oBACd,MAAM,CAAC,aAAa,CAAC,CAAC;gBACxB,CAAC,EAAE,OAAO,CAAC,CACZ;aACF,CAAC,CAAC;SACJ;aAAM;YACL,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;SAC1C;KACF;IAAC,OAAO,CAAC,EAAE;QACV,iBAAiB,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;KACzC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,OAAqB,EACrB,OAAO,GAAG,GAAG;IAEb,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC;QAC7B,IAAI,OAAO,CAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAClC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,aAAa,CAAC,CAAC;QACxB,CAAC,EAAE,OAAO,CAAC,CACZ;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,2CAA2C;IAC3C,IAAI,OAAO,KAAK,GAAG,EAAE;QACnB,OAAO,OAAO,CAAC;KAChB;IACD,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC1C,IAAI;YACF,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACzD,6EAA6E;YAC7E,iEAAiE;YACjE,IAAI,UAAU,CAAC,KAAK,CAAC,2CAA2C,CAAC,EAAE;gBACjE,OAAO,UAAU,CAAC;aACnB;SACF;QAAC,OAAO,CAAC,EAAE;YACV,aAAa;SACd;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CACnB,QAAkB,EAClB,MAAc;AACd,gCAAgC;AAChC,8DAA8D;AAC9D,OAAc,EAAE;IAIhB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,CAAC,KAAc,EAAE,MAAe,EAAE,EAAE;YAC7C,IAAI,KAAK,EAAE;gBACT,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;aACR;YACD,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,wEAAwE;QACxE,wBAAwB;QACxB,IAAI,MAAM,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE;YAChE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC;SAC/B;aAAM;YACL,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;SAClD;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAA4B,KAAK,EACzB,EAAE;IACV,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE;QAC5B,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;KAC5B;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC;AAIF;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAWD;;;;;;GAMG;AACH,gFAAgF;AAChF,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAAI,KAAU;IAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI;QACF,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC5D;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,KAAc,EAAE,eAAyB,EAAE;IACpE,IAAI,CAAC,KAAK,EAAE;QACV,OAAO;KACR;IAED,IAAI,KAAK,YAAY,KAAK,EAAE;QAC1B,MAAM,wBAAwB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1D,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAC7D,CAAC;QAEF,IACE,wBAAwB;YACxB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACzC,KAAK,KAAK,aAAa,EACvB;YACA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACtB;aAAM;YACL,MAAM,KAAK,CAAC;SACb;KACF;SAAM;QACL,+DAA+D;QAC/D,MAAM,KAAK,CAAC;KACb;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,MAAc;IAEd,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QAC5D,OAAO,KAAK,CAAC;KACd;IACD,OAAO,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n\n/**\n * Checks if two strings are equal, ignoring case.\n *\n * @param value1 - The first string to compare.\n * @param value2 - The second string to compare.\n * @returns `true` if the strings are equal, ignoring case; otherwise, `false`.\n */\nexport function isEqualCaseInsensitive(\n value1: string,\n value2: string,\n): boolean {\n if (typeof value1 !== 'string' || typeof value2 !== 'string') {\n return false;\n }\n return value1.toLowerCase() === value2.toLowerCase();\n}\n"]} +\ No newline at end of file diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index c33485f665b7..2ceaff74f131 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -4002,10 +4002,9 @@ export default class MetamaskController extends EventEmitter { ), // CurrencyRateController - currencyRateStartPollingByNetworkClientId: - currencyRateController.startPollingByNetworkClientId.bind( - currencyRateController, - ), + currencyRateStartPolling: currencyRateController.startPolling.bind( + currencyRateController, + ), currencyRateStopPollingByPollingToken: currencyRateController.stopPollingByPollingToken.bind( currencyRateController, diff --git a/package.json b/package.json index c3b60bfa1e48..fca6cafd7b0e 100644 --- a/package.json +++ b/package.json @@ -264,7 +264,12 @@ "@metamask/network-controller@npm:^17.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", "@metamask/network-controller@npm:^19.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", "@metamask/network-controller@npm:^20.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", - "path-to-regexp": "1.9.0" + "path-to-regexp": "1.9.0", + "@metamask/controller-utils@npm:^11.3.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", + "@metamask/controller-utils@npm:^11.2.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", + "@metamask/controller-utils@npm:^11.1.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", + "@metamask/controller-utils@npm:^11.0.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", + "@metamask/controller-utils@npm:^11.0.2": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch" }, "dependencies": { "@babel/runtime": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", @@ -300,12 +305,12 @@ "@metamask/address-book-controller": "^6.0.0", "@metamask/announcement-controller": "^7.0.0", "@metamask/approval-controller": "^7.0.0", - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", "@metamask/base-controller": "^7.0.0", "@metamask/bitcoin-wallet-snap": "^0.8.1", "@metamask/browser-passworder": "^4.3.0", "@metamask/contract-metadata": "^2.5.0", - "@metamask/controller-utils": "^11.2.0", + "@metamask/controller-utils": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", "@metamask/design-tokens": "^4.0.0", "@metamask/ens-controller": "^13.0.0", "@metamask/ens-resolver-snap": "^0.1.2", diff --git a/ui/hooks/useCurrencyRatePolling.ts b/ui/hooks/useCurrencyRatePolling.ts index fb14b1c94797..f9d58620b2b0 100644 --- a/ui/hooks/useCurrencyRatePolling.ts +++ b/ui/hooks/useCurrencyRatePolling.ts @@ -16,9 +16,10 @@ const useCurrencyRatePolling = (networkClientId?: string) => { const selectedNetworkClientId = useSelector(getSelectedNetworkClientId); usePolling({ - startPollingByNetworkClientId: currencyRateStartPollingByNetworkClientId, + startPolling: (input) => + currencyRateStartPollingByNetworkClientId(input.networkClientId), stopPollingByPollingToken: currencyRateStopPollingByPollingToken, - networkClientId: networkClientId ?? selectedNetworkClientId, + input: { networkClientId: networkClientId ?? selectedNetworkClientId }, enabled: useCurrencyRateCheck && completedOnboarding, }); }; diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js index 5ad37925054b..abbaf0db0bb9 100644 --- a/ui/hooks/useGasFeeEstimates.js +++ b/ui/hooks/useGasFeeEstimates.js @@ -74,9 +74,10 @@ export function useGasFeeEstimates(_networkClientId) { }, [networkClientId]); usePolling({ - startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId, + startPolling: (input) => + gasFeeStartPollingByNetworkClientId(input.networkClientId), stopPollingByPollingToken: gasFeeStopPollingByPollingToken, - networkClientId, + input: { networkClientId }, }); return { diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts index 1a9d6b1f576e..613e70cf17b5 100644 --- a/ui/hooks/usePolling.ts +++ b/ui/hooks/usePolling.ts @@ -1,22 +1,16 @@ import { useEffect, useRef } from 'react'; -type UsePollingOptions = { +type UsePollingOptions = { callback?: (pollingToken: string) => (pollingToken: string) => void; - startPollingByNetworkClientId: ( - networkClientId: string, - // TODO: Replace `any` with type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - options: any, - ) => Promise; + startPolling: (input: PollingInput) => Promise; stopPollingByPollingToken: (pollingToken: string) => void; - networkClientId: string; - // TODO: Replace `any` with type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - options?: any; + input: PollingInput; enabled?: boolean; }; -const usePolling = (usePollingOptions: UsePollingOptions) => { +const usePolling = ( + usePollingOptions: UsePollingOptions, +) => { const pollTokenRef = useRef(null); const cleanupRef = useRef void)>(null); let isMounted = false; @@ -38,10 +32,7 @@ const usePolling = (usePollingOptions: UsePollingOptions) => { // Start polling when the component mounts usePollingOptions - .startPollingByNetworkClientId( - usePollingOptions.networkClientId, - usePollingOptions.options, - ) + .startPolling(usePollingOptions.input) .then((pollToken) => { pollTokenRef.current = pollToken; cleanupRef.current = usePollingOptions.callback?.(pollToken) || null; @@ -56,12 +47,7 @@ const usePolling = (usePollingOptions: UsePollingOptions) => { cleanup(); }; }, [ - usePollingOptions.networkClientId, - usePollingOptions.options && - JSON.stringify( - usePollingOptions.options, - Object.keys(usePollingOptions.options).sort(), - ), + usePollingOptions.input && JSON.stringify(usePollingOptions.input), usePollingOptions.enabled, ]); }; diff --git a/ui/store/actions.ts b/ui/store/actions.ts index a051bb15d5fd..a4c80c17ed42 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4559,8 +4559,8 @@ export async function currencyRateStartPollingByNetworkClientId( networkClientId: string, ): Promise { const pollingToken = await submitRequestToBackground( - 'currencyRateStartPollingByNetworkClientId', - [networkClientId], + 'currencyRateStartPolling', + [{ networkClientId }], ); await addPollingTokenToAppState(pollingToken); return pollingToken; diff --git a/yarn.lock b/yarn.lock index af059f8960e9..0c29cfe59972 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4862,9 +4862,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:38.3.0": - version: 38.3.0 - resolution: "@metamask/assets-controllers@npm:38.3.0" +"@metamask/assets-controllers@npm:39.0.0": + version: 39.0.0 + resolution: "@metamask/assets-controllers@npm:39.0.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4877,8 +4877,8 @@ __metadata: "@metamask/controller-utils": "npm:^11.3.0" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^10.0.1" - "@metamask/rpc-errors": "npm:^6.3.1" + "@metamask/polling-controller": "npm:^11.0.0" + "@metamask/rpc-errors": "npm:^7.0.0" "@metamask/utils": "npm:^9.1.0" "@types/bn.js": "npm:^5.1.5" "@types/uuid": "npm:^8.3.0" @@ -4896,13 +4896,13 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^21.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/b6e69c9925c50f351b9de1e31cc5d9a4c0ab7cf1abf116c0669611ecb58b3890dd0de53d36bcaaea4f8c45d6ddc2c53eef80c42f93f8f303f1ee9d8df088872b + checksum: 10/1fcfbe98fc1d2cf2b3dfef94d4a3c0752cfd9b5e7208196ebc58c34e34cbb47480eaa608979cdcf41abb7f8ce3c4a8ee2f6031793a5b584ce377f2fff3ec6ade languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch": - version: 38.3.0 - resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch::version=38.3.0&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": + version: 39.0.0 + resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=39.0.0&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4915,8 +4915,8 @@ __metadata: "@metamask/controller-utils": "npm:^11.3.0" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^10.0.1" - "@metamask/rpc-errors": "npm:^6.3.1" + "@metamask/polling-controller": "npm:^11.0.0" + "@metamask/rpc-errors": "npm:^7.0.0" "@metamask/utils": "npm:^9.1.0" "@types/bn.js": "npm:^5.1.5" "@types/uuid": "npm:^8.3.0" @@ -4934,7 +4934,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^21.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/1f57289a3a2a88f1f16e00a138b30b9a8e4ac894086732a463e6b47d5e984e0a7e05ef2ec345f0e1cd69857669253260d53d4c37b2b3d9b970999602fc01a21c + checksum: 10/95cbdcf80e46a601118c806ba41113ac2feb18f2518265c4084c0b37d04e7a02ea6fb4ca2ff480905b9f9f4c13e2daaa6ae6bd4d375986396c5ef26ce0d2bed3 languageName: node linkType: hard @@ -5015,7 +5015,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0": +"@metamask/controller-utils@npm:11.3.0": version: 11.3.0 resolution: "@metamask/controller-utils@npm:11.3.0" dependencies: @@ -5032,6 +5032,23 @@ __metadata: languageName: node linkType: hard +"@metamask/controller-utils@patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch": + version: 11.3.0 + resolution: "@metamask/controller-utils@patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch::version=11.3.0&hash=9c5e87" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/ethjs-unit": "npm:^0.3.0" + "@metamask/utils": "npm:^9.1.0" + "@spruceid/siwe-parser": "npm:2.1.0" + "@types/bn.js": "npm:^5.1.5" + bn.js: "npm:^5.2.1" + eth-ens-namehash: "npm:^2.0.8" + fast-deep-equal: "npm:^3.1.3" + checksum: 10/841bd38835a298f38b1a56e34ead97da1a55c60a27fa2ec6f4bafb28f43b49d4683ce21129c43f7cfc368804431b181299c457408bb4d69a4a1871e0d62fc846 + languageName: node + linkType: hard + "@metamask/design-tokens@npm:^1.12.0": version: 1.13.0 resolution: "@metamask/design-tokens@npm:1.13.0" @@ -5993,9 +6010,9 @@ __metadata: languageName: node linkType: hard -"@metamask/polling-controller@npm:^10.0.1": - version: 10.0.1 - resolution: "@metamask/polling-controller@npm:10.0.1" +"@metamask/polling-controller@npm:^11.0.0": + version: 11.0.0 + resolution: "@metamask/polling-controller@npm:11.0.0" dependencies: "@metamask/base-controller": "npm:^7.0.1" "@metamask/controller-utils": "npm:^11.3.0" @@ -6005,7 +6022,7 @@ __metadata: uuid: "npm:^8.3.2" peerDependencies: "@metamask/network-controller": ^21.0.0 - checksum: 10/25c11e65eeccb08a2b4b7dec21ccabb4b797907edb03a1534ebacb87d0754a3ade52aad061aad8b3ac23bfc39917c0d61b9734e32bc748c210b2997410ae45a9 + checksum: 10/67b563a5d1ce02dc9c2db25ad4ad1fb9f75d5578cf380cce85176ff2cd136addce612c3982653254647b9d8c535374e93d96abb6e500e42076bf3a524a72e75f languageName: node linkType: hard @@ -26095,14 +26112,14 @@ __metadata: "@metamask/announcement-controller": "npm:^7.0.0" "@metamask/api-specs": "npm:^0.9.3" "@metamask/approval-controller": "npm:^7.0.0" - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch" + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch" "@metamask/auto-changelog": "npm:^2.1.0" "@metamask/base-controller": "npm:^7.0.0" "@metamask/bitcoin-wallet-snap": "npm:^0.8.1" "@metamask/browser-passworder": "npm:^4.3.0" "@metamask/build-utils": "npm:^3.0.0" "@metamask/contract-metadata": "npm:^2.5.0" - "@metamask/controller-utils": "npm:^11.2.0" + "@metamask/controller-utils": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch" "@metamask/design-tokens": "npm:^4.0.0" "@metamask/ens-controller": "npm:^13.0.0" "@metamask/ens-resolver-snap": "npm:^0.1.2" From 0f3cd646a544875bc1692339c29d099063c782a4 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 22 Oct 2024 14:43:33 -0700 Subject: [PATCH 02/50] update ConfirmTransaction --- .../confirm-transaction/confirm-transaction.component.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js index 156bca192523..12971f21a2af 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js @@ -126,9 +126,10 @@ const ConfirmTransaction = () => { const prevTransactionId = usePrevious(transactionId); usePolling({ - startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId, + startPolling: (input) => + gasFeeStartPollingByNetworkClientId(input.networkClientId), stopPollingByPollingToken: gasFeeStopPollingByPollingToken, - networkClientId: transaction.networkClientId ?? networkClientId, + input: { networkClientId: transaction.networkClientId ?? networkClientId }, }); useEffect(() => { From bdf921b6280e4baa41aee4b3c751c8fce3b98dbd Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 22 Oct 2024 15:51:03 -0700 Subject: [PATCH 03/50] fix useGasFeeEstimates unit test --- ui/hooks/useGasFeeEstimates.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/hooks/useGasFeeEstimates.test.js b/ui/hooks/useGasFeeEstimates.test.js index 0187ac793bbe..4243ba37f564 100644 --- a/ui/hooks/useGasFeeEstimates.test.js +++ b/ui/hooks/useGasFeeEstimates.test.js @@ -115,9 +115,9 @@ describe('useGasFeeEstimates', () => { renderHook(() => useGasFeeEstimates()); }); expect(usePolling).toHaveBeenCalledWith({ - startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId, + startPolling: expect.any(Function), stopPollingByPollingToken: gasFeeStopPollingByPollingToken, - networkClientId: 'selectedNetworkClientId', + input: { networkClientId: 'selectedNetworkClientId' }, }); }); @@ -127,9 +127,9 @@ describe('useGasFeeEstimates', () => { renderHook(() => useGasFeeEstimates('networkClientId1')); }); expect(usePolling).toHaveBeenCalledWith({ - startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId, + startPolling: expect.any(Function), stopPollingByPollingToken: gasFeeStopPollingByPollingToken, - networkClientId: 'networkClientId1', + input: { networkClientId: 'networkClientId1' }, }); }); From 9bc4ecfea1ea9e1f7467986f18cdbb3c4f8b93b7 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 22 Oct 2024 19:53:39 -0700 Subject: [PATCH 04/50] fix usePolling tests --- ui/hooks/usePolling.test.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/ui/hooks/usePolling.test.js b/ui/hooks/usePolling.test.js index 9250257d3cbc..a556bb86be54 100644 --- a/ui/hooks/usePolling.test.js +++ b/ui/hooks/usePolling.test.js @@ -4,13 +4,12 @@ import usePolling from './usePolling'; describe('usePolling', () => { // eslint-disable-next-line jest/no-done-callback - it('calls startPollingByNetworkClientId and callback option args with polling token when component instantiating the hook mounts', (done) => { + it('calls startPolling and calls back with polling token when component instantiating the hook mounts', (done) => { const mockStart = jest.fn().mockImplementation(() => { return Promise.resolve('pollingToken'); }); const mockStop = jest.fn(); const networkClientId = 'mainnet'; - const options = {}; const mockState = { metamask: {}, }; @@ -18,17 +17,16 @@ describe('usePolling', () => { renderHookWithProvider(() => { usePolling({ callback: (pollingToken) => { - expect(mockStart).toHaveBeenCalledWith(networkClientId, options); + expect(mockStart).toHaveBeenCalledWith({ networkClientId }); expect(pollingToken).toBeDefined(); done(); return (_pollingToken) => { // noop }; }, - startPollingByNetworkClientId: mockStart, + startPolling: mockStart, stopPollingByPollingToken: mockStop, - networkClientId, - options, + input: { networkClientId }, }); }, mockState); }); @@ -39,7 +37,6 @@ describe('usePolling', () => { }); const mockStop = jest.fn(); const networkClientId = 'mainnet'; - const options = {}; const mockState = { metamask: {}, }; @@ -54,10 +51,9 @@ describe('usePolling', () => { done(); }; }, - startPollingByNetworkClientId: mockStart, + startPolling: mockStart, stopPollingByPollingToken: mockStop, - networkClientId, - options, + input: { networkClientId }, }), mockState, ); From 9b1529b20f86438892eecddcfb2466d5b74b1bf4 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 23 Oct 2024 13:15:35 -0700 Subject: [PATCH 05/50] bump controller utils --- package.json | 9 ++------- yarn.lock | 27 +++++---------------------- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index fca6cafd7b0e..fa671df29cc7 100644 --- a/package.json +++ b/package.json @@ -264,12 +264,7 @@ "@metamask/network-controller@npm:^17.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", "@metamask/network-controller@npm:^19.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", "@metamask/network-controller@npm:^20.0.0": "patch:@metamask/network-controller@npm%3A21.0.0#~/.yarn/patches/@metamask-network-controller-npm-21.0.0-559aa8e395.patch", - "path-to-regexp": "1.9.0", - "@metamask/controller-utils@npm:^11.3.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", - "@metamask/controller-utils@npm:^11.2.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", - "@metamask/controller-utils@npm:^11.1.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", - "@metamask/controller-utils@npm:^11.0.0": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", - "@metamask/controller-utils@npm:^11.0.2": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch" + "path-to-regexp": "1.9.0" }, "dependencies": { "@babel/runtime": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", @@ -310,7 +305,7 @@ "@metamask/bitcoin-wallet-snap": "^0.8.1", "@metamask/browser-passworder": "^4.3.0", "@metamask/contract-metadata": "^2.5.0", - "@metamask/controller-utils": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch", + "@metamask/controller-utils": "^11.4.0", "@metamask/design-tokens": "^4.0.0", "@metamask/ens-controller": "^13.0.0", "@metamask/ens-resolver-snap": "^0.1.2", diff --git a/yarn.lock b/yarn.lock index 0c29cfe59972..9d376df08629 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5015,9 +5015,9 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:11.3.0": - version: 11.3.0 - resolution: "@metamask/controller-utils@npm:11.3.0" +"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0": + version: 11.4.0 + resolution: "@metamask/controller-utils@npm:11.4.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@metamask/eth-query": "npm:^4.0.0" @@ -5028,24 +5028,7 @@ __metadata: bn.js: "npm:^5.2.1" eth-ens-namehash: "npm:^2.0.8" fast-deep-equal: "npm:^3.1.3" - checksum: 10/3200228d1f4ea5fa095228db4e5050529caf0470e072382eb8f7571bb9b07515516ca9e846b7751388399d9ae967e4985dafd6120902ef6c998e98f4eb36d964 - languageName: node - linkType: hard - -"@metamask/controller-utils@patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch": - version: 11.3.0 - resolution: "@metamask/controller-utils@patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch::version=11.3.0&hash=9c5e87" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/ethjs-unit": "npm:^0.3.0" - "@metamask/utils": "npm:^9.1.0" - "@spruceid/siwe-parser": "npm:2.1.0" - "@types/bn.js": "npm:^5.1.5" - bn.js: "npm:^5.2.1" - eth-ens-namehash: "npm:^2.0.8" - fast-deep-equal: "npm:^3.1.3" - checksum: 10/841bd38835a298f38b1a56e34ead97da1a55c60a27fa2ec6f4bafb28f43b49d4683ce21129c43f7cfc368804431b181299c457408bb4d69a4a1871e0d62fc846 + checksum: 10/f34d24880eab264bddaa5bef21afaecb206db6978364565d0f7b7a54b1d411f129eb84175041df3be8a66394c2d49e83b6648b5cbde6f34662a60fc553c31458 languageName: node linkType: hard @@ -26119,7 +26102,7 @@ __metadata: "@metamask/browser-passworder": "npm:^4.3.0" "@metamask/build-utils": "npm:^3.0.0" "@metamask/contract-metadata": "npm:^2.5.0" - "@metamask/controller-utils": "patch:@metamask/controller-utils@npm%3A11.3.0#~/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch" + "@metamask/controller-utils": "npm:^11.4.0" "@metamask/design-tokens": "npm:^4.0.0" "@metamask/ens-controller": "npm:^13.0.0" "@metamask/ens-resolver-snap": "npm:^0.1.2" From c8bcc0bebb95f9b36e12f699452ba6d907e186d5 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 23 Oct 2024 13:16:11 -0700 Subject: [PATCH 06/50] remove patch --- ...ntroller-utils-npm-11.3.0-7971498570.patch | 226 ------------------ 1 file changed, 226 deletions(-) delete mode 100644 .yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch diff --git a/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch b/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch deleted file mode 100644 index 78dcfa1e8ead..000000000000 --- a/.yarn/patches/@metamask-controller-utils-npm-11.3.0-7971498570.patch +++ /dev/null @@ -1,226 +0,0 @@ -diff --git a/dist/index.cjs b/dist/index.cjs -index bd9e58b1c07c1fecd36c934efd75312b1effa3cf..aa3a692fc23fbb7c50e38b17b6129545c604ae89 100644 ---- a/dist/index.cjs -+++ b/dist/index.cjs -@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); - }; - Object.defineProperty(exports, "__esModule", { value: true }); --exports.weiHexToGweiDec = exports.toHex = exports.toChecksumHexAddress = exports.timeoutFetch = exports.successfulFetch = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.query = exports.normalizeEnsName = exports.isValidHexAddress = exports.isValidJson = exports.isSmartContractCode = exports.isSafeDynamicKey = exports.isSafeChainId = exports.isPlainObject = exports.isNonEmptyArray = exports.hexToText = exports.hexToBN = exports.handleFetch = exports.gweiDecToWEIBN = exports.getBuyURL = exports.fromHex = exports.fractionBN = exports.fetchWithErrorHandling = exports.convertHexToDecimal = exports.BNToHex = void 0; -+exports.isEqualCaseInsensitive = exports.weiHexToGweiDec = exports.toHex = exports.toChecksumHexAddress = exports.timeoutFetch = exports.successfulFetch = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.query = exports.normalizeEnsName = exports.isValidHexAddress = exports.isValidJson = exports.isSmartContractCode = exports.isSafeDynamicKey = exports.isSafeChainId = exports.isPlainObject = exports.isNonEmptyArray = exports.hexToText = exports.hexToBN = exports.handleFetch = exports.gweiDecToWEIBN = exports.getBuyURL = exports.fromHex = exports.fractionBN = exports.fetchWithErrorHandling = exports.convertHexToDecimal = exports.BNToHex = void 0; - __exportStar(require("./constants.cjs"), exports); - var util_1 = require("./util.cjs"); - Object.defineProperty(exports, "BNToHex", { enumerable: true, get: function () { return util_1.BNToHex; } }); -@@ -43,6 +43,7 @@ Object.defineProperty(exports, "timeoutFetch", { enumerable: true, get: function - Object.defineProperty(exports, "toChecksumHexAddress", { enumerable: true, get: function () { return util_1.toChecksumHexAddress; } }); - Object.defineProperty(exports, "toHex", { enumerable: true, get: function () { return util_1.toHex; } }); - Object.defineProperty(exports, "weiHexToGweiDec", { enumerable: true, get: function () { return util_1.weiHexToGweiDec; } }); -+Object.defineProperty(exports, "isEqualCaseInsensitive", { enumerable: true, get: function () { return util_1.isEqualCaseInsensitive; } }); - __exportStar(require("./types.cjs"), exports); - __exportStar(require("./siwe.cjs"), exports); - //# sourceMappingURL=index.cjs.map -\ No newline at end of file -diff --git a/dist/index.cjs.map b/dist/index.cjs.map -index 9218cac8330ea42f34c55dd162474cde48b653a8..27e5950afdbe30485f68e07b26d4046c2150ac9b 100644 ---- a/dist/index.cjs.map -+++ b/dist/index.cjs.map -@@ -1 +1 @@ --{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,mCA2BgB;AA1Bd,+FAAA,OAAO,OAAA;AACP,2GAAA,mBAAmB,OAAA;AACnB,8GAAA,sBAAsB,OAAA;AACtB,kGAAA,UAAU,OAAA;AACV,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,sGAAA,cAAc,OAAA;AACd,mGAAA,WAAW,OAAA;AACX,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,qGAAA,aAAa,OAAA;AACb,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,mGAAA,WAAW,OAAA;AACX,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,6FAAA,KAAK,OAAA;AACL,qGAAA,aAAa,OAAA;AACb,gHAAA,wBAAwB,OAAA;AACxB,uGAAA,eAAe,OAAA;AACf,oGAAA,YAAY,OAAA;AACZ,4GAAA,oBAAoB,OAAA;AACpB,6FAAA,KAAK,OAAA;AACL,uGAAA,eAAe,OAAA;AAEjB,8CAAwB;AACxB,6CAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} -\ No newline at end of file -+{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,mCA4BgB;AA3Bd,+FAAA,OAAO,OAAA;AACP,2GAAA,mBAAmB,OAAA;AACnB,8GAAA,sBAAsB,OAAA;AACtB,kGAAA,UAAU,OAAA;AACV,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,sGAAA,cAAc,OAAA;AACd,mGAAA,WAAW,OAAA;AACX,+FAAA,OAAO,OAAA;AACP,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,qGAAA,aAAa,OAAA;AACb,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,mGAAA,WAAW,OAAA;AACX,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,6FAAA,KAAK,OAAA;AACL,qGAAA,aAAa,OAAA;AACb,gHAAA,wBAAwB,OAAA;AACxB,uGAAA,eAAe,OAAA;AACf,oGAAA,YAAY,OAAA;AACZ,4GAAA,oBAAoB,OAAA;AACpB,6FAAA,KAAK,OAAA;AACL,uGAAA,eAAe,OAAA;AACf,8GAAA,sBAAsB,OAAA;AAExB,8CAAwB;AACxB,6CAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n isEqualCaseInsensitive,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} -\ No newline at end of file -diff --git a/dist/index.d.cts b/dist/index.d.cts -index 4ebb06e58295d0c7a2de2c362808d8168b4d735f..942079412efbe12306a8c3957e29fb08b86f09aa 100644 ---- a/dist/index.d.cts -+++ b/dist/index.d.cts -@@ -1,6 +1,6 @@ - export * from "./constants.cjs"; - export type { NonEmptyArray } from "./util.cjs"; --export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, } from "./util.cjs"; -+export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive, } from "./util.cjs"; - export * from "./types.cjs"; - export * from "./siwe.cjs"; - //# sourceMappingURL=index.d.cts.map -\ No newline at end of file -diff --git a/dist/index.d.cts.map b/dist/index.d.cts.map -index ecad0fd2b254b4b126848b441424bf3779ed166d..f8f143c8bf591347106fbd0109a11a57cae81835 100644 ---- a/dist/index.d.cts.map -+++ b/dist/index.d.cts.map -@@ -1 +1 @@ --{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,GAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} -\ No newline at end of file -+{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,GACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} -\ No newline at end of file -diff --git a/dist/index.d.mts b/dist/index.d.mts -index 969a616c848ca98a666a8adfdcb3e5414e4dbb59..7be5be08a6fe001bcf5ab7691fab805159c60218 100644 ---- a/dist/index.d.mts -+++ b/dist/index.d.mts -@@ -1,6 +1,6 @@ - export * from "./constants.mjs"; - export type { NonEmptyArray } from "./util.mjs"; --export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, } from "./util.mjs"; -+export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive, } from "./util.mjs"; - export * from "./types.mjs"; - export * from "./siwe.mjs"; - //# sourceMappingURL=index.d.mts.map -\ No newline at end of file -diff --git a/dist/index.d.mts.map b/dist/index.d.mts.map -index d804348b55cf9029429d3d7826607de38590acb0..448e9ed5d48d572266602973303bbc7f6a26b84d 100644 ---- a/dist/index.d.mts.map -+++ b/dist/index.d.mts.map -@@ -1 +1 @@ --{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,GAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} -\ No newline at end of file -+{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAC5B,YAAY,EAAE,aAAa,EAAE,mBAAe;AAC5C,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,GACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB"} -\ No newline at end of file -diff --git a/dist/index.mjs b/dist/index.mjs -index 4f050229eac5f177f3b3b9891e074bd6355019f3..7ca1bba9c2483959391ffee83c427cfa813266fc 100644 ---- a/dist/index.mjs -+++ b/dist/index.mjs -@@ -1,5 +1,5 @@ - export * from "./constants.mjs"; --export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec } from "./util.mjs"; -+export { BNToHex, convertHexToDecimal, fetchWithErrorHandling, fractionBN, fromHex, getBuyURL, gweiDecToWEIBN, handleFetch, hexToBN, hexToText, isNonEmptyArray, isPlainObject, isSafeChainId, isSafeDynamicKey, isSmartContractCode, isValidJson, isValidHexAddress, normalizeEnsName, query, safelyExecute, safelyExecuteWithTimeout, successfulFetch, timeoutFetch, toChecksumHexAddress, toHex, weiHexToGweiDec, isEqualCaseInsensitive } from "./util.mjs"; - export * from "./types.mjs"; - export * from "./siwe.mjs"; - //# sourceMappingURL=index.mjs.map -\ No newline at end of file -diff --git a/dist/index.mjs.map b/dist/index.mjs.map -index f277eca2f54a81efe5b8c0e2158fa5d6588064df..4fcb2a9ad7fadd8ee352976e7957ae4a23c588b5 100644 ---- a/dist/index.mjs.map -+++ b/dist/index.mjs.map -@@ -1 +1 @@ --{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAE5B,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EAChB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} -\ No newline at end of file -+{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAA4B;AAE5B,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,EACX,OAAO,EACP,SAAS,EACT,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,eAAe,EACf,sBAAsB,EACvB,mBAAe;AAChB,4BAAwB;AACxB,2BAAuB","sourcesContent":["export * from './constants';\nexport type { NonEmptyArray } from './util';\nexport {\n BNToHex,\n convertHexToDecimal,\n fetchWithErrorHandling,\n fractionBN,\n fromHex,\n getBuyURL,\n gweiDecToWEIBN,\n handleFetch,\n hexToBN,\n hexToText,\n isNonEmptyArray,\n isPlainObject,\n isSafeChainId,\n isSafeDynamicKey,\n isSmartContractCode,\n isValidJson,\n isValidHexAddress,\n normalizeEnsName,\n query,\n safelyExecute,\n safelyExecuteWithTimeout,\n successfulFetch,\n timeoutFetch,\n toChecksumHexAddress,\n toHex,\n weiHexToGweiDec,\n isEqualCaseInsensitive,\n} from './util';\nexport * from './types';\nexport * from './siwe';\n"]} -\ No newline at end of file -diff --git a/dist/util.cjs b/dist/util.cjs -index 9033310b086b5c6795ba96b1f7b2a83d6e5eb1cf..e2cbb26c2b805a2be1d3380281044f8d699f1873 100644 ---- a/dist/util.cjs -+++ b/dist/util.cjs -@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; - }; - Object.defineProperty(exports, "__esModule", { value: true }); --exports.isValidJson = exports.isNonEmptyArray = exports.isPlainObject = exports.convertHexToDecimal = exports.query = exports.normalizeEnsName = exports.timeoutFetch = exports.fetchWithErrorHandling = exports.handleFetch = exports.successfulFetch = exports.isSmartContractCode = exports.isValidHexAddress = exports.toChecksumHexAddress = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.toHex = exports.fromHex = exports.hexToText = exports.hexToBN = exports.getBuyURL = exports.weiHexToGweiDec = exports.gweiDecToWEIBN = exports.fractionBN = exports.BNToHex = exports.isSafeChainId = exports.isSafeDynamicKey = exports.PROTOTYPE_POLLUTION_BLOCKLIST = void 0; -+exports.isEqualCaseInsensitive = exports.isValidJson = exports.isNonEmptyArray = exports.isPlainObject = exports.convertHexToDecimal = exports.query = exports.normalizeEnsName = exports.timeoutFetch = exports.fetchWithErrorHandling = exports.handleFetch = exports.successfulFetch = exports.isSmartContractCode = exports.isValidHexAddress = exports.toChecksumHexAddress = exports.safelyExecuteWithTimeout = exports.safelyExecute = exports.toHex = exports.fromHex = exports.hexToText = exports.hexToBN = exports.getBuyURL = exports.weiHexToGweiDec = exports.gweiDecToWEIBN = exports.fractionBN = exports.BNToHex = exports.isSafeChainId = exports.isSafeDynamicKey = exports.PROTOTYPE_POLLUTION_BLOCKLIST = void 0; - const util_1 = require("@ethereumjs/util"); - const ethjs_unit_1 = require("@metamask/ethjs-unit"); - const utils_1 = require("@metamask/utils"); -@@ -509,4 +509,18 @@ function logOrRethrowError(error, codesToCatch = []) { - throw error; - } - } -+/** -+ * Checks if two strings are equal, ignoring case. -+ * -+ * @param value1 - The first string to compare. -+ * @param value2 - The second string to compare. -+ * @returns `true` if the strings are equal, ignoring case; otherwise, `false`. -+ */ -+function isEqualCaseInsensitive(value1, value2) { -+ if (typeof value1 !== 'string' || typeof value2 !== 'string') { -+ return false; -+ } -+ return value1.toLowerCase() === value2.toLowerCase(); -+} -+exports.isEqualCaseInsensitive = isEqualCaseInsensitive; - //# sourceMappingURL=util.cjs.map -\ No newline at end of file -diff --git a/dist/util.cjs.map b/dist/util.cjs.map -index a01b63e991d4b961483a57dbc19440671ab031c8..39f4c32d605f042606c81e46fcc8ab212d493bf4 100644 ---- a/dist/util.cjs.map -+++ b/dist/util.cjs.map -@@ -1 +1 @@ --{"version":3,"file":"util.cjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n"]} -\ No newline at end of file -+{"version":3,"file":"util.cjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n\n/**\n * Checks if two strings are equal, ignoring case.\n *\n * @param value1 - The first string to compare.\n * @param value2 - The second string to compare.\n * @returns `true` if the strings are equal, ignoring case; otherwise, `false`.\n */\nexport function isEqualCaseInsensitive(\n value1: string,\n value2: string,\n): boolean {\n if (typeof value1 !== 'string' || typeof value2 !== 'string') {\n return false;\n }\n return value1.toLowerCase() === value2.toLowerCase();\n}\n"]} -\ No newline at end of file -diff --git a/dist/util.d.cts b/dist/util.d.cts -index fba6d2b047ba9a9a53c683fdf1ae41f3528581b1..0d3418f8c99fda0da1d047d9ba89a7e878935530 100644 ---- a/dist/util.d.cts -+++ b/dist/util.d.cts -@@ -239,5 +239,13 @@ export declare function isNonEmptyArray(value: T[]): value is NonEmptyArray(value: T[]): value is NonEmptyArray key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n"]} -\ No newline at end of file -+{"version":3,"file":"util.mjs","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidAddress, toChecksumAddress } from '@ethereumjs/util';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei, toWei } from '@metamask/ethjs-unit';\nimport type { Hex, Json } from '@metamask/utils';\nimport {\n isStrictHexString,\n add0x,\n isHexString,\n remove0x,\n} from '@metamask/utils';\nimport BN from 'bn.js';\nimport ensNamehash from 'eth-ens-namehash';\nimport deepEqual from 'fast-deep-equal';\n\nimport { MAX_SAFE_CHAIN_ID } from './constants';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\nexport const PROTOTYPE_POLLUTION_BLOCKLIST = [\n '__proto__',\n 'constructor',\n 'prototype',\n] as const;\n\n/**\n * Checks whether a dynamic property key could be used in\n * a [prototype pollution attack](https://portswigger.net/web-security/prototype-pollution).\n *\n * @param key - The dynamic key to validate.\n * @returns Whether the given dynamic key is safe to use.\n */\nexport function isSafeDynamicKey(key: string): boolean {\n return (\n typeof key === 'string' &&\n !PROTOTYPE_POLLUTION_BLOCKLIST.some((blockedKey) => key === blockedKey)\n );\n}\n\n/**\n * Checks whether the given number primitive chain ID is safe.\n * Because some cryptographic libraries we use expect the chain ID to be a\n * number primitive, it must not exceed a certain size.\n *\n * @param chainId - The chain ID to check for safety.\n * @returns Whether the given chain ID is safe.\n */\nexport function isSafeChainId(chainId: Hex): boolean {\n if (!isHexString(chainId)) {\n return false;\n }\n const decimalChainId = Number.parseInt(\n chainId,\n isStrictHexString(chainId) ? 16 : 10,\n );\n return (\n Number.isSafeInteger(decimalChainId) &&\n decimalChainId > 0 &&\n decimalChainId <= MAX_SAFE_CHAIN_ID\n );\n}\n/**\n * Converts a BN object to a hex string with a '0x' prefix.\n *\n * @param inputBn - BN instance to convert to a hex string.\n * @returns A '0x'-prefixed hex string.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function BNToHex(inputBn: BN) {\n return add0x(inputBn.toString(16));\n}\n\n/**\n * Used to multiply a BN by a fraction.\n *\n * @param targetBN - Number to multiply by a fraction.\n * @param numerator - Numerator of the fraction multiplier.\n * @param denominator - Denominator of the fraction multiplier.\n * @returns Product of the multiplication.\n */\nexport function fractionBN(\n targetBN: BN,\n numerator: number | string,\n denominator: number | string,\n) {\n const numBN = new BN(numerator);\n const denomBN = new BN(denominator);\n return targetBN.mul(numBN).div(denomBN);\n}\n\n/**\n * Used to convert a base-10 number from GWEI to WEI. Can handle numbers with decimal parts.\n *\n * @param n - The base 10 number to convert to WEI.\n * @returns The number in WEI, as a BN.\n */\nexport function gweiDecToWEIBN(n: number | string) {\n if (Number.isNaN(n)) {\n return new BN(0);\n }\n\n const parts = n.toString().split('.');\n const wholePart = parts[0] || '0';\n let decimalPart = parts[1] || '';\n\n if (!decimalPart) {\n return toWei(wholePart, 'gwei');\n }\n\n if (decimalPart.length <= 9) {\n return toWei(`${wholePart}.${decimalPart}`, 'gwei');\n }\n\n const decimalPartToRemove = decimalPart.slice(9);\n const decimalRoundingDigit = decimalPartToRemove[0];\n\n decimalPart = decimalPart.slice(0, 9);\n let wei = toWei(`${wholePart}.${decimalPart}`, 'gwei');\n\n if (Number(decimalRoundingDigit) >= 5) {\n wei = wei.add(new BN(1));\n }\n\n return wei;\n}\n\n/**\n * Used to convert values from wei hex format to dec gwei format.\n *\n * @param hex - The value in hex wei.\n * @returns The value in dec gwei as string.\n */\nexport function weiHexToGweiDec(hex: string) {\n const hexWei = new BN(remove0x(hex), 16);\n return fromWei(hexWei, 'gwei');\n}\n\n/**\n * Return a URL that can be used to obtain ETH for a given network.\n *\n * @param networkCode - Network code of desired network.\n * @param address - Address to deposit obtained ETH.\n * @param amount - How much ETH is desired.\n * @returns URL to buy ETH based on network.\n */\nexport function getBuyURL(\n networkCode = '1',\n address?: string,\n amount = 5,\n): string | undefined {\n switch (networkCode) {\n case '1':\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`;\n case '5':\n return 'https://goerli-faucet.slock.it/';\n case '11155111':\n return 'https://sepoliafaucet.net/';\n default:\n return undefined;\n }\n}\n\n/**\n * Converts a hex string to a BN object.\n *\n * @param inputHex - Number represented as a hex string.\n * @returns A BN instance.\n */\nexport function hexToBN(inputHex: string) {\n return inputHex ? new BN(remove0x(inputHex), 16) : new BN(0);\n}\n\n/**\n * A helper function that converts hex data to human readable string.\n *\n * @param hex - The hex string to convert to string.\n * @returns A human readable string conversion.\n */\nexport function hexToText(hex: string) {\n try {\n const stripped = remove0x(hex);\n const buff = Buffer.from(stripped, 'hex');\n return buff.toString('utf8');\n } catch (e) {\n /* istanbul ignore next */\n return hex;\n }\n}\n\n/**\n * Parses a hex string and converts it into a number that can be operated on in a bignum-safe,\n * base-10 way.\n *\n * @param value - A base-16 number encoded as a string.\n * @returns The number as a BN object in base-16 mode.\n */\nexport function fromHex(value: string | BN): BN {\n if (BN.isBN(value)) {\n return value;\n }\n return new BN(hexToBN(value).toString(10));\n}\n\n/**\n * Converts an integer to a hexadecimal representation.\n *\n * @param value - An integer, an integer encoded as a base-10 string, or a BN.\n * @returns The integer encoded as a hex string.\n */\nexport function toHex(value: number | bigint | string | BN): Hex {\n if (typeof value === 'string' && isStrictHexString(value)) {\n return value;\n }\n const hexString =\n BN.isBN(value) || typeof value === 'bigint'\n ? value.toString(16)\n : new BN(value.toString(), 10).toString(16);\n return `0x${hexString}`;\n}\n\n/**\n * Execute and return an asynchronous operation without throwing errors.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecute(\n operation: () => Promise,\n logError = false,\n): Promise {\n try {\n return await operation();\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Execute and return an asynchronous operation with a timeout.\n *\n * @param operation - Function returning a Promise.\n * @param logError - Determines if the error should be logged.\n * @param timeout - Timeout to fail the operation.\n * @template Result - Type of the result of the async operation\n * @returns Promise resolving to the result of the async operation.\n */\nexport async function safelyExecuteWithTimeout(\n operation: () => Promise,\n logError = false,\n timeout = 500,\n): Promise {\n try {\n return await Promise.race([\n operation(),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } catch (error) {\n /* istanbul ignore next */\n if (logError) {\n console.error(error);\n }\n return undefined;\n }\n}\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * @param address - The address to convert.\n * @returns The address in 0x-prefixed hexadecimal checksummed form if it is valid.\n */\nexport function toChecksumHexAddress(address: string): string;\n\n/**\n * Convert an address to a checksummed hexadecimal address.\n *\n * Note that this particular overload does nothing.\n *\n * @param address - A value that is not a string (e.g. `undefined` or `null`).\n * @returns The `address` untouched.\n * @deprecated This overload is designed to gracefully handle an invalid input\n * and is only present for backward compatibility. It may be removed in a future\n * major version. Please pass a string to `toChecksumHexAddress` instead.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function toChecksumHexAddress(address: T): T;\n\n// Tools only see JSDocs for overloads and ignore them for the implementation.\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function toChecksumHexAddress(address: unknown) {\n if (typeof address !== 'string') {\n // Mimic behavior of `addHexPrefix` from `ethereumjs-util` (which this\n // function was previously using) for backward compatibility.\n return address;\n }\n\n const hexPrefixed = add0x(address);\n\n if (!isHexString(hexPrefixed)) {\n // Version 5.1 of ethereumjs-util would have returned '0xY' for input 'y'\n // but we shouldn't waste effort trying to change case on a clearly invalid\n // string. Instead just return the hex prefixed original string which most\n // closely mimics the original behavior.\n return hexPrefixed;\n }\n\n return toChecksumAddress(hexPrefixed);\n}\n\n/**\n * Validates that the input is a hex address. This utility method is a thin\n * wrapper around @metamask/utils.isValidHexAddress, with the exception that it\n * by default will return true for hex strings that are otherwise valid\n * hex addresses, but are not prefixed with `0x`.\n *\n * @param possibleAddress - Input parameter to check against.\n * @param options - The validation options.\n * @param options.allowNonPrefixed - If true will allow addresses without `0x` prefix.`\n * @returns Whether or not the input is a valid hex address.\n */\nexport function isValidHexAddress(\n possibleAddress: string,\n { allowNonPrefixed = true } = {},\n): boolean {\n const addressToCheck = allowNonPrefixed\n ? add0x(possibleAddress)\n : possibleAddress;\n if (!isStrictHexString(addressToCheck)) {\n return false;\n }\n\n return isValidAddress(addressToCheck);\n}\n\n/**\n * Returns whether the given code corresponds to a smart contract.\n *\n * @param code - The potential smart contract code.\n * @returns Whether the code was smart contract code or not.\n */\nexport function isSmartContractCode(code: string) {\n /* istanbul ignore if */\n if (!code) {\n return false;\n }\n // Geth will return '0x', and ganache-core v2.2.1 will return '0x0'\n const smartContractCode = code !== '0x' && code !== '0x0';\n return smartContractCode;\n}\n\n/**\n * Execute fetch and verify that the response was successful.\n *\n * @param request - Request information.\n * @param options - Fetch options.\n * @returns The fetch response.\n */\nexport async function successfulFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await fetch(request, options);\n if (!response.ok) {\n throw new Error(\n `Fetch failed with status '${response.status}' for request '${String(\n request,\n )}'`,\n );\n }\n return response;\n}\n\n/**\n * Execute fetch and return object response.\n *\n * @param request - The request information.\n * @param options - The fetch options.\n * @returns The fetch response JSON data.\n */\nexport async function handleFetch(\n request: URL | RequestInfo,\n options?: RequestInit,\n) {\n const response = await successfulFetch(request, options);\n const object = await response.json();\n return object;\n}\n\n/**\n * Execute fetch and return object response, log if known error thrown, otherwise rethrow error.\n *\n * @param request - the request options object\n * @param request.url - The request url to query.\n * @param request.options - The fetch options.\n * @param request.timeout - Timeout to fail request\n * @param request.errorCodesToCatch - array of error codes for errors we want to catch in a particular context\n * @returns The fetch response JSON data or undefined (if error occurs).\n */\nexport async function fetchWithErrorHandling({\n url,\n options,\n timeout,\n errorCodesToCatch,\n}: {\n url: string;\n options?: RequestInit;\n timeout?: number;\n errorCodesToCatch?: number[];\n}) {\n let result;\n try {\n if (timeout) {\n result = Promise.race([\n await handleFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n } else {\n result = await handleFetch(url, options);\n }\n } catch (e) {\n logOrRethrowError(e, errorCodesToCatch);\n }\n return result;\n}\n\n/**\n * Fetch that fails after timeout.\n *\n * @param url - Url to fetch.\n * @param options - Options to send with the request.\n * @param timeout - Timeout to fail request.\n * @returns Promise resolving the request.\n */\nexport async function timeoutFetch(\n url: string,\n options?: RequestInit,\n timeout = 500,\n): Promise {\n return Promise.race([\n successfulFetch(url, options),\n new Promise((_, reject) =>\n setTimeout(() => {\n reject(TIMEOUT_ERROR);\n }, timeout),\n ),\n ]);\n}\n\n/**\n * Normalizes the given ENS name.\n *\n * @param ensName - The ENS name.\n * @returns The normalized ENS name string.\n */\nexport function normalizeEnsName(ensName: string): string | null {\n // `.` refers to the registry root contract\n if (ensName === '.') {\n return ensName;\n }\n if (ensName && typeof ensName === 'string') {\n try {\n const normalized = ensNamehash.normalize(ensName.trim());\n // this regex is only sufficient with the above call to ensNamehash.normalize\n // TODO: change 7 in regex to 3 when shorter ENS domains are live\n if (normalized.match(/^(([\\w\\d-]+)\\.)*[\\w\\d-]{7,}\\.(eth|test)$/u)) {\n return normalized;\n }\n } catch (_) {\n // do nothing\n }\n }\n return null;\n}\n\n/**\n * Wrapper method to handle EthQuery requests.\n *\n * @param ethQuery - EthQuery object initialized with a provider.\n * @param method - Method to request.\n * @param args - Arguments to send.\n * @returns Promise resolving the request.\n */\nexport function query(\n ethQuery: EthQuery,\n method: string,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any[] = [],\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise {\n return new Promise((resolve, reject) => {\n const cb = (error: unknown, result: unknown) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n };\n\n // Using `in` rather than `hasProperty` so that we look up the prototype\n // chain for the method.\n if (method in ethQuery && typeof ethQuery[method] === 'function') {\n ethQuery[method](...args, cb);\n } else {\n ethQuery.sendAsync({ method, params: args }, cb);\n }\n });\n}\n\n/**\n * Converts valid hex strings to decimal numbers, and handles unexpected arg types.\n *\n * @param value - a string that is either a hexadecimal with `0x` prefix or a decimal string.\n * @returns a decimal number.\n */\nexport const convertHexToDecimal = (\n value: string | undefined = '0x0',\n): number => {\n if (isStrictHexString(value)) {\n return parseInt(value, 16);\n }\n\n return Number(value) ? Number(value) : 0;\n};\n\ntype PlainObject = Record;\n\n/**\n * Determines whether a value is a \"plain\" object.\n *\n * @param value - A value to check\n * @returns True if the passed value is a plain object\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Like {@link Array}, but always non-empty.\n *\n * @template T - The non-empty array member type.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Type guard for {@link NonEmptyArray}.\n *\n * @template T - The non-empty array member type.\n * @param value - The value to check.\n * @returns Whether the value is a non-empty array.\n */\n// TODO: Either fix this lint violation or explain why it's necessary to ignore.\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function isNonEmptyArray(value: T[]): value is NonEmptyArray {\n return Array.isArray(value) && value.length > 0;\n}\n\n/**\n * Type guard for {@link Json}.\n *\n * @param value - The value to check.\n * @returns Whether the value is valid JSON.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n return deepEqual(value, JSON.parse(JSON.stringify(value)));\n } catch (_) {\n return false;\n }\n}\n\n/**\n * Utility method to log if error is a common fetch error and otherwise rethrow it.\n *\n * @param error - Caught error that we should either rethrow or log to console\n * @param codesToCatch - array of error codes for errors we want to catch and log in a particular context\n */\nfunction logOrRethrowError(error: unknown, codesToCatch: number[] = []) {\n if (!error) {\n return;\n }\n\n if (error instanceof Error) {\n const includesErrorCodeToCatch = codesToCatch.some((code) =>\n error.message.includes(`Fetch failed with status '${code}'`),\n );\n\n if (\n includesErrorCodeToCatch ||\n error.message.includes('Failed to fetch') ||\n error === TIMEOUT_ERROR\n ) {\n console.error(error);\n } else {\n throw error;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error;\n }\n}\n\n/**\n * Checks if two strings are equal, ignoring case.\n *\n * @param value1 - The first string to compare.\n * @param value2 - The second string to compare.\n * @returns `true` if the strings are equal, ignoring case; otherwise, `false`.\n */\nexport function isEqualCaseInsensitive(\n value1: string,\n value2: string,\n): boolean {\n if (typeof value1 !== 'string' || typeof value2 !== 'string') {\n return false;\n }\n return value1.toLowerCase() === value2.toLowerCase();\n}\n"]} -\ No newline at end of file From 05fd6ef0b5e9c54058f3f6e051a2d17e2fff159d Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Wed, 23 Oct 2024 20:34:37 +0000 Subject: [PATCH 07/50] Update LavaMoat policies --- lavamoat/browserify/beta/policy.json | 8 +------- lavamoat/browserify/flask/policy.json | 8 +------- lavamoat/browserify/main/policy.json | 8 +------- lavamoat/browserify/mmi/policy.json | 8 +------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 86597b9a15fa..970490ac86e2 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -670,13 +670,13 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, - "@metamask/assets-controllers>@metamask/rpc-errors": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, + "@metamask/rpc-errors": true, "@metamask/utils": true, "bn.js": true, "cockatiel": true, @@ -698,12 +698,6 @@ "uuid": true } }, - "@metamask/assets-controllers>@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>fast-safe-stringify": true, - "@metamask/utils": true - } - }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 86597b9a15fa..970490ac86e2 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -670,13 +670,13 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, - "@metamask/assets-controllers>@metamask/rpc-errors": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, + "@metamask/rpc-errors": true, "@metamask/utils": true, "bn.js": true, "cockatiel": true, @@ -698,12 +698,6 @@ "uuid": true } }, - "@metamask/assets-controllers>@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>fast-safe-stringify": true, - "@metamask/utils": true - } - }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 86597b9a15fa..970490ac86e2 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -670,13 +670,13 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, - "@metamask/assets-controllers>@metamask/rpc-errors": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, + "@metamask/rpc-errors": true, "@metamask/utils": true, "bn.js": true, "cockatiel": true, @@ -698,12 +698,6 @@ "uuid": true } }, - "@metamask/assets-controllers>@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>fast-safe-stringify": true, - "@metamask/utils": true - } - }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index db949049605f..8597c66d89f8 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -762,13 +762,13 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, - "@metamask/assets-controllers>@metamask/rpc-errors": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, + "@metamask/rpc-errors": true, "@metamask/utils": true, "bn.js": true, "cockatiel": true, @@ -790,12 +790,6 @@ "uuid": true } }, - "@metamask/assets-controllers>@metamask/rpc-errors": { - "packages": { - "@metamask/rpc-errors>fast-safe-stringify": true, - "@metamask/utils": true - } - }, "@metamask/base-controller": { "globals": { "setTimeout": true From 9dfdfa8b43b9c4e60527ee7c4892c8e4ef3c2792 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 23 Oct 2024 13:48:33 -0700 Subject: [PATCH 08/50] lint --- ui/hooks/useGasFeeEstimates.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/hooks/useGasFeeEstimates.test.js b/ui/hooks/useGasFeeEstimates.test.js index 4243ba37f564..dd63e10581d0 100644 --- a/ui/hooks/useGasFeeEstimates.test.js +++ b/ui/hooks/useGasFeeEstimates.test.js @@ -8,7 +8,6 @@ import { getIsNetworkBusyByChainId, } from '../ducks/metamask/metamask'; import { - gasFeeStartPollingByNetworkClientId, gasFeeStopPollingByPollingToken, getNetworkConfigurationByNetworkClientId, } from '../store/actions'; From 785de28ec185d840408b7bdba9d1cfa67807b080 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 29 Oct 2024 08:31:46 -0700 Subject: [PATCH 09/50] initial multi chain polling for currency and token rates --- app/scripts/metamask-controller.js | 33 ++++---- package.json | 1 + ui/contexts/tokenRates.js | 8 ++ ui/hooks/useCurrencyRatePolling.ts | 46 ++++++++--- ui/hooks/useMultiPolling.ts | 55 +++++++++++++ ui/hooks/useTokenRatesPolling.ts | 30 ++++++++ ui/pages/index.js | 5 +- ui/store/actions.ts | 39 +++++++++- yarn.lock | 119 ++++++++++++++++++----------- 9 files changed, 255 insertions(+), 81 deletions(-) create mode 100644 ui/contexts/tokenRates.js create mode 100644 ui/hooks/useMultiPolling.ts create mode 100644 ui/hooks/useTokenRatesPolling.ts diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 9e2210277406..356f0030ec8b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -874,13 +874,13 @@ export default class MetamaskController extends EventEmitter { messenger: currencyRateMessenger, state: initState.CurrencyController, }); - const initialFetchExchangeRate = - this.currencyRateController.fetchExchangeRate.bind( + const initialFetchMultiExchangeRate = + this.currencyRateController.fetchMultiExchangeRate.bind( this.currencyRateController, ); - this.currencyRateController.fetchExchangeRate = (...args) => { + this.currencyRateController.fetchMultiExchangeRate = (...args) => { if (this.preferencesController.state.useCurrencyRateCheck) { - return initialFetchExchangeRate(...args); + return initialFetchMultiExchangeRate(...args); } return { conversionRate: null, @@ -1004,6 +1004,7 @@ export default class MetamaskController extends EventEmitter { state: initState.TokenRatesController, messenger: tokenRatesMessenger, tokenPricesService: new CodefiTokenPricesServiceV2(), + disabled: !this.preferencesController.state.useCurrencyRateCheck, }); this.controllerMessenger.subscribe( @@ -1012,9 +1013,9 @@ export default class MetamaskController extends EventEmitter { const { useCurrencyRateCheck: prevUseCurrencyRateCheck } = prevState; const { useCurrencyRateCheck: currUseCurrencyRateCheck } = currState; if (currUseCurrencyRateCheck && !prevUseCurrencyRateCheck) { - this.tokenRatesController.start(); + this.tokenRatesController.enable(); } else if (!currUseCurrencyRateCheck && prevUseCurrencyRateCheck) { - this.tokenRatesController.stop(); + this.tokenRatesController.disable(); } }, this.preferencesController.state), ); @@ -2589,12 +2590,6 @@ export default class MetamaskController extends EventEmitter { const preferencesControllerState = this.preferencesController.state; - const { useCurrencyRateCheck } = preferencesControllerState; - - if (useCurrencyRateCheck) { - this.tokenRatesController.start(); - } - if (this.#isTokenListPollingRequired(preferencesControllerState)) { this.tokenListController.start(); } @@ -2607,12 +2602,6 @@ export default class MetamaskController extends EventEmitter { const preferencesControllerState = this.preferencesController.state; - const { useCurrencyRateCheck } = preferencesControllerState; - - if (useCurrencyRateCheck) { - this.tokenRatesController.stop(); - } - if (this.#isTokenListPollingRequired(preferencesControllerState)) { this.tokenListController.stop(); } @@ -3249,6 +3238,7 @@ export default class MetamaskController extends EventEmitter { backup, approvalController, phishingController, + tokenRatesController, // Notification Controllers authenticationController, userStorageController, @@ -4010,6 +4000,13 @@ export default class MetamaskController extends EventEmitter { currencyRateController, ), + tokenRatesStartPolling: + tokenRatesController.startPolling.bind(tokenRatesController), + tokenRatesStopPollingByPollingToken: + tokenRatesController.stopPollingByPollingToken.bind( + tokenRatesController, + ), + // GasFeeController gasFeeStartPollingByNetworkClientId: gasFeeController.startPollingByNetworkClientId.bind(gasFeeController), diff --git a/package.json b/package.json index 118479f5ede0..0d43f2e85521 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/ui/contexts/tokenRates.js b/ui/contexts/tokenRates.js new file mode 100644 index 000000000000..4f788081a68a --- /dev/null +++ b/ui/contexts/tokenRates.js @@ -0,0 +1,8 @@ +import React from 'react'; +import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; + +export const TokenRatesProvider = ({ children }) => { + useTokenRatesPolling(); + + return <>{children}; +}; diff --git a/ui/hooks/useCurrencyRatePolling.ts b/ui/hooks/useCurrencyRatePolling.ts index f9d58620b2b0..fbfa938eee4a 100644 --- a/ui/hooks/useCurrencyRatePolling.ts +++ b/ui/hooks/useCurrencyRatePolling.ts @@ -1,27 +1,49 @@ import { useSelector } from 'react-redux'; import { - getSelectedNetworkClientId, + FALL_BACK_VS_CURRENCY, + TESTNET_TICKER_SYMBOLS, +} from '@metamask/controller-utils'; +import { + getNetworkConfigurationsByChainId, getUseCurrencyRateCheck, } from '../selectors'; import { - currencyRateStartPollingByNetworkClientId, + currencyRateStartPolling, currencyRateStopPollingByPollingToken, } from '../store/actions'; -import { getCompletedOnboarding } from '../ducks/metamask/metamask'; -import usePolling from './usePolling'; +import { + getCompletedOnboarding, +} from '../ducks/metamask/metamask'; +import useMultiPolling from './useMultiPolling'; -const useCurrencyRatePolling = (networkClientId?: string) => { +const useCurrencyRatePolling = () => { const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const completedOnboarding = useSelector(getCompletedOnboarding); - const selectedNetworkClientId = useSelector(getSelectedNetworkClientId); + const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); - usePolling({ - startPolling: (input) => - currencyRateStartPollingByNetworkClientId(input.networkClientId), + const testnetSymbols = Object.values(TESTNET_TICKER_SYMBOLS); + const nativeCurrencies = + useCurrencyRateCheck && completedOnboarding + ? [ + ...new Set( + Object.values(networkConfigurations).map((n) => + // For testnet currencies like 'SepoliaETH', fetch rates for real ETH. + testnetSymbols.includes(n.nativeCurrency) + ? FALL_BACK_VS_CURRENCY + : n.nativeCurrency, + ), + ), + ] + : []; + useMultiPolling({ + startPolling: currencyRateStartPolling, stopPollingByPollingToken: currencyRateStopPollingByPollingToken, - input: { networkClientId: networkClientId ?? selectedNetworkClientId }, - enabled: useCurrencyRateCheck && completedOnboarding, + input: [nativeCurrencies], }); -}; + return { + // TODO: Eventually return currency rates here. UI elements will + // consume them from this hook instead of a selector directly. + } +}; export default useCurrencyRatePolling; diff --git a/ui/hooks/useMultiPolling.ts b/ui/hooks/useMultiPolling.ts new file mode 100644 index 000000000000..16714aa8ee79 --- /dev/null +++ b/ui/hooks/useMultiPolling.ts @@ -0,0 +1,55 @@ +import { useEffect, useRef, useState } from 'react'; + +type UseMultiPollingOptions = { + startPolling: (input: PollingInput) => Promise; + stopPollingByPollingToken: (pollingToken: string) => void; + input: PollingInput[]; +}; + +// Version of ui/hooks/usePolling.ts that supports multiple inputs / polling loops +const useMultiPolling = ( + usePollingOptions: UseMultiPollingOptions, +) => { + const [polls, setPolls] = useState(new Map()); + + useEffect(() => { + // start new polls + for (const input of usePollingOptions.input) { + const key = JSON.stringify(input); + if (!polls.has(key)) { + usePollingOptions + .startPolling(input) + .then((token) => + setPolls((prevPolls) => new Map(prevPolls).set(key, token)), + ); + } + } + + // stop existing polls + for (const [inputKey, token] of polls.entries()) { + const exists = usePollingOptions.input.some( + (i) => inputKey === JSON.stringify(i), + ); + + if (!exists) { + usePollingOptions.stopPollingByPollingToken(token); + setPolls((prevPolls) => { + const newPolls = new Map(prevPolls); + newPolls.delete(inputKey); + return newPolls; + }); + } + } + }, [usePollingOptions.input && JSON.stringify(usePollingOptions.input)]); + + // stop all polling on dismount + useEffect(() => { + return () => { + for (const token of polls.values()) { + usePollingOptions.stopPollingByPollingToken(token); + } + }; + }, []); +}; + +export default useMultiPolling; diff --git a/ui/hooks/useTokenRatesPolling.ts b/ui/hooks/useTokenRatesPolling.ts new file mode 100644 index 000000000000..d4ed101b63b0 --- /dev/null +++ b/ui/hooks/useTokenRatesPolling.ts @@ -0,0 +1,30 @@ +import { useSelector } from 'react-redux'; +import { + getNetworkConfigurationsByChainId, + getUseCurrencyRateCheck, +} from '../selectors'; +import { + tokenRatesStartPolling, + tokenRatesStopPollingByPollingToken, +} from '../store/actions'; +import useMultiPolling from './useMultiPolling'; + +const useTokenRatesPolling = () => { + const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); + const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); + const networkClientIds = Object.values(networkConfigurations).map( + (n) => n.rpcEndpoints[n.defaultRpcEndpointIndex].networkClientId, + ); + useMultiPolling({ + startPolling: tokenRatesStartPolling, + stopPollingByPollingToken: tokenRatesStopPollingByPollingToken, + input: useCurrencyRateCheck ? networkClientIds : [], + }); + + return { + // TODO: Eventually return token rates here. UI elements will + // consume them from this hook instead of a selector directly. + }; +}; + +export default useTokenRatesPolling; diff --git a/ui/pages/index.js b/ui/pages/index.js index 0b1cdcef78cd..c496c2bbaf1c 100644 --- a/ui/pages/index.js +++ b/ui/pages/index.js @@ -11,6 +11,7 @@ import { } from '../contexts/metametrics'; import { MetamaskNotificationsProvider } from '../contexts/metamask-notifications'; import { CurrencyRateProvider } from '../contexts/currencyRate'; +import { TokenRatesProvider } from '../contexts/tokenRates'; import ErrorPage from './error'; import Routes from './routes'; @@ -51,7 +52,9 @@ class Index extends PureComponent { - + + + diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 82054a80f3cd..1023f931743c 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4517,15 +4517,15 @@ export async function removePollingTokenFromAppState(pollingToken: string) { /** * Informs the CurrencyRateController that the UI requires currency rate polling * - * @param networkClientId - unique identifier for the network client + * @param nativeCurrencies * @returns polling token that can be used to stop polling */ -export async function currencyRateStartPollingByNetworkClientId( - networkClientId: string, +export async function currencyRateStartPolling( + nativeCurrencies: string[], ): Promise { const pollingToken = await submitRequestToBackground( 'currencyRateStartPolling', - [{ networkClientId }], + [{ nativeCurrencies }], ); await addPollingTokenToAppState(pollingToken); return pollingToken; @@ -4547,6 +4547,37 @@ export async function currencyRateStopPollingByPollingToken( await removePollingTokenFromAppState(pollingToken); } +/** + * Informs the TokenRatesController that the UI requires token rate polling + * + * @param networkClientId + * @returns polling token that can be used to stop polling + */ +export async function tokenRatesStartPolling( + networkClientId: string, +): Promise { + const pollingToken = await submitRequestToBackground( + 'tokenRatesStartPolling', + [{ networkClientId }], + ); + // todo needed? + await addPollingTokenToAppState(pollingToken); + return pollingToken; +} +/** + * + * @param pollingToken - + */ +export async function tokenRatesStopPollingByPollingToken( + pollingToken: string, +) { + await submitRequestToBackground('tokenRatesStopPollingByPollingToken', [ + pollingToken, + ]); + // todo needed? + await removePollingTokenFromAppState(pollingToken); +} + /** * Informs the GasFeeController that the UI requires gas fee polling * diff --git a/yarn.lock b/yarn.lock index adf890e5aa02..0538f4e7098b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4704,6 +4704,44 @@ __metadata: languageName: node linkType: hard +"@metamask-previews/assets-controllers@npm:39.0.0-preview-1e2accee": + version: 39.0.0-preview-1e2accee + resolution: "@metamask-previews/assets-controllers@npm:39.0.0-preview-1e2accee" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@ethersproject/address": "npm:^5.7.0" + "@ethersproject/bignumber": "npm:^5.7.0" + "@ethersproject/contracts": "npm:^5.7.0" + "@ethersproject/providers": "npm:^5.7.0" + "@metamask/abi-utils": "npm:^2.0.3" + "@metamask/base-controller": "npm:^7.0.1" + "@metamask/contract-metadata": "npm:^2.4.0" + "@metamask/controller-utils": "npm:^11.4.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/metamask-eth-abis": "npm:^3.1.1" + "@metamask/polling-controller": "npm:^11.0.0" + "@metamask/rpc-errors": "npm:^7.0.1" + "@metamask/utils": "npm:^10.0.0" + "@types/bn.js": "npm:^5.1.5" + "@types/uuid": "npm:^8.3.0" + async-mutex: "npm:^0.5.0" + bn.js: "npm:^5.2.1" + cockatiel: "npm:^3.1.2" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + multiformats: "npm:^13.1.0" + single-call-balance-checker-abi: "npm:^1.0.0" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/accounts-controller": ^18.0.0 + "@metamask/approval-controller": ^7.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/network-controller": ^22.0.0 + "@metamask/preferences-controller": ^13.0.0 + checksum: 10/ffe9439aa8fd7dc6c98681073728cb876da4ca565a8fb9076b0c8ba0886588e7cb572460dc149b42a550f277f240488c0b152d240e687520cae7086256d41e3d + languageName: node + linkType: hard + "@metamask/abi-utils@npm:^2.0.2, @metamask/abi-utils@npm:^2.0.3, @metamask/abi-utils@npm:^2.0.4": version: 2.0.4 resolution: "@metamask/abi-utils@npm:2.0.4" @@ -4813,47 +4851,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:39.0.0": - version: 39.0.0 - resolution: "@metamask/assets-controllers@npm:39.0.0" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/address": "npm:^5.7.0" - "@ethersproject/bignumber": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.1" - "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.3.0" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^11.0.0" - "@metamask/rpc-errors": "npm:^7.0.0" - "@metamask/utils": "npm:^9.1.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - multiformats: "npm:^13.1.0" - single-call-balance-checker-abi: "npm:^1.0.0" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/accounts-controller": ^18.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^21.0.0 - "@metamask/preferences-controller": ^13.0.0 - checksum: 10/1fcfbe98fc1d2cf2b3dfef94d4a3c0752cfd9b5e7208196ebc58c34e34cbb47480eaa608979cdcf41abb7f8ce3c4a8ee2f6031793a5b584ce377f2fff3ec6ade - languageName: node - linkType: hard - -"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": - version: 39.0.0 - resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=39.0.0&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": + version: 39.0.0-preview-1e2accee + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=39.0.0-preview-1e2accee&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4863,12 +4863,12 @@ __metadata: "@metamask/abi-utils": "npm:^2.0.3" "@metamask/base-controller": "npm:^7.0.1" "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.3.0" + "@metamask/controller-utils": "npm:^11.4.0" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" "@metamask/polling-controller": "npm:^11.0.0" - "@metamask/rpc-errors": "npm:^7.0.0" - "@metamask/utils": "npm:^9.1.0" + "@metamask/rpc-errors": "npm:^7.0.1" + "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" "@types/uuid": "npm:^8.3.0" async-mutex: "npm:^0.5.0" @@ -4883,9 +4883,9 @@ __metadata: "@metamask/accounts-controller": ^18.0.0 "@metamask/approval-controller": ^7.0.0 "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^21.0.0 + "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/95cbdcf80e46a601118c806ba41113ac2feb18f2518265c4084c0b37d04e7a02ea6fb4ca2ff480905b9f9f4c13e2daaa6ae6bd4d375986396c5ef26ce0d2bed3 + checksum: 10/3a9d8d494710b5c30df916564c6ccb727e05e614ec3c37c5e5127aaab8c46f04fdd84a0ebcb9f244976b76787b7654825c26a67067a6485cc9d2507e931ed289 languageName: node linkType: hard @@ -6111,6 +6111,16 @@ __metadata: languageName: node linkType: hard +"@metamask/rpc-errors@npm:^7.0.1": + version: 7.0.1 + resolution: "@metamask/rpc-errors@npm:7.0.1" + dependencies: + "@metamask/utils": "npm:^10.0.0" + fast-safe-stringify: "npm:^2.0.6" + checksum: 10/819708b4a7d9695ee67fd867d8f94bb5a273b479a242b17bd53c83d1fceec421fc42928f0bb340f4f138ec803dd82ec9659ce7b09a86aedad6a81d5a39ec5c35 + languageName: node + linkType: hard + "@metamask/safe-event-emitter@npm:^3.0.0, @metamask/safe-event-emitter@npm:^3.1.1": version: 3.1.1 resolution: "@metamask/safe-event-emitter@npm:3.1.1" @@ -6502,6 +6512,23 @@ __metadata: languageName: node linkType: hard +"@metamask/utils@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/utils@npm:10.0.0" + dependencies: + "@ethereumjs/tx": "npm:^4.2.0" + "@metamask/superstruct": "npm:^3.1.0" + "@noble/hashes": "npm:^1.3.1" + "@scure/base": "npm:^1.1.3" + "@types/debug": "npm:^4.1.7" + debug: "npm:^4.3.4" + pony-cause: "npm:^2.1.10" + semver: "npm:^7.5.4" + uuid: "npm:^9.0.1" + checksum: 10/9c2e6421f685d8a45145b6026a6f9fd0701eb5a2e8490fc6d18e64c103d5a62097f301cbc797790da52ceb5853bd9f65845c934b00299e69e5e6736c52b32f0f + languageName: node + linkType: hard + "@metamask/utils@npm:^8.1.0, @metamask/utils@npm:^8.2.0, @metamask/utils@npm:^8.3.0": version: 8.5.0 resolution: "@metamask/utils@npm:8.5.0" From f461767a50cbb9644dd2543aa5805c36b398934a Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 29 Oct 2024 11:23:18 -0700 Subject: [PATCH 10/50] fix testnets --- package.json | 2 +- ui/hooks/useCurrencyRatePolling.ts | 19 ++------ yarn.lock | 69 +++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index 0d43f2e85521..292dd00cb8bb 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/ui/hooks/useCurrencyRatePolling.ts b/ui/hooks/useCurrencyRatePolling.ts index fbfa938eee4a..f4fe25488467 100644 --- a/ui/hooks/useCurrencyRatePolling.ts +++ b/ui/hooks/useCurrencyRatePolling.ts @@ -1,8 +1,4 @@ import { useSelector } from 'react-redux'; -import { - FALL_BACK_VS_CURRENCY, - TESTNET_TICKER_SYMBOLS, -} from '@metamask/controller-utils'; import { getNetworkConfigurationsByChainId, getUseCurrencyRateCheck, @@ -11,9 +7,7 @@ import { currencyRateStartPolling, currencyRateStopPollingByPollingToken, } from '../store/actions'; -import { - getCompletedOnboarding, -} from '../ducks/metamask/metamask'; +import { getCompletedOnboarding } from '../ducks/metamask/metamask'; import useMultiPolling from './useMultiPolling'; const useCurrencyRatePolling = () => { @@ -21,20 +15,15 @@ const useCurrencyRatePolling = () => { const completedOnboarding = useSelector(getCompletedOnboarding); const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); - const testnetSymbols = Object.values(TESTNET_TICKER_SYMBOLS); const nativeCurrencies = useCurrencyRateCheck && completedOnboarding ? [ ...new Set( - Object.values(networkConfigurations).map((n) => - // For testnet currencies like 'SepoliaETH', fetch rates for real ETH. - testnetSymbols.includes(n.nativeCurrency) - ? FALL_BACK_VS_CURRENCY - : n.nativeCurrency, - ), + Object.values(networkConfigurations).map((n) => n.nativeCurrency), ), ] : []; + useMultiPolling({ startPolling: currencyRateStartPolling, stopPollingByPollingToken: currencyRateStopPollingByPollingToken, @@ -44,6 +33,6 @@ const useCurrencyRatePolling = () => { return { // TODO: Eventually return currency rates here. UI elements will // consume them from this hook instead of a selector directly. - } + }; }; export default useCurrencyRatePolling; diff --git a/yarn.lock b/yarn.lock index 0538f4e7098b..b0c6999c69c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4704,9 +4704,9 @@ __metadata: languageName: node linkType: hard -"@metamask-previews/assets-controllers@npm:39.0.0-preview-1e2accee": - version: 39.0.0-preview-1e2accee - resolution: "@metamask-previews/assets-controllers@npm:39.0.0-preview-1e2accee" +"@metamask-previews/assets-controllers@npm:40.0.0-preview-c6d939c9": + version: 40.0.0-preview-c6d939c9 + resolution: "@metamask-previews/assets-controllers@npm:40.0.0-preview-c6d939c9" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4714,12 +4714,12 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.1" + "@metamask/base-controller": "npm:^7.0.2" "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.0" + "@metamask/controller-utils": "npm:^11.4.1" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^11.0.0" + "@metamask/polling-controller": "npm:^12.0.0" "@metamask/rpc-errors": "npm:^7.0.1" "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" @@ -4738,7 +4738,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/ffe9439aa8fd7dc6c98681073728cb876da4ca565a8fb9076b0c8ba0886588e7cb572460dc149b42a550f277f240488c0b152d240e687520cae7086256d41e3d + checksum: 10/7a6057c98033238f7f158abc34518f051e30267b8884538b2a83e6c57b56ed5f27acb2b7666904a8b0e9fdb6bc5b92521f7abf2f99d234fc171f00a1ac3d1305 languageName: node linkType: hard @@ -4851,9 +4851,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": - version: 39.0.0-preview-1e2accee - resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A39.0.0-preview-1e2accee#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=39.0.0-preview-1e2accee&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": + version: 40.0.0-preview-c6d939c9 + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=40.0.0-preview-c6d939c9&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4861,12 +4861,12 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.1" + "@metamask/base-controller": "npm:^7.0.2" "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.0" + "@metamask/controller-utils": "npm:^11.4.1" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^11.0.0" + "@metamask/polling-controller": "npm:^12.0.0" "@metamask/rpc-errors": "npm:^7.0.1" "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" @@ -4885,7 +4885,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/3a9d8d494710b5c30df916564c6ccb727e05e614ec3c37c5e5127aaab8c46f04fdd84a0ebcb9f244976b76787b7654825c26a67067a6485cc9d2507e931ed289 + checksum: 10/45d670a1484eea4005c6f7d341ff0c27115c23a39b753b90a0babcf18b3baa9767180590912c4943678f19c63b7821908883fc0ddcdf3c92e9abb3cde4bd31e2 languageName: node linkType: hard @@ -4933,6 +4933,16 @@ __metadata: languageName: node linkType: hard +"@metamask/base-controller@npm:^7.0.2": + version: 7.0.2 + resolution: "@metamask/base-controller@npm:7.0.2" + dependencies: + "@metamask/utils": "npm:^10.0.0" + immer: "npm:^9.0.6" + checksum: 10/6f78ec5af840c9947aa8eac6e402df6469600260d613a92196daefd5b072097a176fe5da1c386f2d36853513254b74140d667d817a12880c46f088e18ff3606a + languageName: node + linkType: hard + "@metamask/bitcoin-wallet-snap@npm:^0.8.1": version: 0.8.1 resolution: "@metamask/bitcoin-wallet-snap@npm:0.8.1" @@ -4983,6 +4993,23 @@ __metadata: languageName: node linkType: hard +"@metamask/controller-utils@npm:^11.4.1": + version: 11.4.1 + resolution: "@metamask/controller-utils@npm:11.4.1" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/ethjs-unit": "npm:^0.3.0" + "@metamask/utils": "npm:^10.0.0" + "@spruceid/siwe-parser": "npm:2.1.0" + "@types/bn.js": "npm:^5.1.5" + bn.js: "npm:^5.2.1" + eth-ens-namehash: "npm:^2.0.8" + fast-deep-equal: "npm:^3.1.3" + checksum: 10/fff4864858ce2072456537c9b51cb4c10d178a27b39ab5af8d6e9595efb59dd043bb49be336d8ac725d1281279db4365855f024329398508658b2b2d3b5bc2a5 + languageName: node + linkType: hard + "@metamask/design-tokens@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/design-tokens@npm:4.0.0" @@ -5918,19 +5945,19 @@ __metadata: languageName: node linkType: hard -"@metamask/polling-controller@npm:^11.0.0": - version: 11.0.0 - resolution: "@metamask/polling-controller@npm:11.0.0" +"@metamask/polling-controller@npm:^12.0.0": + version: 12.0.0 + resolution: "@metamask/polling-controller@npm:12.0.0" dependencies: "@metamask/base-controller": "npm:^7.0.1" - "@metamask/controller-utils": "npm:^11.3.0" - "@metamask/utils": "npm:^9.1.0" + "@metamask/controller-utils": "npm:^11.4.0" + "@metamask/utils": "npm:^10.0.0" "@types/uuid": "npm:^8.3.0" fast-json-stable-stringify: "npm:^2.1.0" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/network-controller": ^21.0.0 - checksum: 10/67b563a5d1ce02dc9c2db25ad4ad1fb9f75d5578cf380cce85176ff2cd136addce612c3982653254647b9d8c535374e93d96abb6e500e42076bf3a524a72e75f + "@metamask/network-controller": ^22.0.0 + checksum: 10/0f96365c9eab06ef60e5f1cd93acce4d6f6d48d41d51dfff1c4776daf7402fd43362d7b45326c5c6a210210b413e0c2b93e63f5feffbdea54025ba536de9fc7b languageName: node linkType: hard From f1da818422fceb7eceb9ca274bae56fe0a6f6586 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 29 Oct 2024 14:29:15 -0700 Subject: [PATCH 11/50] only refetch prices on chains whose tokens changed --- package.json | 2 +- yarn.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 292dd00cb8bb..cc95bbde7647 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index b0c6999c69c9..ffa54e0ac070 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4704,9 +4704,9 @@ __metadata: languageName: node linkType: hard -"@metamask-previews/assets-controllers@npm:40.0.0-preview-c6d939c9": - version: 40.0.0-preview-c6d939c9 - resolution: "@metamask-previews/assets-controllers@npm:40.0.0-preview-c6d939c9" +"@metamask-previews/assets-controllers@npm:40.0.0-preview-fa7d96bb": + version: 40.0.0-preview-fa7d96bb + resolution: "@metamask-previews/assets-controllers@npm:40.0.0-preview-fa7d96bb" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4738,7 +4738,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/7a6057c98033238f7f158abc34518f051e30267b8884538b2a83e6c57b56ed5f27acb2b7666904a8b0e9fdb6bc5b92521f7abf2f99d234fc171f00a1ac3d1305 + checksum: 10/b4ad08d082770e7947b2c0fce3926ab8776394b15079d8b5c3696bb7bb2db9698192580d895dcb45a6d5497f105576acc4e504987a17c19f541e5ba74b93bb7a languageName: node linkType: hard @@ -4851,9 +4851,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": - version: 40.0.0-preview-c6d939c9 - resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-c6d939c9#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=40.0.0-preview-c6d939c9&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": + version: 40.0.0-preview-fa7d96bb + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=40.0.0-preview-fa7d96bb&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4885,7 +4885,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/45d670a1484eea4005c6f7d341ff0c27115c23a39b753b90a0babcf18b3baa9767180590912c4943678f19c63b7821908883fc0ddcdf3c92e9abb3cde4bd31e2 + checksum: 10/f24fe4a422fe68d3df6473611680459cff1651e1eb6d006b90f2e91a6df5a5588aa101eb5f9b2d30e298c499e8e7c71ef69bb95720df13818f5a032702e73d9f languageName: node linkType: hard From 878f407c0d945179c94ded96d4fd15f4d67ac1e2 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 12:45:40 -0700 Subject: [PATCH 12/50] poll multiple native currencies --- ...s-controllers-npm-41.0.0-57b3d695bb.patch} | 0 app/scripts/metamask-controller.js | 8 +- package.json | 2 +- ui/hooks/useCurrencyRatePolling.ts | 19 +++-- ui/store/actions.ts | 8 +- yarn.lock | 76 ++++++++++++------- 6 files changed, 68 insertions(+), 45 deletions(-) rename .yarn/patches/{@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch => @metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch} (100%) diff --git a/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch b/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch similarity index 100% rename from .yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch rename to .yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5eba6f25c12e..f52b45baec94 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -867,13 +867,13 @@ export default class MetamaskController extends EventEmitter { messenger: currencyRateMessenger, state: initState.CurrencyController, }); - const initialFetchExchangeRate = - this.currencyRateController.fetchExchangeRate.bind( + const initialFetchMultiExchangeRate = + this.currencyRateController.fetchMultiExchangeRate.bind( this.currencyRateController, ); - this.currencyRateController.fetchExchangeRate = (...args) => { + this.currencyRateController.fetchMultiExchangeRate = (...args) => { if (this.preferencesController.state.useCurrencyRateCheck) { - return initialFetchExchangeRate(...args); + return initialFetchMultiExchangeRate(...args); } return { conversionRate: null, diff --git a/package.json b/package.json index 43513828d7fe..f19d5b597588 100644 --- a/package.json +++ b/package.json @@ -286,7 +286,7 @@ "@metamask/address-book-controller": "^6.0.0", "@metamask/announcement-controller": "^7.0.0", "@metamask/approval-controller": "^7.0.0", - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", "@metamask/base-controller": "^7.0.0", "@metamask/bitcoin-wallet-snap": "^0.8.2", "@metamask/browser-passworder": "^4.3.0", diff --git a/ui/hooks/useCurrencyRatePolling.ts b/ui/hooks/useCurrencyRatePolling.ts index f9d58620b2b0..e7ad21adedf5 100644 --- a/ui/hooks/useCurrencyRatePolling.ts +++ b/ui/hooks/useCurrencyRatePolling.ts @@ -1,25 +1,30 @@ import { useSelector } from 'react-redux'; import { - getSelectedNetworkClientId, + getNetworkConfigurationsByChainId, getUseCurrencyRateCheck, } from '../selectors'; import { - currencyRateStartPollingByNetworkClientId, + currencyRateStartPolling, currencyRateStopPollingByPollingToken, } from '../store/actions'; import { getCompletedOnboarding } from '../ducks/metamask/metamask'; import usePolling from './usePolling'; -const useCurrencyRatePolling = (networkClientId?: string) => { +const useCurrencyRatePolling = () => { const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const completedOnboarding = useSelector(getCompletedOnboarding); - const selectedNetworkClientId = useSelector(getSelectedNetworkClientId); + const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); + + const nativeCurrencies = [ + ...new Set( + Object.values(networkConfigurations).map((n) => n.nativeCurrency), + ), + ]; usePolling({ - startPolling: (input) => - currencyRateStartPollingByNetworkClientId(input.networkClientId), + startPolling: currencyRateStartPolling, stopPollingByPollingToken: currencyRateStopPollingByPollingToken, - input: { networkClientId: networkClientId ?? selectedNetworkClientId }, + input: nativeCurrencies, enabled: useCurrencyRateCheck && completedOnboarding, }); }; diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 06b892db0b1c..77189e9683af 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4525,15 +4525,15 @@ export async function removePollingTokenFromAppState(pollingToken: string) { /** * Informs the CurrencyRateController that the UI requires currency rate polling * - * @param networkClientId - unique identifier for the network client + * @param nativeCurrencies - An array of native currency symbols * @returns polling token that can be used to stop polling */ -export async function currencyRateStartPollingByNetworkClientId( - networkClientId: string, +export async function currencyRateStartPolling( + nativeCurrencies: string[], ): Promise { const pollingToken = await submitRequestToBackground( 'currencyRateStartPolling', - [{ networkClientId }], + [{ nativeCurrencies }], ); await addPollingTokenToAppState(pollingToken); return pollingToken; diff --git a/yarn.lock b/yarn.lock index 175f874647f6..5b8924e62858 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4772,9 +4772,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:39.0.0": - version: 39.0.0 - resolution: "@metamask/assets-controllers@npm:39.0.0" +"@metamask/assets-controllers@npm:41.0.0": + version: 41.0.0 + resolution: "@metamask/assets-controllers@npm:41.0.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4782,14 +4782,14 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.1" + "@metamask/base-controller": "npm:^7.0.2" "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.3.0" + "@metamask/controller-utils": "npm:^11.4.2" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^11.0.0" - "@metamask/rpc-errors": "npm:^7.0.0" - "@metamask/utils": "npm:^9.1.0" + "@metamask/polling-controller": "npm:^12.0.1" + "@metamask/rpc-errors": "npm:^7.0.1" + "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" "@types/uuid": "npm:^8.3.0" async-mutex: "npm:^0.5.0" @@ -4804,15 +4804,15 @@ __metadata: "@metamask/accounts-controller": ^18.0.0 "@metamask/approval-controller": ^7.0.0 "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^21.0.0 + "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/1fcfbe98fc1d2cf2b3dfef94d4a3c0752cfd9b5e7208196ebc58c34e34cbb47480eaa608979cdcf41abb7f8ce3c4a8ee2f6031793a5b584ce377f2fff3ec6ade + checksum: 10/63f1a9605d692217889511ca161ee614d8e12d7f7233773afb34c4fb6323fad1c29b3a4ee920ef6f84e4b165ffb8764dfd105bdc9bad75084f52a7c876faa4f5 languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": - version: 39.0.0 - resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=39.0.0&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": + version: 41.0.0 + resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4820,14 +4820,14 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.1" + "@metamask/base-controller": "npm:^7.0.2" "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.3.0" + "@metamask/controller-utils": "npm:^11.4.2" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^11.0.0" - "@metamask/rpc-errors": "npm:^7.0.0" - "@metamask/utils": "npm:^9.1.0" + "@metamask/polling-controller": "npm:^12.0.1" + "@metamask/rpc-errors": "npm:^7.0.1" + "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" "@types/uuid": "npm:^8.3.0" async-mutex: "npm:^0.5.0" @@ -4842,9 +4842,9 @@ __metadata: "@metamask/accounts-controller": ^18.0.0 "@metamask/approval-controller": ^7.0.0 "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^21.0.0 + "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/95cbdcf80e46a601118c806ba41113ac2feb18f2518265c4084c0b37d04e7a02ea6fb4ca2ff480905b9f9f4c13e2daaa6ae6bd4d375986396c5ef26ce0d2bed3 + checksum: 10/f7d609be61f4e952abd78d996a44131941f1fcd476066d007bed5047d1c887d38e9e9cf117eeb963148674fd9ad6ae87c8384bc8a21d4281628aaab1b60ce7a8 languageName: node linkType: hard @@ -4942,6 +4942,24 @@ __metadata: languageName: node linkType: hard +"@metamask/controller-utils@npm:^11.4.2": + version: 11.4.2 + resolution: "@metamask/controller-utils@npm:11.4.2" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/ethjs-unit": "npm:^0.3.0" + "@metamask/utils": "npm:^10.0.0" + "@spruceid/siwe-parser": "npm:2.1.0" + "@types/bn.js": "npm:^5.1.5" + bignumber.js: "npm:^9.1.2" + bn.js: "npm:^5.2.1" + eth-ens-namehash: "npm:^2.0.8" + fast-deep-equal: "npm:^3.1.3" + checksum: 10/fdae49ee97e7a2a1bb6414011ca59932f8712a768a9c4c43673a2504c9fa9e61d83df53a21ff0506ef6a8cf774704f2df58a6d71385c8786ec5cab4359c051e1 + languageName: node + linkType: hard + "@metamask/design-tokens@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/design-tokens@npm:4.0.0" @@ -5906,19 +5924,19 @@ __metadata: languageName: node linkType: hard -"@metamask/polling-controller@npm:^11.0.0": - version: 11.0.0 - resolution: "@metamask/polling-controller@npm:11.0.0" +"@metamask/polling-controller@npm:^12.0.1": + version: 12.0.1 + resolution: "@metamask/polling-controller@npm:12.0.1" dependencies: - "@metamask/base-controller": "npm:^7.0.1" - "@metamask/controller-utils": "npm:^11.3.0" - "@metamask/utils": "npm:^9.1.0" + "@metamask/base-controller": "npm:^7.0.2" + "@metamask/controller-utils": "npm:^11.4.2" + "@metamask/utils": "npm:^10.0.0" "@types/uuid": "npm:^8.3.0" fast-json-stable-stringify: "npm:^2.1.0" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/network-controller": ^21.0.0 - checksum: 10/67b563a5d1ce02dc9c2db25ad4ad1fb9f75d5578cf380cce85176ff2cd136addce612c3982653254647b9d8c535374e93d96abb6e500e42076bf3a524a72e75f + "@metamask/network-controller": ^22.0.0 + checksum: 10/eac9ed2fcc9697a2aa55e9746d4eac8d762dd6948b00d77cd2d4894b8c3e1a8e6ed5d0df4d01a69d9a7e2b3c09d9d7c1ffc6f9504023388dd7452d45b5d87065 languageName: node linkType: hard @@ -25934,7 +25952,7 @@ __metadata: "@metamask/announcement-controller": "npm:^7.0.0" "@metamask/api-specs": "npm:^0.9.3" "@metamask/approval-controller": "npm:^7.0.0" - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A39.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch" + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch" "@metamask/auto-changelog": "npm:^2.1.0" "@metamask/base-controller": "npm:^7.0.0" "@metamask/bitcoin-wallet-snap": "npm:^0.8.2" From 074c5fc76683044d3638dd62a7b1375a0093f41e Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 12:54:19 -0700 Subject: [PATCH 13/50] feat: add tokenListStartPolling and tokenListStopPollingByPollingToken actions --- ui/store/actions.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 1023f931743c..e2b9e537fa48 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4578,6 +4578,40 @@ export async function tokenRatesStopPollingByPollingToken( await removePollingTokenFromAppState(pollingToken); } +/** + * Informs the TokenListController that the UI requires tokenlist polling + * + * @param chainId + * @returns polling token that can be used to stop polling + */ +export async function tokenListStartPolling( + chainId: string[], +): Promise { + const pollingToken = await submitRequestToBackground( + 'tokenListStartPolling', + [{ chainId }], + ); + await addPollingTokenToAppState(pollingToken); + return pollingToken; +} + +/** + * Informs the TokenListController that the UI requires tokenlist to stop polling given a specific polling token + * + * @param pollingToken + * @returns polling token that can be used to stop polling + */ +export async function tokenListStopPollingByPollingToken( + pollingToken: string, +): Promise { + const pollingToken = await submitRequestToBackground( + 'tokenListStopPollingByPollingToken', + [pollingToken], + ); + await addPollingTokenToAppState(pollingToken); + return pollingToken; +} + /** * Informs the GasFeeController that the UI requires gas fee polling * From e8a9d6a79113fc14366027548646777f2b990ff2 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 13:02:10 -0700 Subject: [PATCH 14/50] fix test --- ui/selectors/multichain.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/selectors/multichain.test.ts b/ui/selectors/multichain.test.ts index 19fdac1559a7..3097d61f9549 100644 --- a/ui/selectors/multichain.test.ts +++ b/ui/selectors/multichain.test.ts @@ -105,7 +105,7 @@ function getEvmState(chainId: Hex = CHAIN_IDS.MAINNET): TestState { rates: { btc: { conversionDate: 0, - conversionRate: '100000', + conversionRate: 100000, }, }, }, From 245f8d323f41990845788578a091f387a3adcd38 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 13:02:22 -0700 Subject: [PATCH 15/50] yarn dedupe --- yarn.lock | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b8924e62858..dba7bb3b061c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4925,24 +4925,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0, @metamask/controller-utils@npm:^11.4.1": - version: 11.4.1 - resolution: "@metamask/controller-utils@npm:11.4.1" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/ethjs-unit": "npm:^0.3.0" - "@metamask/utils": "npm:^10.0.0" - "@spruceid/siwe-parser": "npm:2.1.0" - "@types/bn.js": "npm:^5.1.5" - bn.js: "npm:^5.2.1" - eth-ens-namehash: "npm:^2.0.8" - fast-deep-equal: "npm:^3.1.3" - checksum: 10/fff4864858ce2072456537c9b51cb4c10d178a27b39ab5af8d6e9595efb59dd043bb49be336d8ac725d1281279db4365855f024329398508658b2b2d3b5bc2a5 - languageName: node - linkType: hard - -"@metamask/controller-utils@npm:^11.4.2": +"@metamask/controller-utils@npm:^11.0.0, @metamask/controller-utils@npm:^11.0.2, @metamask/controller-utils@npm:^11.1.0, @metamask/controller-utils@npm:^11.2.0, @metamask/controller-utils@npm:^11.3.0, @metamask/controller-utils@npm:^11.4.0, @metamask/controller-utils@npm:^11.4.1, @metamask/controller-utils@npm:^11.4.2": version: 11.4.2 resolution: "@metamask/controller-utils@npm:11.4.2" dependencies: From 1afebeeeb5fe1b59572e98dad5181f7b5fb12f1f Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Wed, 30 Oct 2024 20:11:25 +0000 Subject: [PATCH 16/50] Update LavaMoat policies --- lavamoat/browserify/beta/policy.json | 17 ++++++++++++++++- lavamoat/browserify/flask/policy.json | 17 ++++++++++++++++- lavamoat/browserify/main/policy.json | 17 ++++++++++++++++- lavamoat/browserify/mmi/policy.json | 17 ++++++++++++++++- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 09a0999ef6b0..62f8b878ea62 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -674,6 +674,7 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, @@ -681,7 +682,6 @@ "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, "bn.js": true, "cockatiel": true, "ethers>@ethersproject/address": true, @@ -702,6 +702,21 @@ "uuid": true } }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils>@scure/base": true, + "@metamask/utils>pony-cause": true, + "@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true + } + }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 09a0999ef6b0..62f8b878ea62 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -674,6 +674,7 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, @@ -681,7 +682,6 @@ "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, "bn.js": true, "cockatiel": true, "ethers>@ethersproject/address": true, @@ -702,6 +702,21 @@ "uuid": true } }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils>@scure/base": true, + "@metamask/utils>pony-cause": true, + "@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true + } + }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 09a0999ef6b0..62f8b878ea62 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -674,6 +674,7 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, @@ -681,7 +682,6 @@ "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, "bn.js": true, "cockatiel": true, "ethers>@ethersproject/address": true, @@ -702,6 +702,21 @@ "uuid": true } }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils>@scure/base": true, + "@metamask/utils>pony-cause": true, + "@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true + } + }, "@metamask/base-controller": { "globals": { "setTimeout": true diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index b94fc59f9574..466f9573cbd1 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -766,6 +766,7 @@ "@ethersproject/providers": true, "@metamask/abi-utils": true, "@metamask/assets-controllers>@metamask/polling-controller": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, "@metamask/controller-utils": true, @@ -773,7 +774,6 @@ "@metamask/metamask-eth-abis": true, "@metamask/name-controller>async-mutex": true, "@metamask/rpc-errors": true, - "@metamask/utils": true, "bn.js": true, "cockatiel": true, "ethers>@ethersproject/address": true, @@ -794,6 +794,21 @@ "uuid": true } }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/utils>@metamask/superstruct": true, + "@metamask/utils>@scure/base": true, + "@metamask/utils>pony-cause": true, + "@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true + } + }, "@metamask/base-controller": { "globals": { "setTimeout": true From ca590ecac127733554583029537a18564fee93e8 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 14:05:11 -0700 Subject: [PATCH 17/50] fix e2e test mocks --- test/e2e/mock-e2e.js | 8 +++++--- test/e2e/tests/privacy/basic-functionality.spec.js | 4 ++-- test/e2e/tests/settings/localization.spec.js | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index cc49b55f192a..f1bcad82e7c4 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -616,13 +616,15 @@ async function setupMocking( }); await server - .forGet('https://min-api.cryptocompare.com/data/price') - .withQuery({ fsym: 'ETH', tsyms: 'USD' }) + .forGet('https://min-api.cryptocompare.com/data/pricemulti') + .withQuery({ fsyms: 'ETH', tsyms: 'usd' }) .thenCallback(() => { return { statusCode: 200, json: { - USD: ethConversionInUsd, + ETH: { + USD: ethConversionInUsd, + }, }, }; }); diff --git a/test/e2e/tests/privacy/basic-functionality.spec.js b/test/e2e/tests/privacy/basic-functionality.spec.js index 674ba8772e29..a945154f4bd3 100644 --- a/test/e2e/tests/privacy/basic-functionality.spec.js +++ b/test/e2e/tests/privacy/basic-functionality.spec.js @@ -26,8 +26,8 @@ async function mockApis(mockServer) { }; }), await mockServer - .forGet('https://min-api.cryptocompare.com/data/price') - .withQuery({ fsym: 'ETH', tsyms: 'USD' }) + .forGet('https://min-api.cryptocompare.com/data/pricemulti') + .withQuery({ fsyms: 'ETH', tsyms: 'usd' }) .thenCallback(() => { return { statusCode: 200, diff --git a/test/e2e/tests/settings/localization.spec.js b/test/e2e/tests/settings/localization.spec.js index 1fb1e8d1e8a6..229c385efbeb 100644 --- a/test/e2e/tests/settings/localization.spec.js +++ b/test/e2e/tests/settings/localization.spec.js @@ -7,14 +7,16 @@ const FixtureBuilder = require('../../fixture-builder'); async function mockPhpConversion(mockServer) { return await mockServer - .forGet('https://min-api.cryptocompare.com/data/price') - .withQuery({ fsym: 'ETH', tsyms: 'PHP,USD' }) + .forGet('https://min-api.cryptocompare.com/data/pricemulti') + .withQuery({ fsyms: 'ETH', tsyms: 'php,USD' }) .thenCallback(() => { return { statusCode: 200, json: { - PHP: '100000', - USD: '2500', + ETH: { + PHP: '100000', + USD: '2500', + }, }, }; }); From 6321d836c773dc60ac204e8f1f0ea383294e2847 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 14:38:53 -0700 Subject: [PATCH 18/50] feat: Bind new polling methods in metamask state --- app/scripts/metamask-controller.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 356f0030ec8b..9361ecb3373a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -3239,6 +3239,7 @@ export default class MetamaskController extends EventEmitter { approvalController, phishingController, tokenRatesController, + tokenListController, // Notification Controllers authenticationController, userStorageController, @@ -4007,6 +4008,14 @@ export default class MetamaskController extends EventEmitter { tokenRatesController, ), + // TokeListController + tokenListControllerStartPolling: + tokenListController.startPolling.bind(tokenListController), + tokenListStopPollingByPollingToken: + tokenListController.stopPollingByPollingToken.bind(tokenListController), + + // tokenListStopPollingByPollingToken: this. + // GasFeeController gasFeeStartPollingByNetworkClientId: gasFeeController.startPollingByNetworkClientId.bind(gasFeeController), From 0633b8e03141d0284f84b3560faeca264b04d373 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 14:39:16 -0700 Subject: [PATCH 19/50] feat: Introduce useTokenListPolling hook --- ui/hooks/useTokenListPolling.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 ui/hooks/useTokenListPolling.ts diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts new file mode 100644 index 000000000000..42349baffe1f --- /dev/null +++ b/ui/hooks/useTokenListPolling.ts @@ -0,0 +1,25 @@ +import { useSelector } from 'react-redux'; +import { getNetworkConfigurationsByChainId } from '../selectors'; +import { + tokenListStartPolling, + tokenListStopPollingByPollingToken, +} from '../store/actions'; +import useMultiPolling from './useMultiPolling'; + +const useTokenListPolling = () => { + const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); + + const chainIds = Object.keys(networkConfigurations); + + useMultiPolling({ + startPolling: tokenListStartPolling, + stopPollingByPollingToken: tokenListStopPollingByPollingToken, + input: [chainIds], + }); + + return { + // TODO: Eventually return currency rates here. UI elements will + // consume them from this hook instead of a selector directly. + }; +}; +export default useTokenListPolling; From 5a57889d444d34e7e0b69ddea9d617de94a8b0a1 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 14:53:00 -0700 Subject: [PATCH 20/50] chore: Remove chainId from constructor of TokenListController --- app/scripts/metamask-controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 9361ecb3373a..c8e0c3e92e98 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -635,7 +635,6 @@ export default class MetamaskController extends EventEmitter { }); this.tokenListController = new TokenListController({ - chainId: getCurrentChainId({ metamask: this.networkController.state }), preventPollingOnNetworkRestart: !this.#isTokenListPollingRequired( this.preferencesController.state, ), From 70c0db4182f2460903d6ebda0bd0fe78acb7e34c Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 15:10:53 -0700 Subject: [PATCH 21/50] fix e2e test --- test/e2e/mock-e2e.js | 2 +- test/e2e/tests/metrics/errors.spec.js | 2 ++ .../errors-after-init-opt-in-background-state.json | 12 +++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index f1bcad82e7c4..85636fcb9089 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -107,7 +107,7 @@ const privateHostMatchers = [ async function setupMocking( server, testSpecificMock, - { chainId, ethConversionInUsd = '1700' }, + { chainId, ethConversionInUsd = 1700 }, ) { const privacyReport = new Set(); await server.forAnyRequest().thenPassThrough({ diff --git a/test/e2e/tests/metrics/errors.spec.js b/test/e2e/tests/metrics/errors.spec.js index e9fae5d6323c..3b003b044b5a 100644 --- a/test/e2e/tests/metrics/errors.spec.js +++ b/test/e2e/tests/metrics/errors.spec.js @@ -46,6 +46,8 @@ const maskedBackgroundFields = [ 'AppStateController.notificationGasPollTokens', 'AppStateController.popupGasPollTokens', 'CurrencyController.currencyRates.ETH.conversionDate', + 'CurrencyController.currencyRates.LineaETH.conversionDate', + 'CurrencyController.currencyRates.SepoliaETH.conversionDate', ]; const maskedUiFields = maskedBackgroundFields.map(backgroundToUiField); diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index 80ea24c8cc3a..68632bf28077 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -85,6 +85,16 @@ "conversionDate": "number", "conversionRate": 1700, "usdConversionRate": 1700 + }, + "LineaETH": { + "conversionDate": "number", + "conversionRate": 1700, + "usdConversionRate": 1700 + }, + "SepoliaETH": { + "conversionDate": "number", + "conversionRate": 1700, + "usdConversionRate": 1700 } }, "currentCurrency": "usd" @@ -134,7 +144,7 @@ "MultichainBalancesController": { "balances": "object" }, "MultichainRatesController": { "fiatCurrency": "usd", - "rates": { "btc": { "conversionDate": 0, "conversionRate": "0" } }, + "rates": { "btc": { "conversionDate": 0, "conversionRate": 0 } }, "cryptocurrencies": ["btc"] }, "NameController": { "names": "object", "nameSources": "object" }, From 6b7df4d720e651ae28e70b72146633812c37e941 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 15:20:19 -0700 Subject: [PATCH 22/50] . From 4e816c2c52b51030c333c66f638bbdd68529036f Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 15:27:51 -0700 Subject: [PATCH 23/50] lint --- .../errors-after-init-opt-in-background-state.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index 68632bf28077..6d77cd3ae351 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -87,7 +87,7 @@ "usdConversionRate": 1700 }, "LineaETH": { - "conversionDate": "number", + "conversionDate": "number", "conversionRate": 1700, "usdConversionRate": 1700 }, From aaef3775fc5ecece291aa39fcff8d66071cdf232 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 16:10:13 -0700 Subject: [PATCH 24/50] fix e2e test --- .../errors-after-init-opt-in-ui-state.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index 6574204ec2bf..e577bb71a6be 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -54,6 +54,16 @@ "conversionDate": "number", "conversionRate": 1700, "usdConversionRate": 1700 + }, + "LineaETH": { + "conversionDate": "number", + "conversionRate": 1700, + "usdConversionRate": 1700 + }, + "SepoliaETH": { + "conversionDate": "number", + "conversionRate": 1700, + "usdConversionRate": 1700 } }, "connectedStatusPopoverHasBeenShown": true, @@ -187,7 +197,7 @@ "lastFetchedBlockNumbers": "object", "submitHistory": "object", "fiatCurrency": "usd", - "rates": { "btc": { "conversionDate": 0, "conversionRate": "0" } }, + "rates": { "btc": { "conversionDate": 0, "conversionRate": 0 } }, "cryptocurrencies": ["btc"], "snaps": "object", "jobs": "object", From 0450b0412f217179701efe220da46d5f1e165ee1 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 17:53:02 -0700 Subject: [PATCH 25/50] package.json --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 127225e862a2..c448b9663fab 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index 4c3f6fb13bcc..506c0c8902bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4810,9 +4810,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch": +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": version: 40.0.0-preview-fa7d96bb - resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-39.0.0-57b3d695bb.patch::version=40.0.0-preview-fa7d96bb&hash=e14ff8" + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=40.0.0-preview-fa7d96bb&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" From 2e267280690231c9966cf52dbb9a64ae325e5789 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 18:15:59 -0700 Subject: [PATCH 26/50] fix: Update comment --- ui/hooks/useTokenListPolling.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index 42349baffe1f..4e2d3c34a1d2 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -18,7 +18,7 @@ const useTokenListPolling = () => { }); return { - // TODO: Eventually return currency rates here. UI elements will + // TODO: Eventually return token list here. UI elements will // consume them from this hook instead of a selector directly. }; }; From 9d21f84710e5ede1a978b1412e62892e50c39ca9 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 18:21:56 -0700 Subject: [PATCH 27/50] chore: Cleanup --- ui/store/actions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/store/actions.ts b/ui/store/actions.ts index e2b9e537fa48..a149bbd590fb 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4581,15 +4581,15 @@ export async function tokenRatesStopPollingByPollingToken( /** * Informs the TokenListController that the UI requires tokenlist polling * - * @param chainId + * @param chainIds * @returns polling token that can be used to stop polling */ export async function tokenListStartPolling( - chainId: string[], + chainIds: string[], ): Promise { const pollingToken = await submitRequestToBackground( 'tokenListStartPolling', - [{ chainId }], + [{ chainIds }], ); await addPollingTokenToAppState(pollingToken); return pollingToken; From b28d396be13455a3a80cb7acbf4aaee9c9dd5e71 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Wed, 30 Oct 2024 18:22:20 -0700 Subject: [PATCH 28/50] chore: Cleanup --- app/scripts/metamask-controller.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index c8e0c3e92e98..146e999a5512 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -4013,8 +4013,6 @@ export default class MetamaskController extends EventEmitter { tokenListStopPollingByPollingToken: tokenListController.stopPollingByPollingToken.bind(tokenListController), - // tokenListStopPollingByPollingToken: this. - // GasFeeController gasFeeStartPollingByNetworkClientId: gasFeeController.startPollingByNetworkClientId.bind(gasFeeController), From 3ec3574c97802834ae59a21d5e964f50454af3b9 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Thu, 31 Oct 2024 10:19:33 -0700 Subject: [PATCH 29/50] bump controller preview version --- package.json | 2 +- yarn.lock | 84 ++++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index c448b9663fab..deb6110b0207 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@40.0.0-preview-fa7d96bb#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index 1047946c0bc9..9e43888c49c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4663,6 +4663,44 @@ __metadata: languageName: node linkType: hard +"@metamask-previews/assets-controllers@npm:41.0.0-preview-699c6b6a": + version: 41.0.0-preview-699c6b6a + resolution: "@metamask-previews/assets-controllers@npm:41.0.0-preview-699c6b6a" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@ethersproject/address": "npm:^5.7.0" + "@ethersproject/bignumber": "npm:^5.7.0" + "@ethersproject/contracts": "npm:^5.7.0" + "@ethersproject/providers": "npm:^5.7.0" + "@metamask/abi-utils": "npm:^2.0.3" + "@metamask/base-controller": "npm:^7.0.2" + "@metamask/contract-metadata": "npm:^2.4.0" + "@metamask/controller-utils": "npm:^11.4.2" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/metamask-eth-abis": "npm:^3.1.1" + "@metamask/polling-controller": "npm:^12.0.1" + "@metamask/rpc-errors": "npm:^7.0.1" + "@metamask/utils": "npm:^10.0.0" + "@types/bn.js": "npm:^5.1.5" + "@types/uuid": "npm:^8.3.0" + async-mutex: "npm:^0.5.0" + bn.js: "npm:^5.2.1" + cockatiel: "npm:^3.1.2" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + multiformats: "npm:^13.1.0" + single-call-balance-checker-abi: "npm:^1.0.0" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/accounts-controller": ^18.0.0 + "@metamask/approval-controller": ^7.0.0 + "@metamask/keyring-controller": ^17.0.0 + "@metamask/network-controller": ^22.0.0 + "@metamask/preferences-controller": ^13.0.0 + checksum: 10/f4f67269cb369faebf38fc5ed8318b65bfc4e4370506655c1da5f4b7353f99ecf04a33b4d06fc7d9743fc948c30101518206a6a0ed8bebcbe1fab4bf5d6c8dc9 + languageName: node + linkType: hard + "@metamask/abi-utils@npm:^2.0.2, @metamask/abi-utils@npm:^2.0.3, @metamask/abi-utils@npm:^2.0.4": version: 2.0.4 resolution: "@metamask/abi-utils@npm:2.0.4" @@ -4772,47 +4810,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:41.0.0": - version: 41.0.0 - resolution: "@metamask/assets-controllers@npm:41.0.0" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/address": "npm:^5.7.0" - "@ethersproject/bignumber": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.2" - "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.2" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^12.0.1" - "@metamask/rpc-errors": "npm:^7.0.1" - "@metamask/utils": "npm:^10.0.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - multiformats: "npm:^13.1.0" - single-call-balance-checker-abi: "npm:^1.0.0" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/accounts-controller": ^18.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^22.0.0 - "@metamask/preferences-controller": ^13.0.0 - checksum: 10/63f1a9605d692217889511ca161ee614d8e12d7f7233773afb34c4fb6323fad1c29b3a4ee920ef6f84e4b165ffb8764dfd105bdc9bad75084f52a7c876faa4f5 - languageName: node - linkType: hard - -"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": - version: 41.0.0 - resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": + version: 41.0.0-preview-699c6b6a + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0-preview-699c6b6a&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4844,7 +4844,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/f7d609be61f4e952abd78d996a44131941f1fcd476066d007bed5047d1c887d38e9e9cf117eeb963148674fd9ad6ae87c8384bc8a21d4281628aaab1b60ce7a8 + checksum: 10/ace49a17c67c01371a9402db3891d1373a89eeab75e8c1c51cf5186b66c5271734749fa4c4b5ed308796defd104cd053cc75ea83e7c326d2de273a2638f735f0 languageName: node linkType: hard From 7c78314cefce8635dab238c8a1788370c29e2864 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 14:22:33 -0700 Subject: [PATCH 30/50] fix: Provide chainId in contructor of TokenList --- app/scripts/metamask-controller.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 146e999a5512..0a750fe4e79e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -635,6 +635,7 @@ export default class MetamaskController extends EventEmitter { }); this.tokenListController = new TokenListController({ + chainId: getCurrentChainId({ metamask: this.networkController.state }), preventPollingOnNetworkRestart: !this.#isTokenListPollingRequired( this.preferencesController.state, ), @@ -2587,11 +2588,11 @@ export default class MetamaskController extends EventEmitter { this.txController.startIncomingTransactionPolling(); this.tokenDetectionController.enable(); - const preferencesControllerState = this.preferencesController.state; + // const preferencesControllerState = this.preferencesController.state; - if (this.#isTokenListPollingRequired(preferencesControllerState)) { - this.tokenListController.start(); - } + // if (this.#isTokenListPollingRequired(preferencesControllerState)) { + // this.tokenListController.start(); + // } } stopNetworkRequests() { @@ -2599,11 +2600,11 @@ export default class MetamaskController extends EventEmitter { this.txController.stopIncomingTransactionPolling(); this.tokenDetectionController.disable(); - const preferencesControllerState = this.preferencesController.state; + // const preferencesControllerState = this.preferencesController.state; - if (this.#isTokenListPollingRequired(preferencesControllerState)) { - this.tokenListController.stop(); - } + // if (this.#isTokenListPollingRequired(preferencesControllerState)) { + // this.tokenListController.stop(); + // } } resetStates(resetMethods) { From 2a51a23aed0edafdaf683b08a52586229ec7eb84 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 14:23:04 -0700 Subject: [PATCH 31/50] chore: Consider global settings when useTokeListPolling --- ui/hooks/useTokenListPolling.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index 4e2d3c34a1d2..b63106323364 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -1,5 +1,8 @@ import { useSelector } from 'react-redux'; -import { getNetworkConfigurationsByChainId } from '../selectors'; +import { + getNetworkConfigurationsByChainId, + getPreferences, +} from '../selectors'; import { tokenListStartPolling, tokenListStopPollingByPollingToken, @@ -8,14 +11,18 @@ import useMultiPolling from './useMultiPolling'; const useTokenListPolling = () => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); + const { petnamesEnabled, useTokenDetection, useTransactionSimulations } = + useSelector(getPreferences); const chainIds = Object.keys(networkConfigurations); - useMultiPolling({ - startPolling: tokenListStartPolling, - stopPollingByPollingToken: tokenListStopPollingByPollingToken, - input: [chainIds], - }); + if (useTokenDetection || petnamesEnabled || useTransactionSimulations) { + useMultiPolling({ + startPolling: tokenListStartPolling, + stopPollingByPollingToken: tokenListStopPollingByPollingToken, + input: [chainIds], + }); + } return { // TODO: Eventually return token list here. UI elements will From 0557e3fbdbecbefe0c3299fce74380b9202c5bb9 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 14:32:23 -0700 Subject: [PATCH 32/50] fix: actions should only accept a single hook, multiPolling will destructure arry and handle individually enquing polls --- ui/hooks/useTokenListPolling.ts | 5 +++-- ui/store/actions.ts | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index b63106323364..ae32be6761dd 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -8,19 +8,20 @@ import { tokenListStopPollingByPollingToken, } from '../store/actions'; import useMultiPolling from './useMultiPolling'; +import { Hex } from '@metamask/utils'; const useTokenListPolling = () => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); const { petnamesEnabled, useTokenDetection, useTransactionSimulations } = useSelector(getPreferences); - const chainIds = Object.keys(networkConfigurations); + const chainIds = Object.keys(networkConfigurations) as Hex[]; if (useTokenDetection || petnamesEnabled || useTransactionSimulations) { useMultiPolling({ startPolling: tokenListStartPolling, stopPollingByPollingToken: tokenListStopPollingByPollingToken, - input: [chainIds], + input: chainIds, }); } diff --git a/ui/store/actions.ts b/ui/store/actions.ts index a149bbd590fb..1bc8a4335331 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4581,15 +4581,13 @@ export async function tokenRatesStopPollingByPollingToken( /** * Informs the TokenListController that the UI requires tokenlist polling * - * @param chainIds + * @param chainId * @returns polling token that can be used to stop polling */ -export async function tokenListStartPolling( - chainIds: string[], -): Promise { +export async function tokenListStartPolling(chainId: Hex): Promise { const pollingToken = await submitRequestToBackground( 'tokenListStartPolling', - [{ chainIds }], + { chainId }, ); await addPollingTokenToAppState(pollingToken); return pollingToken; @@ -4604,10 +4602,9 @@ export async function tokenListStartPolling( export async function tokenListStopPollingByPollingToken( pollingToken: string, ): Promise { - const pollingToken = await submitRequestToBackground( - 'tokenListStopPollingByPollingToken', - [pollingToken], - ); + await submitRequestToBackground('tokenListStopPollingByPollingToken', [ + pollingToken, + ]); await addPollingTokenToAppState(pollingToken); return pollingToken; } From a216bc92d5fc69ea7dcaf33052e0ad830a5d81a8 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 14:34:38 -0700 Subject: [PATCH 33/50] chore: Remove comments --- app/scripts/metamask-controller.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0a750fe4e79e..fb29326f5b54 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -2587,24 +2587,12 @@ export default class MetamaskController extends EventEmitter { this.accountTrackerController.start(); this.txController.startIncomingTransactionPolling(); this.tokenDetectionController.enable(); - - // const preferencesControllerState = this.preferencesController.state; - - // if (this.#isTokenListPollingRequired(preferencesControllerState)) { - // this.tokenListController.start(); - // } } stopNetworkRequests() { this.accountTrackerController.stop(); this.txController.stopIncomingTransactionPolling(); this.tokenDetectionController.disable(); - - // const preferencesControllerState = this.preferencesController.state; - - // if (this.#isTokenListPollingRequired(preferencesControllerState)) { - // this.tokenListController.stop(); - // } } resetStates(resetMethods) { From 8810e88f435c69ada1817eab5cf0a085b52b48b8 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 14:39:04 -0700 Subject: [PATCH 34/50] chore: Incorporate tokensChainCache selector in useTokenListPolling hook --- ui/hooks/useTokenListPolling.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index ae32be6761dd..bece2f737a76 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -2,6 +2,7 @@ import { useSelector } from 'react-redux'; import { getNetworkConfigurationsByChainId, getPreferences, + selectERC20TokensByChain, } from '../selectors'; import { tokenListStartPolling, @@ -14,6 +15,7 @@ const useTokenListPolling = () => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); const { petnamesEnabled, useTokenDetection, useTransactionSimulations } = useSelector(getPreferences); + const tokensChainsCache = useSelector(selectERC20TokensByChain); const chainIds = Object.keys(networkConfigurations) as Hex[]; @@ -26,8 +28,7 @@ const useTokenListPolling = () => { } return { - // TODO: Eventually return token list here. UI elements will - // consume them from this hook instead of a selector directly. + tokensChainsCache, }; }; export default useTokenListPolling; From 3f772a254da1f4031fca1161bdf1bcf89b374a9d Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 15:04:29 -0700 Subject: [PATCH 35/50] chore: Add tokenList global context --- ui/contexts/tokenList.js | 12 ++++++++++++ ui/pages/index.js | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 ui/contexts/tokenList.js diff --git a/ui/contexts/tokenList.js b/ui/contexts/tokenList.js new file mode 100644 index 000000000000..3eb0bfb0f9f7 --- /dev/null +++ b/ui/contexts/tokenList.js @@ -0,0 +1,12 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import useTokenListPolling from '../hooks/useTokenListPolling'; + +export const TokenRatesProvider = ({ children }) => { + useTokenListPolling(); + + return <>{children}; +}; +TokenRatesProvider.propTypes = { + children: PropTypes.node, +}; diff --git a/ui/pages/index.js b/ui/pages/index.js index c496c2bbaf1c..fcb4a732b8b7 100644 --- a/ui/pages/index.js +++ b/ui/pages/index.js @@ -53,7 +53,9 @@ class Index extends PureComponent { - + + + From 92c22eadcd8d3042897b2d2e6d6ce1b43118762f Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 15:08:10 -0700 Subject: [PATCH 36/50] fix: Correct naming convention in context --- ui/contexts/tokenList.js | 4 ++-- ui/pages/index.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/contexts/tokenList.js b/ui/contexts/tokenList.js index 3eb0bfb0f9f7..ee7bfb4b3e4f 100644 --- a/ui/contexts/tokenList.js +++ b/ui/contexts/tokenList.js @@ -2,11 +2,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import useTokenListPolling from '../hooks/useTokenListPolling'; -export const TokenRatesProvider = ({ children }) => { +export const TokenListProvider = ({ children }) => { useTokenListPolling(); return <>{children}; }; -TokenRatesProvider.propTypes = { +TokenListProvider.propTypes = { children: PropTypes.node, }; diff --git a/ui/pages/index.js b/ui/pages/index.js index fcb4a732b8b7..6dc4d1546e42 100644 --- a/ui/pages/index.js +++ b/ui/pages/index.js @@ -12,6 +12,7 @@ import { import { MetamaskNotificationsProvider } from '../contexts/metamask-notifications'; import { CurrencyRateProvider } from '../contexts/currencyRate'; import { TokenRatesProvider } from '../contexts/tokenRates'; +import { TokenListProvider } from '../contexts/tokenList'; import ErrorPage from './error'; import Routes from './routes'; From fc9a8ea5ba375423679c1f247cadb6846fb0d252 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Thu, 31 Oct 2024 15:54:19 -0700 Subject: [PATCH 37/50] chore: Include tokenList in hook result --- ui/hooks/useTokenListPolling.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index bece2f737a76..dce9a160dcca 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -2,6 +2,7 @@ import { useSelector } from 'react-redux'; import { getNetworkConfigurationsByChainId, getPreferences, + selectERC20Tokens, selectERC20TokensByChain, } from '../selectors'; import { @@ -15,6 +16,7 @@ const useTokenListPolling = () => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); const { petnamesEnabled, useTokenDetection, useTransactionSimulations } = useSelector(getPreferences); + const tokenList = useSelector(selectERC20Tokens); const tokensChainsCache = useSelector(selectERC20TokensByChain); const chainIds = Object.keys(networkConfigurations) as Hex[]; @@ -28,6 +30,7 @@ const useTokenListPolling = () => { } return { + tokenList, tokensChainsCache, }; }; From 0e7a8722bff749bf0fa4bcf9d9a0e808e617c0e7 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 1 Nov 2024 00:31:06 +0100 Subject: [PATCH 38/50] fix: fix lint --- ui/contexts/tokenRates.js | 4 ++++ ui/hooks/useMultiPolling.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/contexts/tokenRates.js b/ui/contexts/tokenRates.js index 4f788081a68a..63ed7ccaa3b1 100644 --- a/ui/contexts/tokenRates.js +++ b/ui/contexts/tokenRates.js @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; export const TokenRatesProvider = ({ children }) => { @@ -6,3 +7,6 @@ export const TokenRatesProvider = ({ children }) => { return <>{children}; }; +TokenRatesProvider.propTypes = { + children: PropTypes.string, +}; diff --git a/ui/hooks/useMultiPolling.ts b/ui/hooks/useMultiPolling.ts index 16714aa8ee79..ec217ec21208 100644 --- a/ui/hooks/useMultiPolling.ts +++ b/ui/hooks/useMultiPolling.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useState } from 'react'; type UseMultiPollingOptions = { startPolling: (input: PollingInput) => Promise; From ea95acac4dba2be0fc2ed30cfa0b6b4826dd2245 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 1 Nov 2024 00:42:50 +0100 Subject: [PATCH 39/50] fix: update js file to tsx --- ui/contexts/tokenRates.js | 12 ------------ ui/contexts/tokenRates.tsx | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 ui/contexts/tokenRates.js create mode 100644 ui/contexts/tokenRates.tsx diff --git a/ui/contexts/tokenRates.js b/ui/contexts/tokenRates.js deleted file mode 100644 index 63ed7ccaa3b1..000000000000 --- a/ui/contexts/tokenRates.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; - -export const TokenRatesProvider = ({ children }) => { - useTokenRatesPolling(); - - return <>{children}; -}; -TokenRatesProvider.propTypes = { - children: PropTypes.string, -}; diff --git a/ui/contexts/tokenRates.tsx b/ui/contexts/tokenRates.tsx new file mode 100644 index 000000000000..d5df4b750ff9 --- /dev/null +++ b/ui/contexts/tokenRates.tsx @@ -0,0 +1,12 @@ +import React, { ReactElement } from 'react'; +import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; + +export const TokenRatesProvider = ({ + children, +}: { + children: ReactElement; +}) => { + useTokenRatesPolling(); + + return <>{children}; +}; From bb1f2786499d42a0982b66d3248d9e353061875e Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Fri, 1 Nov 2024 10:15:25 -0700 Subject: [PATCH 40/50] make polling input a chain id --- package.json | 2 +- ui/hooks/useTokenRatesPolling.ts | 7 +++---- ui/store/actions.ts | 8 +++----- yarn.lock | 16 ++++++++-------- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 870331ecc7bd..24ed7ad53ceb 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/ui/hooks/useTokenRatesPolling.ts b/ui/hooks/useTokenRatesPolling.ts index d4ed101b63b0..eafdd81e427a 100644 --- a/ui/hooks/useTokenRatesPolling.ts +++ b/ui/hooks/useTokenRatesPolling.ts @@ -12,13 +12,12 @@ import useMultiPolling from './useMultiPolling'; const useTokenRatesPolling = () => { const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); - const networkClientIds = Object.values(networkConfigurations).map( - (n) => n.rpcEndpoints[n.defaultRpcEndpointIndex].networkClientId, - ); + const chainIds = Object.keys(networkConfigurations); + useMultiPolling({ startPolling: tokenRatesStartPolling, stopPollingByPollingToken: tokenRatesStopPollingByPollingToken, - input: useCurrencyRateCheck ? networkClientIds : [], + input: useCurrencyRateCheck ? chainIds : [], }); return { diff --git a/ui/store/actions.ts b/ui/store/actions.ts index f6a14721f086..0264f0df5353 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4558,15 +4558,13 @@ export async function currencyRateStopPollingByPollingToken( /** * Informs the TokenRatesController that the UI requires token rate polling * - * @param networkClientId + * @param chainId - The chain id to poll token rates on. * @returns polling token that can be used to stop polling */ -export async function tokenRatesStartPolling( - networkClientId: string, -): Promise { +export async function tokenRatesStartPolling(chainId: string): Promise { const pollingToken = await submitRequestToBackground( 'tokenRatesStartPolling', - [{ networkClientId }], + [{ chainId }], ); // todo needed? await addPollingTokenToAppState(pollingToken); diff --git a/yarn.lock b/yarn.lock index c2d7491b581d..172ca71b33fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4663,9 +4663,9 @@ __metadata: languageName: node linkType: hard -"@metamask-previews/assets-controllers@npm:41.0.0-preview-699c6b6a": - version: 41.0.0-preview-699c6b6a - resolution: "@metamask-previews/assets-controllers@npm:41.0.0-preview-699c6b6a" +"@metamask-previews/assets-controllers@npm:41.0.0-preview-db2c53b": + version: 41.0.0-preview-db2c53b + resolution: "@metamask-previews/assets-controllers@npm:41.0.0-preview-db2c53b" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4697,7 +4697,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/f4f67269cb369faebf38fc5ed8318b65bfc4e4370506655c1da5f4b7353f99ecf04a33b4d06fc7d9743fc948c30101518206a6a0ed8bebcbe1fab4bf5d6c8dc9 + checksum: 10/e2cd6586c1deb1c7f1f2afdd5e681b27126bc23e94da8fad936bcab97ec43a9dcea042d07851192f90ab9ca5283dd775808d19391ba5659564191267e52d5189 languageName: node linkType: hard @@ -4810,9 +4810,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": - version: 41.0.0-preview-699c6b6a - resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A41.0.0-preview-699c6b6a#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0-preview-699c6b6a&hash=e14ff8" +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": + version: 41.0.0-preview-db2c53b + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0-preview-db2c53b&hash=e14ff8" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4844,7 +4844,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/ace49a17c67c01371a9402db3891d1373a89eeab75e8c1c51cf5186b66c5271734749fa4c4b5ed308796defd104cd053cc75ea83e7c326d2de273a2638f735f0 + checksum: 10/1b3d04626e1ff712daa47e135fa0533556c076803af0ad45f9bae62882120661068700dfcadc3aa17d90a37bbbac6ae2b856056ea01413d8d01956b1d3e01bcb languageName: node linkType: hard From 0af4924332b0fae2bdfa0a16e2e39740a2afe05e Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Fri, 1 Nov 2024 12:16:08 -0700 Subject: [PATCH 41/50] fix: Correctly bind controller method to action --- app/scripts/metamask-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index fb29326f5b54..9fedf4a7925e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -3997,7 +3997,7 @@ export default class MetamaskController extends EventEmitter { ), // TokeListController - tokenListControllerStartPolling: + tokenListStartPolling: tokenListController.startPolling.bind(tokenListController), tokenListStopPollingByPollingToken: tokenListController.stopPollingByPollingToken.bind(tokenListController), From 090390f1e5becebe7580550eedfc2808ad290e3f Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Fri, 1 Nov 2024 12:17:27 -0700 Subject: [PATCH 42/50] fix: Correct usage of tokenListStartPolling action --- ui/store/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 1bc8a4335331..365dc3fc9b35 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4587,7 +4587,7 @@ export async function tokenRatesStopPollingByPollingToken( export async function tokenListStartPolling(chainId: Hex): Promise { const pollingToken = await submitRequestToBackground( 'tokenListStartPolling', - { chainId }, + [{ chainId }], ); await addPollingTokenToAppState(pollingToken); return pollingToken; From a02d77299e1ecc1c71f81e5e0001beb95c5b4940 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Fri, 1 Nov 2024 14:39:41 -0700 Subject: [PATCH 43/50] fix: Remove action should remove polling token from AppState --- ui/store/actions.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 365dc3fc9b35..2c943e7fbf50 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4605,8 +4605,7 @@ export async function tokenListStopPollingByPollingToken( await submitRequestToBackground('tokenListStopPollingByPollingToken', [ pollingToken, ]); - await addPollingTokenToAppState(pollingToken); - return pollingToken; + await removePollingTokenFromAppState(pollingToken); } /** From 90bd51c1a51519c0c786fe10bc8a4ea8d7bff73e Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 10:02:40 -0800 Subject: [PATCH 44/50] fix: Missed unresolved merge conflict --- app/scripts/metamask-controller.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 637701fb412d..0ee40fbe281a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -2588,30 +2588,12 @@ export default class MetamaskController extends EventEmitter { this.accountTrackerController.start(); this.txController.startIncomingTransactionPolling(); this.tokenDetectionController.enable(); -<<<<<<< HEAD -======= - - const preferencesControllerState = this.preferencesController.state; - - if (this.#isTokenListPollingRequired(preferencesControllerState)) { - this.tokenListController.start(); - } ->>>>>>> develop } stopNetworkRequests() { this.accountTrackerController.stop(); this.txController.stopIncomingTransactionPolling(); this.tokenDetectionController.disable(); -<<<<<<< HEAD -======= - - const preferencesControllerState = this.preferencesController.state; - - if (this.#isTokenListPollingRequired(preferencesControllerState)) { - this.tokenListController.stop(); - } ->>>>>>> develop } resetStates(resetMethods) { @@ -3246,10 +3228,7 @@ export default class MetamaskController extends EventEmitter { approvalController, phishingController, tokenRatesController, -<<<<<<< HEAD tokenListController, -======= ->>>>>>> develop // Notification Controllers authenticationController, userStorageController, From b7e9327c521f9e52a753f50a22ce0b4cf2005150 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 10:47:32 -0800 Subject: [PATCH 45/50] fix: Leverage preview build of core --- package.json | 2 +- yarn.lock | 218 +++------------------------------------------------ 2 files changed, 10 insertions(+), 210 deletions(-) diff --git a/package.json b/package.json index 2d30b08b9b3b..5476414c9a28 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask-previews/assets-controllers@41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch", + "@metamask/assets-controllers": "npm:@metamask-previews/assets-controllers@42.0.0-preview-3399c81f", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/yarn.lock b/yarn.lock index bd840cd2271b..8a571cf34516 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,9 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + __metadata: version: 8 - cacheKey: merged + cacheKey: 10 "@aashutoshrathi/word-wrap@npm:^1.2.3": version: 1.2.6 @@ -1921,7 +1924,6 @@ __metadata: "@esbuild/aix-ppc64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/aix-ppc64@npm:0.19.12" - checksum: 10/undefined conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -1929,7 +1931,6 @@ __metadata: "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" - checksum: 10/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -1937,7 +1938,6 @@ __metadata: "@esbuild/android-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-arm64@npm:0.19.12" - checksum: 10/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -1945,7 +1945,6 @@ __metadata: "@esbuild/android-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm@npm:0.18.20" - checksum: 10/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -1953,7 +1952,6 @@ __metadata: "@esbuild/android-arm@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-arm@npm:0.19.12" - checksum: 10/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -1961,7 +1959,6 @@ __metadata: "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -1969,7 +1966,6 @@ __metadata: "@esbuild/android-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -1977,7 +1973,6 @@ __metadata: "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -1985,7 +1980,6 @@ __metadata: "@esbuild/darwin-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-arm64@npm:0.19.12" - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -1993,7 +1987,6 @@ __metadata: "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2001,7 +1994,6 @@ __metadata: "@esbuild/darwin-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2009,7 +2001,6 @@ __metadata: "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" - checksum: 10/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2017,7 +2008,6 @@ __metadata: "@esbuild/freebsd-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - checksum: 10/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2025,7 +2015,6 @@ __metadata: "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2033,7 +2022,6 @@ __metadata: "@esbuild/freebsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2041,7 +2029,6 @@ __metadata: "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2049,7 +2036,6 @@ __metadata: "@esbuild/linux-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm64@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2057,7 +2043,6 @@ __metadata: "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2065,7 +2050,6 @@ __metadata: "@esbuild/linux-arm@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2073,7 +2057,6 @@ __metadata: "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2081,7 +2064,6 @@ __metadata: "@esbuild/linux-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ia32@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2089,7 +2071,6 @@ __metadata: "@esbuild/linux-loong64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-loong64@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2097,7 +2078,6 @@ __metadata: "@esbuild/linux-loong64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-loong64@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2105,7 +2085,6 @@ __metadata: "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2113,7 +2092,6 @@ __metadata: "@esbuild/linux-mips64el@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-mips64el@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2121,7 +2099,6 @@ __metadata: "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2129,7 +2106,6 @@ __metadata: "@esbuild/linux-ppc64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ppc64@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2137,7 +2113,6 @@ __metadata: "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2145,7 +2120,6 @@ __metadata: "@esbuild/linux-riscv64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-riscv64@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2153,7 +2127,6 @@ __metadata: "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2161,7 +2134,6 @@ __metadata: "@esbuild/linux-s390x@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-s390x@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2169,7 +2141,6 @@ __metadata: "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2177,7 +2148,6 @@ __metadata: "@esbuild/linux-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2185,7 +2155,6 @@ __metadata: "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2193,7 +2162,6 @@ __metadata: "@esbuild/netbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/netbsd-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2201,7 +2169,6 @@ __metadata: "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2209,7 +2176,6 @@ __metadata: "@esbuild/openbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/openbsd-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2217,7 +2183,6 @@ __metadata: "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2225,7 +2190,6 @@ __metadata: "@esbuild/sunos-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/sunos-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2233,7 +2197,6 @@ __metadata: "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" - checksum: 10/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2241,7 +2204,6 @@ __metadata: "@esbuild/win32-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-arm64@npm:0.19.12" - checksum: 10/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2249,7 +2211,6 @@ __metadata: "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" - checksum: 10/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2257,7 +2218,6 @@ __metadata: "@esbuild/win32-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-ia32@npm:0.19.12" - checksum: 10/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2265,7 +2225,6 @@ __metadata: "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" - checksum: 10/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2273,7 +2232,6 @@ __metadata: "@esbuild/win32-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-x64@npm:0.19.12" - checksum: 10/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4368,7 +4326,6 @@ __metadata: "@lydell/node-pty-darwin-arm64@npm:1.0.1": version: 1.0.1 resolution: "@lydell/node-pty-darwin-arm64@npm:1.0.1" - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -4376,7 +4333,6 @@ __metadata: "@lydell/node-pty-darwin-x64@npm:1.0.1": version: 1.0.1 resolution: "@lydell/node-pty-darwin-x64@npm:1.0.1" - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -4384,7 +4340,6 @@ __metadata: "@lydell/node-pty-linux-x64@npm:1.0.1": version: 1.0.1 resolution: "@lydell/node-pty-linux-x64@npm:1.0.1" - checksum: 10/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -4392,7 +4347,6 @@ __metadata: "@lydell/node-pty-win32-arm64@npm:1.0.1": version: 1.0.1 resolution: "@lydell/node-pty-win32-arm64@npm:1.0.1" - checksum: 10/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -4400,7 +4354,6 @@ __metadata: "@lydell/node-pty-win32-x64@npm:1.0.1": version: 1.0.1 resolution: "@lydell/node-pty-win32-x64@npm:1.0.1" - checksum: 10/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4710,44 +4663,6 @@ __metadata: languageName: node linkType: hard -"@metamask-previews/assets-controllers@npm:41.0.0-preview-db2c53b": - version: 41.0.0-preview-db2c53b - resolution: "@metamask-previews/assets-controllers@npm:41.0.0-preview-db2c53b" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/address": "npm:^5.7.0" - "@ethersproject/bignumber": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.2" - "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.2" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^12.0.1" - "@metamask/rpc-errors": "npm:^7.0.1" - "@metamask/utils": "npm:^10.0.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - multiformats: "npm:^13.1.0" - single-call-balance-checker-abi: "npm:^1.0.0" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/accounts-controller": ^18.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^22.0.0 - "@metamask/preferences-controller": ^13.0.0 - checksum: 10/e2cd6586c1deb1c7f1f2afdd5e681b27126bc23e94da8fad936bcab97ec43a9dcea042d07851192f90ab9ca5283dd775808d19391ba5659564191267e52d5189 - languageName: node - linkType: hard - "@metamask/abi-utils@npm:^2.0.2, @metamask/abi-utils@npm:^2.0.3, @metamask/abi-utils@npm:^2.0.4": version: 2.0.4 resolution: "@metamask/abi-utils@npm:2.0.4" @@ -4857,85 +4772,9 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:42.0.0": - version: 42.0.0 - resolution: "@metamask/assets-controllers@npm:42.0.0" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/address": "npm:^5.7.0" - "@ethersproject/bignumber": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.2" - "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.2" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^12.0.1" - "@metamask/rpc-errors": "npm:^7.0.1" - "@metamask/utils": "npm:^10.0.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - multiformats: "npm:^13.1.0" - single-call-balance-checker-abi: "npm:^1.0.0" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/accounts-controller": ^18.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^22.0.0 - "@metamask/preferences-controller": ^13.0.0 - checksum: 10/64d2bd43139ee5c19bd665b07212cd5d5dd41b457dedde3b5db31442292c4d064dc015011f5f001bb423683675fb20898ff652e91d2339ad1d21cc45fa93487a - languageName: node - linkType: hard - -"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch": - version: 41.0.0-preview-db2c53b - resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A41.0.0-preview-db2c53b#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch::version=41.0.0-preview-db2c53b&hash=e14ff8" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@ethersproject/address": "npm:^5.7.0" - "@ethersproject/bignumber": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/base-controller": "npm:^7.0.2" - "@metamask/contract-metadata": "npm:^2.4.0" - "@metamask/controller-utils": "npm:^11.4.2" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/polling-controller": "npm:^12.0.1" - "@metamask/rpc-errors": "npm:^7.0.1" - "@metamask/utils": "npm:^10.0.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - async-mutex: "npm:^0.5.0" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - multiformats: "npm:^13.1.0" - single-call-balance-checker-abi: "npm:^1.0.0" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/accounts-controller": ^18.0.0 - "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^17.0.0 - "@metamask/network-controller": ^22.0.0 - "@metamask/preferences-controller": ^13.0.0 - checksum: 10/1b3d04626e1ff712daa47e135fa0533556c076803af0ad45f9bae62882120661068700dfcadc3aa17d90a37bbbac6ae2b856056ea01413d8d01956b1d3e01bcb - languageName: node - linkType: hard - -"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A42.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch": - version: 42.0.0 - resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A42.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch::version=42.0.0&hash=e14ff8" +"@metamask/assets-controllers@npm:@metamask-previews/assets-controllers@42.0.0-preview-3399c81f": + version: 42.0.0-preview-3399c81f + resolution: "@metamask-previews/assets-controllers@npm:42.0.0-preview-3399c81f" dependencies: "@ethereumjs/util": "npm:^8.1.0" "@ethersproject/address": "npm:^5.7.0" @@ -4967,7 +4806,7 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/9a6727b28f88fd2df3f4b1628dd5d8c2f3e73fd4b9cd090f22d175c2522faa6c6b7e9a93d0ec2b2d123a263c8f4116fbfe97f196b99401b28ac8597f522651eb + checksum: 10/d295c3e8489064d8a3c17e68739c390d4e667c81e7aed91445b4a1ef00b24994f7fbfde997d106aa16930ffd3cf409db8baf326808b0ed1fe3adf623336ae400 languageName: node linkType: hard @@ -9376,7 +9215,6 @@ __metadata: "@swc/core-darwin-arm64@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-darwin-arm64@npm:1.4.11" - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -9384,7 +9222,6 @@ __metadata: "@swc/core-darwin-arm64@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-darwin-arm64@npm:1.5.7" - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -9392,7 +9229,6 @@ __metadata: "@swc/core-darwin-x64@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-darwin-x64@npm:1.4.11" - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -9400,7 +9236,6 @@ __metadata: "@swc/core-darwin-x64@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-darwin-x64@npm:1.5.7" - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -9408,7 +9243,6 @@ __metadata: "@swc/core-linux-arm-gnueabihf@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.11" - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -9416,7 +9250,6 @@ __metadata: "@swc/core-linux-arm-gnueabihf@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.7" - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -9424,7 +9257,6 @@ __metadata: "@swc/core-linux-arm64-gnu@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-linux-arm64-gnu@npm:1.4.11" - checksum: 10/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -9432,7 +9264,6 @@ __metadata: "@swc/core-linux-arm64-gnu@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-linux-arm64-gnu@npm:1.5.7" - checksum: 10/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -9440,7 +9271,6 @@ __metadata: "@swc/core-linux-arm64-musl@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-linux-arm64-musl@npm:1.4.11" - checksum: 10/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -9448,7 +9278,6 @@ __metadata: "@swc/core-linux-arm64-musl@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-linux-arm64-musl@npm:1.5.7" - checksum: 10/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -9456,7 +9285,6 @@ __metadata: "@swc/core-linux-x64-gnu@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-linux-x64-gnu@npm:1.4.11" - checksum: 10/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -9464,7 +9292,6 @@ __metadata: "@swc/core-linux-x64-gnu@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-linux-x64-gnu@npm:1.5.7" - checksum: 10/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -9472,7 +9299,6 @@ __metadata: "@swc/core-linux-x64-musl@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-linux-x64-musl@npm:1.4.11" - checksum: 10/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -9480,7 +9306,6 @@ __metadata: "@swc/core-linux-x64-musl@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-linux-x64-musl@npm:1.5.7" - checksum: 10/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -9488,7 +9313,6 @@ __metadata: "@swc/core-win32-arm64-msvc@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-win32-arm64-msvc@npm:1.4.11" - checksum: 10/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -9496,7 +9320,6 @@ __metadata: "@swc/core-win32-arm64-msvc@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-win32-arm64-msvc@npm:1.5.7" - checksum: 10/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -9504,7 +9327,6 @@ __metadata: "@swc/core-win32-ia32-msvc@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-win32-ia32-msvc@npm:1.4.11" - checksum: 10/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -9512,7 +9334,6 @@ __metadata: "@swc/core-win32-ia32-msvc@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-win32-ia32-msvc@npm:1.5.7" - checksum: 10/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -9520,7 +9341,6 @@ __metadata: "@swc/core-win32-x64-msvc@npm:1.4.11": version: 1.4.11 resolution: "@swc/core-win32-x64-msvc@npm:1.4.11" - checksum: 10/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9528,7 +9348,6 @@ __metadata: "@swc/core-win32-x64-msvc@npm:1.5.7": version: 1.5.7 resolution: "@swc/core-win32-x64-msvc@npm:1.5.7" - checksum: 10/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -20323,7 +20142,6 @@ __metadata: resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" dependencies: node-gyp: "npm:latest" - checksum: 10/undefined conditions: os=darwin languageName: node linkType: hard @@ -20333,7 +20151,6 @@ __metadata: resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: node-gyp: "npm:latest" - checksum: 10/undefined conditions: os=darwin languageName: node linkType: hard @@ -26542,7 +26359,7 @@ __metadata: "@metamask/announcement-controller": "npm:^7.0.0" "@metamask/api-specs": "npm:^0.9.3" "@metamask/approval-controller": "npm:^7.0.0" - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A41.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch" + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A42.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch" "@metamask/auto-changelog": "npm:^2.1.0" "@metamask/base-controller": "npm:^7.0.0" "@metamask/bitcoin-wallet-snap": "npm:^0.8.2" @@ -26912,7 +26729,6 @@ __metadata: yargs: "npm:^17.7.2" yargs-parser: "npm:^21.1.1" zxcvbn: "npm:^4.4.2" - checksum: 10/undefined languageName: unknown linkType: soft @@ -32832,7 +32648,6 @@ __metadata: resolution: "sass-embedded-android-arm64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -32842,7 +32657,6 @@ __metadata: resolution: "sass-embedded-android-arm@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -32852,7 +32666,6 @@ __metadata: resolution: "sass-embedded-android-ia32@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=android & cpu=ia32 languageName: node linkType: hard @@ -32862,7 +32675,6 @@ __metadata: resolution: "sass-embedded-android-x64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -32872,7 +32684,6 @@ __metadata: resolution: "sass-embedded-darwin-arm64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -32882,7 +32693,6 @@ __metadata: resolution: "sass-embedded-darwin-x64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -32892,7 +32702,6 @@ __metadata: resolution: "sass-embedded-linux-arm64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -32902,7 +32711,6 @@ __metadata: resolution: "sass-embedded-linux-arm@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -32912,7 +32720,6 @@ __metadata: resolution: "sass-embedded-linux-ia32@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -32920,7 +32727,6 @@ __metadata: "sass-embedded-linux-musl-arm64@npm:1.71.0": version: 1.71.0 resolution: "sass-embedded-linux-musl-arm64@npm:1.71.0" - checksum: 10/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -32928,7 +32734,6 @@ __metadata: "sass-embedded-linux-musl-arm@npm:1.71.0": version: 1.71.0 resolution: "sass-embedded-linux-musl-arm@npm:1.71.0" - checksum: 10/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -32936,7 +32741,6 @@ __metadata: "sass-embedded-linux-musl-ia32@npm:1.71.0": version: 1.71.0 resolution: "sass-embedded-linux-musl-ia32@npm:1.71.0" - checksum: 10/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -32944,7 +32748,6 @@ __metadata: "sass-embedded-linux-musl-x64@npm:1.71.0": version: 1.71.0 resolution: "sass-embedded-linux-musl-x64@npm:1.71.0" - checksum: 10/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -32954,7 +32757,6 @@ __metadata: resolution: "sass-embedded-linux-x64@npm:1.71.0" bin: sass: dart-sass/sass - checksum: 10/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -32964,7 +32766,6 @@ __metadata: resolution: "sass-embedded-win32-ia32@npm:1.71.0" bin: sass: dart-sass/sass.bat - checksum: 10/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -32974,7 +32775,6 @@ __metadata: resolution: "sass-embedded-win32-x64@npm:1.71.0" bin: sass: dart-sass/sass.bat - checksum: 10/undefined conditions: os=win32 & (cpu=arm64 | cpu=x64) languageName: node linkType: hard From 731baa28f39f183e7ec5054731bc20849b25f161 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 11:19:07 -0800 Subject: [PATCH 46/50] fix: Update fixture builder to include tokenChainsCache --- .../errors-after-init-opt-in-background-state.json | 8 +++++++- .../errors-after-init-opt-in-ui-state.json | 8 +++++++- test/integration/data/onboarding-completion-route.json | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index 6d77cd3ae351..311c4645be00 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -311,7 +311,13 @@ }, "TokenListController": { "tokenList": "object", - "tokensChainsCache": {}, + "tokensChainsCache": { + "0x1": "object", + "0x539": "object", + "0xaa36a7": "object", + "0xe705": "object", + "0xe708": "object" + }, "preventPollingOnNetworkRestart": false }, "TokenRatesController": { "marketData": "object" }, diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index e577bb71a6be..3160f927c819 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -173,7 +173,13 @@ "gasEstimateType": "none", "nonRPCGasFeeApisDisabled": "boolean", "tokenList": "object", - "tokensChainsCache": {}, + "tokensChainsCache": { + "0x1": "object", + "0x539": "object", + "0xaa36a7": "object", + "0xe705": "object", + "0xe708": "object" + }, "preventPollingOnNetworkRestart": false, "tokens": "object", "ignoredTokens": "object", diff --git a/test/integration/data/onboarding-completion-route.json b/test/integration/data/onboarding-completion-route.json index e47d1379b2eb..f07d5a8d4c9d 100644 --- a/test/integration/data/onboarding-completion-route.json +++ b/test/integration/data/onboarding-completion-route.json @@ -435,7 +435,13 @@ "theme": "os", "tokenList": {}, "tokens": [], - "tokensChainsCache": {}, + "tokensChainsCache": { + "0x1": "object", + "0x539": "object", + "0xaa36a7": "object", + "0xe705": "object", + "0xe708": "object" + }, "traits": {}, "transactions": [], "trezorModel": null, From c404ccb5c063770b141f917409be81b6654453f3 Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Mon, 4 Nov 2024 20:17:48 +0000 Subject: [PATCH 47/50] Update LavaMoat policies --- lavamoat/browserify/beta/policy.json | 2 +- lavamoat/browserify/flask/policy.json | 2 +- lavamoat/browserify/main/policy.json | 2 +- lavamoat/browserify/mmi/policy.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index ac719964d896..126b6b1db5f2 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -660,6 +660,7 @@ "Headers": true, "URL": true, "URLSearchParams": true, + "__import__": true, "clearInterval": true, "clearTimeout": true, "console.error": true, @@ -668,7 +669,6 @@ "setTimeout": true }, "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index ac719964d896..126b6b1db5f2 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -660,6 +660,7 @@ "Headers": true, "URL": true, "URLSearchParams": true, + "__import__": true, "clearInterval": true, "clearTimeout": true, "console.error": true, @@ -668,7 +669,6 @@ "setTimeout": true }, "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index ac719964d896..126b6b1db5f2 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -660,6 +660,7 @@ "Headers": true, "URL": true, "URLSearchParams": true, + "__import__": true, "clearInterval": true, "clearTimeout": true, "console.error": true, @@ -668,7 +669,6 @@ "setTimeout": true }, "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 1b4e98aae177..7c45a9dc191b 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -752,6 +752,7 @@ "Headers": true, "URL": true, "URLSearchParams": true, + "__import__": true, "clearInterval": true, "clearTimeout": true, "console.error": true, @@ -760,7 +761,6 @@ "setTimeout": true }, "packages": { - "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true, "@ethereumjs/tx>@ethereumjs/util": true, "@ethersproject/contracts": true, "@ethersproject/providers": true, From 7a0cac33e334ce86ac870aba02fb87cae5f1e617 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 14:07:34 -0800 Subject: [PATCH 48/50] fix: Remove deprecated start and stop tokenListPolling --- app/scripts/metamask-controller.js | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0ee40fbe281a..5e97975555bc 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -645,9 +645,9 @@ export default class MetamaskController extends EventEmitter { this.tokenListController = new TokenListController({ chainId: getCurrentChainId({ metamask: this.networkController.state }), - preventPollingOnNetworkRestart: !this.#isTokenListPollingRequired( - this.preferencesController.state, - ), + // preventPollingOnNetworkRestart: !this.#isTokenListPollingRequired( + // this.preferencesController.state, + // ), messenger: tokenListMessenger, state: initState.TokenListController, }); @@ -2854,7 +2854,7 @@ export default class MetamaskController extends EventEmitter { this.txController.stopIncomingTransactionPolling(); } - this.#checkTokenListPolling(currState, prevState); + // this.#checkTokenListPolling(currState, prevState); }, this.preferencesController.state), ); @@ -7166,32 +7166,32 @@ export default class MetamaskController extends EventEmitter { }; } - #checkTokenListPolling(currentState, previousState) { - const previousEnabled = this.#isTokenListPollingRequired(previousState); - const newEnabled = this.#isTokenListPollingRequired(currentState); + // #checkTokenListPolling(currentState, previousState) { + // const previousEnabled = this.#isTokenListPollingRequired(previousState); + // const newEnabled = this.#isTokenListPollingRequired(currentState); - if (previousEnabled === newEnabled) { - return; - } + // if (previousEnabled === newEnabled) { + // return; + // } - this.tokenListController.updatePreventPollingOnNetworkRestart(!newEnabled); + // this.tokenListController.updatePreventPollingOnNetworkRestart(!newEnabled); - if (newEnabled) { - log.debug('Started token list controller polling'); - this.tokenListController.start(); - } else { - log.debug('Stopped token list controller polling'); - this.tokenListController.clearingTokenListData(); - this.tokenListController.stop(); - } - } + // if (newEnabled) { + // log.debug('Started token list controller polling'); + // this.tokenListController.start(); + // } else { + // log.debug('Stopped token list controller polling'); + // this.tokenListController.clearingTokenListData(); + // this.tokenListController.stop(); + // } + // } - #isTokenListPollingRequired(preferencesControllerState) { - const { useTokenDetection, useTransactionSimulations, preferences } = - preferencesControllerState ?? {}; + // #isTokenListPollingRequired(preferencesControllerState) { + // const { useTokenDetection, useTransactionSimulations, preferences } = + // preferencesControllerState ?? {}; - const { petnamesEnabled } = preferences ?? {}; + // const { petnamesEnabled } = preferences ?? {}; - return useTokenDetection || petnamesEnabled || useTransactionSimulations; - } + // return useTokenDetection || petnamesEnabled || useTransactionSimulations; + // } } From 5fc34e46811652bb35c1ee8c17d0732b94e77315 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 14:09:58 -0800 Subject: [PATCH 49/50] fix: Lint and cleanup comments --- app/scripts/metamask-controller.js | 33 +----------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 04849d3f0b59..35ed8d155059 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -2843,7 +2843,7 @@ export default class MetamaskController extends EventEmitter { let lastSelectedAddress; this.controllerMessenger.subscribe( 'PreferencesController:stateChange', - previousValueComparator(async (prevState, currState) => { + previousValueComparator(async (_, currState) => { const { currentLocale } = currState; const chainId = getCurrentChainId({ metamask: this.networkController.state, @@ -2855,8 +2855,6 @@ export default class MetamaskController extends EventEmitter { } else { this.txController.stopIncomingTransactionPolling(); } - - // this.#checkTokenListPolling(currState, prevState); }, this.preferencesController.state), ); @@ -7171,33 +7169,4 @@ export default class MetamaskController extends EventEmitter { metamask: this.getState(), }; } - - // #checkTokenListPolling(currentState, previousState) { - // const previousEnabled = this.#isTokenListPollingRequired(previousState); - // const newEnabled = this.#isTokenListPollingRequired(currentState); - - // if (previousEnabled === newEnabled) { - // return; - // } - - // this.tokenListController.updatePreventPollingOnNetworkRestart(!newEnabled); - - // if (newEnabled) { - // log.debug('Started token list controller polling'); - // this.tokenListController.start(); - // } else { - // log.debug('Stopped token list controller polling'); - // this.tokenListController.clearingTokenListData(); - // this.tokenListController.stop(); - // } - // } - - // #isTokenListPollingRequired(preferencesControllerState) { - // const { useTokenDetection, useTransactionSimulations, preferences } = - // preferencesControllerState ?? {}; - - // const { petnamesEnabled } = preferences ?? {}; - - // return useTokenDetection || petnamesEnabled || useTransactionSimulations; - // } } From 9b9bbc52b502982c7b7c0909b21e91d1d2b42704 Mon Sep 17 00:00:00 2001 From: Nicholas Gambino Date: Mon, 4 Nov 2024 14:24:58 -0800 Subject: [PATCH 50/50] chore: Lint useTokenListPolling hook --- ui/hooks/useTokenListPolling.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/hooks/useTokenListPolling.ts b/ui/hooks/useTokenListPolling.ts index dce9a160dcca..9744b17962c9 100644 --- a/ui/hooks/useTokenListPolling.ts +++ b/ui/hooks/useTokenListPolling.ts @@ -1,4 +1,5 @@ import { useSelector } from 'react-redux'; +import { Hex } from '@metamask/utils'; import { getNetworkConfigurationsByChainId, getPreferences, @@ -10,7 +11,6 @@ import { tokenListStopPollingByPollingToken, } from '../store/actions'; import useMultiPolling from './useMultiPolling'; -import { Hex } from '@metamask/utils'; const useTokenListPolling = () => { const networkConfigurations = useSelector(getNetworkConfigurationsByChainId);