From 85fe12d3f5a3a6d640485da1a340208819162752 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Tue, 22 Oct 2024 14:30:23 -0700 Subject: [PATCH 01/73] 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":"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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/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/73] 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/73] 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/73] 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/73] 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/73] 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":";;;;;;;;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 From 05fd6ef0b5e9c54058f3f6e051a2d17e2fff159d Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Wed, 23 Oct 2024 20:34:37 +0000 Subject: [PATCH 07/73] 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/73] 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/73] 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/73] 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/73] 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/73] 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 e8a9d6a79113fc14366027548646777f2b990ff2 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 13:02:10 -0700 Subject: [PATCH 13/73] 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 14/73] 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 15/73] 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 16/73] 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 70c0db4182f2460903d6ebda0bd0fe78acb7e34c Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 15:10:53 -0700 Subject: [PATCH 17/73] 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 18/73] . From 4e816c2c52b51030c333c66f638bbdd68529036f Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Wed, 30 Oct 2024 15:27:51 -0700 Subject: [PATCH 19/73] 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 20/73] 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 21/73] 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 3ec3574c97802834ae59a21d5e964f50454af3b9 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Thu, 31 Oct 2024 10:19:33 -0700 Subject: [PATCH 22/73] 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 0e7a8722bff749bf0fa4bcf9d9a0e808e617c0e7 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 1 Nov 2024 00:31:06 +0100 Subject: [PATCH 23/73] 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 24/73] 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 25/73] 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 ef3ef10753dcd97f07f25f75c4a9e10f5aff3855 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Fri, 1 Nov 2024 15:38:55 -0700 Subject: [PATCH 26/73] bump to asset controller v42 --- ...s-controllers-npm-42.0.0-57b3d695bb.patch} | 0 package.json | 3 +- ui/contexts/tokenRates.tsx | 12 --- ui/hooks/useTokenRatesPolling.ts | 21 +++-- ui/selectors/selectors.js | 16 ++++ yarn.lock | 86 +++++++++---------- 6 files changed, 76 insertions(+), 62 deletions(-) rename .yarn/patches/{@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch => @metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch} (100%) delete mode 100644 ui/contexts/tokenRates.tsx diff --git a/.yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch b/.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch similarity index 100% rename from .yarn/patches/@metamask-assets-controllers-npm-41.0.0-57b3d695bb.patch rename to .yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch diff --git a/package.json b/package.json index 24ed7ad53ceb..cad47b45c8f3 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,6 @@ "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", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", @@ -287,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%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/base-controller": "^7.0.0", "@metamask/bitcoin-wallet-snap": "^0.8.2", "@metamask/browser-passworder": "^4.3.0", diff --git a/ui/contexts/tokenRates.tsx b/ui/contexts/tokenRates.tsx deleted file mode 100644 index d5df4b750ff9..000000000000 --- a/ui/contexts/tokenRates.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, { ReactElement } from 'react'; -import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; - -export const TokenRatesProvider = ({ - children, -}: { - children: ReactElement; -}) => { - useTokenRatesPolling(); - - return <>{children}; -}; diff --git a/ui/hooks/useTokenRatesPolling.ts b/ui/hooks/useTokenRatesPolling.ts index eafdd81e427a..cc69350614e4 100644 --- a/ui/hooks/useTokenRatesPolling.ts +++ b/ui/hooks/useTokenRatesPolling.ts @@ -1,6 +1,9 @@ import { useSelector } from 'react-redux'; import { + getMarketData, getNetworkConfigurationsByChainId, + getTokenExchangeRates, + getTokensMarketData, getUseCurrencyRateCheck, } from '../selectors'; import { @@ -9,20 +12,28 @@ import { } from '../store/actions'; import useMultiPolling from './useMultiPolling'; -const useTokenRatesPolling = () => { +const useTokenRatesPolling = (chainIds: string[] | undefined = undefined) => { + // Selectors to determine polling input const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); - const chainIds = Object.keys(networkConfigurations); + + // Selectors returning state updated by the polling + const tokenExchangeRates = useSelector(getTokenExchangeRates); + const tokensMarketData = useSelector(getTokensMarketData); + const marketData = useSelector(getMarketData); useMultiPolling({ startPolling: tokenRatesStartPolling, stopPollingByPollingToken: tokenRatesStopPollingByPollingToken, - input: useCurrencyRateCheck ? chainIds : [], + input: useCurrencyRateCheck + ? chainIds ?? Object.keys(networkConfigurations) + : [], }); return { - // TODO: Eventually return token rates here. UI elements will - // consume them from this hook instead of a selector directly. + tokenExchangeRates, + tokensMarketData, + marketData, }; }; diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index bb7ef5f796d7..853de6ab92b7 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -582,11 +582,27 @@ export const getTokenExchangeRates = (state) => { ); }; +/** + * Get market data for tokens on the current chain + * + * @param state + * @returns {Record} + */ export const getTokensMarketData = (state) => { const chainId = getCurrentChainId(state); return state.metamask.marketData?.[chainId]; }; +/** + * Get market data for tokens across all chains + * + * @param state + * @returns {Record>} + */ +export const getMarketData = (state) => { + return state.metamask.marketData; +}; + export function getAddressBook(state) { const chainId = getCurrentChainId(state); if (!state.metamask.addressBook[chainId]) { diff --git a/yarn.lock b/yarn.lock index 172ca71b33fc..a1f4dfe4ea4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4663,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" @@ -4810,9 +4772,47 @@ __metadata: 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" +"@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/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" 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/1b3d04626e1ff712daa47e135fa0533556c076803af0ad45f9bae62882120661068700dfcadc3aa17d90a37bbbac6ae2b856056ea01413d8d01956b1d3e01bcb + checksum: 10/9a6727b28f88fd2df3f4b1628dd5d8c2f3e73fd4b9cd090f22d175c2522faa6c6b7e9a93d0ec2b2d123a263c8f4116fbfe97f196b99401b28ac8597f522651eb languageName: node linkType: hard @@ -26397,7 +26397,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" From ab6e7cca439516fd241d873a995b5e232e8fdb12 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Fri, 1 Nov 2024 15:41:07 -0700 Subject: [PATCH 27/73] . --- ui/contexts/tokenRates.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ui/contexts/tokenRates.tsx diff --git a/ui/contexts/tokenRates.tsx b/ui/contexts/tokenRates.tsx new file mode 100644 index 000000000000..d5764a95d675 --- /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}; +}; \ No newline at end of file From 411fc1c74299ddc6520eec3d5702add6ba3bfe9c Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Mon, 4 Nov 2024 09:35:06 -0800 Subject: [PATCH 28/73] initial token balances controller --- app/scripts/constants/sentry-state.ts | 3 + app/scripts/metamask-controller.js | 34 + package.json | 1 + ui/ducks/metamask/metamask.js | 9 + ui/hooks/useAccountTotalFiatBalance.js | 9 +- ui/hooks/useTokenBalances.ts | 109 ++ ui/store/actions.ts | 20 + yarn.lock | 1911 +++++++++++++++++++++--- 8 files changed, 1857 insertions(+), 239 deletions(-) create mode 100644 ui/hooks/useTokenBalances.ts diff --git a/app/scripts/constants/sentry-state.ts b/app/scripts/constants/sentry-state.ts index 3125016ea0b5..590e18ed1037 100644 --- a/app/scripts/constants/sentry-state.ts +++ b/app/scripts/constants/sentry-state.ts @@ -353,6 +353,9 @@ export const SENTRY_BACKGROUND_STATE = { [AllProperties]: false, }, }, + TokenBalancesController: { + tokenBalances: false, + }, TokenRatesController: { marketData: false, }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b43ef72cae5c..358552588947 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -12,6 +12,7 @@ import { CodefiTokenPricesServiceV2, RatesController, fetchMultiExchangeRate, + TokenBalancesController, } from '@metamask/assets-controllers'; import { JsonRpcEngine } from '@metamask/json-rpc-engine'; import { createEngineStream } from '@metamask/json-rpc-middleware-stream'; @@ -891,6 +892,27 @@ export default class MetamaskController extends EventEmitter { }; }; + const tokenBalancesMessenger = this.controllerMessenger.getRestricted({ + name: 'TokenBalancesController', + allowedActions: [ + 'NetworkController:getState', + 'NetworkController:getNetworkClientById', + 'TokensController:getState', + 'PreferencesController:getState', + 'AccountsController:getSelectedAccount', + ], + allowedEvents: [ + 'PreferencesController:stateChange', + 'TokensController:stateChange', + ], + }); + + this.tokenBalancesController = new TokenBalancesController({ + messenger: tokenBalancesMessenger, + state: initState.TokenBalancesController, + interval: 30000, + }); + const phishingControllerMessenger = this.controllerMessenger.getRestricted({ name: 'PhishingController', }); @@ -2395,6 +2417,7 @@ export default class MetamaskController extends EventEmitter { GasFeeController: this.gasFeeController, TokenListController: this.tokenListController, TokensController: this.tokensController, + TokenBalancesController: this.tokenBalancesController, SmartTransactionsController: this.smartTransactionsController, NftController: this.nftController, PhishingController: this.phishingController, @@ -2450,6 +2473,7 @@ export default class MetamaskController extends EventEmitter { GasFeeController: this.gasFeeController, TokenListController: this.tokenListController, TokensController: this.tokensController, + TokenBalancesController: this.tokenBalancesController, SmartTransactionsController: this.smartTransactionsController, NftController: this.nftController, SelectedNetworkController: this.selectedNetworkController, @@ -3223,6 +3247,7 @@ export default class MetamaskController extends EventEmitter { nftController, nftDetectionController, currencyRateController, + tokenBalancesController, tokenDetectionController, ensController, gasFeeController, @@ -4013,6 +4038,14 @@ export default class MetamaskController extends EventEmitter { tokenRatesController, ), + tokenBalancesStartPolling: tokenBalancesController.startPolling.bind( + tokenBalancesController, + ), + tokenBalancesStopPollingByPollingToken: + tokenBalancesController.stopPollingByPollingToken.bind( + tokenBalancesController, + ), + // GasFeeController gasFeeStartPollingByNetworkClientId: gasFeeController.startPollingByNetworkClientId.bind(gasFeeController), @@ -6646,6 +6679,7 @@ export default class MetamaskController extends EventEmitter { this.currencyRateController.stopAllPolling(); this.tokenRatesController.stopAllPolling(); this.appStateController.clearPollingTokens(); + this.tokenBalancesController.stopAllPolling(); } catch (error) { console.error(error); } diff --git a/package.json b/package.json index cad47b45c8f3..9695c8a6236a 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@42.0.0-preview-651fe366#./.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js index 9627608eb709..9bb5f3c380b8 100644 --- a/ui/ducks/metamask/metamask.js +++ b/ui/ducks/metamask/metamask.js @@ -457,6 +457,15 @@ export const getGasEstimateTypeByChainId = createSelector( }, ); +/** + * + * @param {*} state + * @returns { import('@metamask/assets-controllers').TokenBalancesControllerState['tokenBalances']} + */ +export function getTokenBalances(state) { + return state.metamask.tokenBalances; +} + export const getGasFeeEstimatesByChainId = createSelector( getGasFeeControllerEstimatesByChainId, getTransactionGasFeeEstimatesByChainId, diff --git a/ui/hooks/useAccountTotalFiatBalance.js b/ui/hooks/useAccountTotalFiatBalance.js index 7b4a4675225a..1fc702a42f4a 100644 --- a/ui/hooks/useAccountTotalFiatBalance.js +++ b/ui/hooks/useAccountTotalFiatBalance.js @@ -22,7 +22,7 @@ import { import { formatCurrency } from '../helpers/utils/confirm-tx.util'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; import { roundToDecimalPlacesRemovingExtraZeroes } from '../helpers/utils/util'; -import { useTokenTracker } from './useTokenTracker'; +import { useTokenTracker } from './useTokenBalances'; export const useAccountTotalFiatBalance = ( account, @@ -54,10 +54,11 @@ export const useAccountTotalFiatBalance = ( const primaryTokenImage = useSelector(getNativeCurrencyImage); const nativeCurrency = useSelector(getNativeCurrency); - const { loading, tokensWithBalances } = useTokenTracker({ + const loading = false; + const { loading:tokensWithBalances } = useTokenTracker({ + chainId: currentChainId, tokens, - address: account?.address, - includeFailedTokens: true, + address: account.address, hideZeroBalanceTokens: shouldHideZeroBalanceTokens, }); diff --git a/ui/hooks/useTokenBalances.ts b/ui/hooks/useTokenBalances.ts new file mode 100644 index 000000000000..10686f266b62 --- /dev/null +++ b/ui/hooks/useTokenBalances.ts @@ -0,0 +1,109 @@ +import { useSelector } from 'react-redux'; +import BN from 'bn.js'; +import { Token } from '@metamask/assets-controllers'; +import { + getNetworkConfigurationsByChainId, +} from '../selectors'; +import { + tokenBalancesStartPolling, + tokenBalancesStopPollingByPollingToken, +} from '../store/actions'; +import { getTokenBalances, getTokens } from '../ducks/metamask/metamask'; +import { hexToDecimal } from '../../shared/modules/conversion.utils'; +import useMultiPolling from './useMultiPolling'; +import { Hex } from '@metamask/utils'; + +export const useTokenBalances = ({chainIds}: {chainIds?: Hex[]} = {}) => { + const tokenBalances = useSelector(getTokenBalances); + const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); + + useMultiPolling({ + startPolling: tokenBalancesStartPolling, + stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken, + input: chainIds ?? Object.keys(networkConfigurations), + }); + + return { tokenBalances }; +}; + +// This hook is designed for backwards compatibility with `ui/hooks/useTokenTracker.js` +// and the github.com/MetaMask/eth-token-tracker library. It replaces RPC +// calls with reading state from `TokenBalancesController`. New code may prefer +// to use `useTokenBalances` directly, or compose higher level hooks from it. +export const useTokenTracker = ({ + chainId, + tokens, + address, + hideZeroBalanceTokens, +}: { + chainId: Hex; + tokens: Token[]; + address: Hex; + hideZeroBalanceTokens?: boolean; +}) => { + + const { tokenBalances } = useTokenBalances({ chainIds: [chainId] }); + + const tokensWithBalances = tokens.reduce((acc, token) => { + const hexBalance = tokenBalances[address]?.[chainId]?.[token.address as Hex] ?? '0x0'; + if (hexBalance !== '0x0' || !hideZeroBalanceTokens) { + const decimalBalance = hexToDecimal(hexBalance); + acc.push({ + address: token.address, + symbol: token.symbol, + decimals: token.decimals, + balance: decimalBalance, + string: stringifyBalance(new BN(decimalBalance), new BN(token.decimals)), + }); + } + return acc; + }, [] as (Token & { balance: string, string: string })[]) + + return { + tokensWithBalances + } + +}; + +// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js +// Ensures backwards compatibility with display formatting. +function stringifyBalance(balance: BN, bnDecimals: BN, balanceDecimals = 3) { + if (balance.eq(new BN(0))) { + return '0'; + } + + const decimals = parseInt(bnDecimals.toString()); + if (decimals === 0) { + return balance.toString(); + } + + let bal = balance.toString(); + let len = bal.length; + let decimalIndex = len - decimals; + let prefix = ''; + + if (decimalIndex <= 0) { + while (prefix.length <= decimalIndex * -1) { + prefix += '0'; + len++; + } + bal = prefix + bal; + decimalIndex = 1; + } + + const whole = bal.substr(0, len - decimals); + + if (balanceDecimals === 0) { + return whole; + } + + const fractional = bal.substr(decimalIndex, balanceDecimals); + if (/0+$/.test(fractional)) { + let withOnlySigZeroes = bal.substr(decimalIndex).replace(/0+$/, ''); + if (withOnlySigZeroes.length > 0) { + withOnlySigZeroes = `.${withOnlySigZeroes}`; + } + return `${whole}${withOnlySigZeroes}`; + } + return `${whole}.${fractional}`; +} diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 886739d2d54f..65f57ea84a7c 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -4555,6 +4555,26 @@ export async function currencyRateStopPollingByPollingToken( await removePollingTokenFromAppState(pollingToken); } +export async function tokenBalancesStartPolling( + chainId: string, +): Promise { + const pollingToken = await submitRequestToBackground( + 'tokenBalancesStartPolling', + [{ chainId }], + ); + await addPollingTokenToAppState(pollingToken); + return pollingToken; +} + +export async function tokenBalancesStopPollingByPollingToken( + pollingToken: string, +) { + await submitRequestToBackground('tokenBalancesStopPollingByPollingToken', [ + pollingToken, + ]); + await removePollingTokenFromAppState(pollingToken); +} + /** * Informs the TokenRatesController that the UI requires * token rate polling for the given chain id. diff --git a/yarn.lock b/yarn.lock index a1f4dfe4ea4c..da908500d7af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,20 +88,38 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/code-frame@npm:7.25.9" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" dependencies: - "@babel/highlight": "npm:^7.25.9" + "@babel/highlight": "npm:^7.24.7" picocolors: "npm:^1.0.0" - checksum: 10/96d69a570d0df82daedeb3d26ca508970bb31de83580c36c9605e7e7c0aae307ae17bc42609363016f0bdab12e991cebca3c02bf10765036b136bfe7281aee9a + checksum: 10/4812e94885ba7e3213d49583a155fdffb05292330f0a9b2c41b49288da70cf3c746a3fda0bf1074041a6d741c33f8d7be24be5e96f41ef77395eeddc5c9ff624 languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/compat-data@npm:7.25.9" - checksum: 10/76d06c56e1d1ab661dc90870d70d950c7df5514d2abfb115387ea0790ceeb1924ee3a88c959345f235aad219cfb13ff03c4458081ac350d47fc135a7ba2d49d3 +"@babel/code-frame@npm:^7.25.9": + version: 7.26.2 + resolution: "@babel/code-frame@npm:7.26.2" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.25.9" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/db2c2122af79d31ca916755331bb4bac96feb2b334cdaca5097a6b467fdd41963b89b14b6836a14f083de7ff887fc78fa1b3c10b14e743d33e12dbfe5ee3d223 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.2": + version: 7.23.2 + resolution: "@babel/compat-data@npm:7.23.2" + checksum: 10/c18eccd13975c1434a65d04f721075e30d03ba1608f4872d84e8538c16552b878aaac804ff31243d8c2c0e91524f3bc98de6305e117ba1a55c9956871973b4dc + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.25.9, @babel/compat-data@npm:^7.26.0": + version: 7.26.2 + resolution: "@babel/compat-data@npm:7.26.2" + checksum: 10/ed9eed6b62ce803ef4a320b1dac76b0302abbb29c49dddf96f3e3207d9717eb34e299a8651bb1582e9c3346ead74b6d595ffced5b3dae718afa08b18741f8402 languageName: node linkType: hard @@ -177,15 +195,37 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.22.5, @babel/generator@npm:^7.23.0, @babel/generator@npm:^7.23.6, @babel/generator@npm:^7.25.9, @babel/generator@npm:^7.7.2": - version: 7.25.9 - resolution: "@babel/generator@npm:7.25.9" +"@babel/generator@npm:^7.22.5, @babel/generator@npm:^7.23.0, @babel/generator@npm:^7.23.6, @babel/generator@npm:^7.25.4, @babel/generator@npm:^7.7.2": + version: 7.25.5 + resolution: "@babel/generator@npm:7.25.5" dependencies: - "@babel/types": "npm:^7.25.9" + "@babel/types": "npm:^7.25.4" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10/e6d046afe739cfa706c40c127b7436731acb2a3146d408a7d89dbf16448491b35bc09b7d285cc19c2c1f8980d74b5a99df200d67c859bb5260986614685b0770 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.25.9": + version: 7.26.2 + resolution: "@babel/generator@npm:7.26.2" + dependencies: + "@babel/parser": "npm:^7.26.2" + "@babel/types": "npm:^7.26.0" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10/eb36706c62ea77a09604077b84fae4e25d103cce58a15926d9d8b62d90c5fa69e35962515c05e78b5a975848ef772406dd79e2d4e83851bf9f7517b197a1b19d + checksum: 10/71ace82b5b07a554846a003624bfab93275ccf73cdb9f1a37a4c1094bf9dc94bb677c67e8b8c939dbd6c5f0eda2e8f268aa2b0d9c3b9511072565660e717e045 + languageName: node + linkType: hard + +"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" + dependencies: + "@babel/types": "npm:^7.24.7" + checksum: 10/a9017bfc1c4e9f2225b967fbf818004703de7cf29686468b54002ffe8d6b56e0808afa20d636819fcf3a34b89ba72f52c11bdf1d69f303928ee10d92752cad95 languageName: node linkType: hard @@ -198,6 +238,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.5": + version: 7.22.15 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" + dependencies: + "@babel/types": "npm:^7.22.15" + checksum: 10/639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a + languageName: node + linkType: hard + "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.9" @@ -208,7 +257,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.9": +"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6": + version: 7.22.15 + resolution: "@babel/helper-compilation-targets@npm:7.22.15" + dependencies: + "@babel/compat-data": "npm:^7.22.9" + "@babel/helper-validator-option": "npm:^7.22.15" + browserslist: "npm:^4.21.9" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10/9706decaa1591cf44511b6f3447eb9653b50ca3538215fe2e5387a8598c258c062f4622da5b95e61f0415706534deee619bbf53a2889f9bd967949b8f6024e0e + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-compilation-targets@npm:7.25.9" dependencies: @@ -221,6 +283,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.5, @babel/helper-create-class-features-plugin@npm:^7.25.0": + version: 7.25.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.24.7" + "@babel/helper-member-expression-to-functions": "npm:^7.24.8" + "@babel/helper-optimise-call-expression": "npm:^7.24.7" + "@babel/helper-replace-supers": "npm:^7.25.0" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.4" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/47218da9fd964af30d41f0635d9e33eed7518e03aa8f10c3eb8a563bb2c14f52be3e3199db5912ae0e26058c23bb511c811e565c55ecec09427b04b867ed13c2 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9" @@ -238,7 +317,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.9": +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": + version: 7.22.15 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + regexpu-core: "npm:^5.3.1" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/886b675e82f1327b4f7a2c69a68eefdb5dbb0b9d4762c2d4f42a694960a9ccf61e1a3bcad601efd92c110033eb1a944fcd1e5cac188aa6b2e2076b541e210e20 + languageName: node + linkType: hard + +"@babel/helper-create-regexp-features-plugin@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.9" dependencies: @@ -251,6 +343,21 @@ __metadata: languageName: node linkType: hard +"@babel/helper-define-polyfill-provider@npm:^0.4.3": + version: 0.4.3 + resolution: "@babel/helper-define-polyfill-provider@npm:0.4.3" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.22.6" + "@babel/helper-plugin-utils": "npm:^7.22.5" + debug: "npm:^4.1.1" + lodash.debounce: "npm:^4.0.8" + resolve: "npm:^1.14.2" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/9ab9d6a2cfaffc44f8b7ad661b642b03f31597282557686b7f4c64f67acd3c5844d4eac028e63d238819bcec0549ddef7dc0539d10966ace96f4c61e97b33138 + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.6.2": version: 0.6.2 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" @@ -266,7 +373,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.20": +"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.22.5": version: 7.24.7 resolution: "@babel/helper-environment-visitor@npm:7.24.7" dependencies: @@ -275,7 +382,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.23.0": +"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": version: 7.24.7 resolution: "@babel/helper-function-name@npm:7.24.7" dependencies: @@ -294,6 +401,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" + dependencies: + "@babel/traverse": "npm:^7.24.8" + "@babel/types": "npm:^7.24.8" + checksum: 10/ac878761cfd0a46c081cda0da75cc186f922cf16e8ecdd0c4fb6dca4330d9fe4871b41a9976224cf9669c9e7fe0421b5c27349f2e99c125fa0be871b327fa770 + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9" @@ -304,7 +421,17 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.25.9": +"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.22.5, @babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" + dependencies: + "@babel/traverse": "npm:^7.24.7" + "@babel/types": "npm:^7.24.7" + checksum: 10/df8bfb2bb18413aa151ecd63b7d5deb0eec102f924f9de6bc08022ced7ed8ca7fed914562d2f6fa5b59b74a5d6e255dc35612b2bc3b8abf361e13f61b3704770 + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-module-imports@npm:7.25.9" dependencies: @@ -314,17 +441,39 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0, @babel/helper-module-transforms@npm:^7.24.8": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" + dependencies: + "@babel/helper-module-imports": "npm:^7.24.7" + "@babel/helper-simple-access": "npm:^7.24.7" + "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.2" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/a3bcf7815f3e9d8b205e0af4a8d92603d685868e45d119b621357e274996bf916216bb95ab5c6a60fde3775b91941555bf129d608e3d025b04f8aac84589f300 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-module-transforms@npm:7.25.9" + version: 7.26.0 + resolution: "@babel/helper-module-transforms@npm:7.26.0" dependencies: "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-simple-access": "npm:^7.25.9" "@babel/helper-validator-identifier": "npm:^7.25.9" "@babel/traverse": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10/6a9dc7da67f901a511ef26b99fd1b395946d466495159cbf80c092345ef3238306296ee76b204aea5f2675713130c58760c46b1ff3b6f6b19f7f8afcaa19d8ca + checksum: 10/9841d2a62f61ad52b66a72d08264f23052d533afc4ce07aec2a6202adac0bfe43014c312f94feacb3291f4c5aafe681955610041ece2c276271adce3f570f2f5 + languageName: node + linkType: hard + +"@babel/helper-optimise-call-expression@npm:^7.22.5, @babel/helper-optimise-call-expression@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" + dependencies: + "@babel/types": "npm:^7.24.7" + checksum: 10/da7a7f2d1bb1be4cffd5fa820bd605bc075c7dd014e0458f608bb6f34f450fe9412c8cea93e788227ab396e0e02c162d7b1db3fbcb755a6360e354c485d61df0 languageName: node linkType: hard @@ -337,13 +486,33 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.8.0": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 10/adbc9fc1142800a35a5eb0793296924ee8057fe35c61657774208670468a9fbfbb216f2d0bc46c680c5fefa785e5ff917cc1674b10bd75cdf9a6aa3444780630 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-plugin-utils@npm:7.25.9" checksum: 10/e347d87728b1ab10b6976d46403941c8f9008c045ea6d99997a7ffca7b852dc34b6171380f7b17edf94410e0857ff26f3a53d8618f11d73744db86e8ca9b8c64 languageName: node linkType: hard +"@babel/helper-remap-async-to-generator@npm:^7.22.20, @babel/helper-remap-async-to-generator@npm:^7.22.5": + version: 7.22.20 + resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-wrap-function": "npm:^7.22.20" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-remap-async-to-generator@npm:7.25.9" @@ -357,6 +526,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.22.5, @babel/helper-replace-supers@npm:^7.22.9, @babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.24.8" + "@babel/helper-optimise-call-expression": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/97c6c17780cb9692132f7243f5a21fb6420104cb8ff8752dc03cfc9a1912a243994c0290c77ff096637ab6f2a7363b63811cfc68c2bad44e6b39460ac2f6a63f + languageName: node + linkType: hard + "@babel/helper-replace-supers@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-replace-supers@npm:7.25.9" @@ -370,6 +552,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-simple-access@npm:7.24.7" + dependencies: + "@babel/traverse": "npm:^7.24.7" + "@babel/types": "npm:^7.24.7" + checksum: 10/5083e190186028e48fc358a192e4b93ab320bd016103caffcfda81302a13300ccce46c9cd255ae520c25d2a6a9b47671f93e5fe5678954a2329dc0a685465c49 + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-simple-access@npm:7.25.9" @@ -380,6 +572,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5, @babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" + dependencies: + "@babel/traverse": "npm:^7.24.7" + "@babel/types": "npm:^7.24.7" + checksum: 10/784a6fdd251a9a7e42ccd04aca087ecdab83eddc60fda76a2950e00eb239cc937d3c914266f0cc476298b52ac3f44ffd04c358e808bd17552a7e008d75494a77 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9" @@ -399,27 +601,59 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.23.4, @babel/helper-string-parser@npm:^7.25.9": +"@babel/helper-string-parser@npm:^7.23.4, @babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 10/6d1bf8f27dd725ce02bdc6dffca3c95fb9ab8a06adc2edbd9c1c9d68500274230d1a609025833ed81981eff560045b6b38f7b4c6fb1ab19fc90e5004e3932535 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-string-parser@npm:7.25.9" checksum: 10/c28656c52bd48e8c1d9f3e8e68ecafd09d949c57755b0d353739eb4eae7ba4f7e67e92e4036f1cd43378cc1397a2c943ed7bcaf5949b04ab48607def0258b775 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.25.9": +"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 10/86875063f57361471b531dbc2ea10bbf5406e12b06d249b03827d361db4cad2388c6f00936bcd9dc86479f7e2c69ea21412c2228d4b3672588b754b70a449d4b + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" checksum: 10/3f9b649be0c2fd457fa1957b694b4e69532a668866b8a0d81eabfa34ba16dbf3107b39e0e7144c55c3c652bf773ec816af8df4a61273a2bb4eb3145ca9cf478e languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.23.5, @babel/helper-validator-option@npm:^7.25.9": +"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5, @babel/helper-validator-option@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: 10/a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-option@npm:7.25.9" checksum: 10/9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d languageName: node linkType: hard +"@babel/helper-wrap-function@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-wrap-function@npm:7.22.20" + dependencies: + "@babel/helper-function-name": "npm:^7.22.5" + "@babel/template": "npm:^7.22.15" + "@babel/types": "npm:^7.22.19" + checksum: 10/b22e4666dec3d401bdf8ebd01d448bb3733617dae5aa6fbd1b684a22a35653cca832edd876529fd139577713b44fb89b4f5e52b7315ab218620f78b8a8ae23de + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-wrap-function@npm:7.25.9" @@ -432,12 +666,12 @@ __metadata: linkType: hard "@babel/helpers@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helpers@npm:7.25.9" + version: 7.26.0 + resolution: "@babel/helpers@npm:7.26.0" dependencies: "@babel/template": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10/83c0df8f45850c5621be660b69c33d93c02832162a9109bb9a03de32a2b6477fbbd1e2c8c5c19fadb0d48f07066ff20d2d2da32de62dfda5c0a6a1036cebeb00 + "@babel/types": "npm:^7.26.0" + checksum: 10/fd4757f65d10b64cfdbf4b3adb7ea6ffff9497c53e0786452f495d1f7794da7e0898261b4db65e1c62bbb9a360d7d78a1085635c23dfc3af2ab6dcba06585f86 languageName: node linkType: hard @@ -452,15 +686,15 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.22.13, @babel/highlight@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/highlight@npm:7.25.9" +"@babel/highlight@npm:^7.22.13, @babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" dependencies: - "@babel/helper-validator-identifier": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.24.7" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10/0d165283dd4eb312292cea8fec3ae0d376874b1885f476014f0136784ed5b564b2c2ba2d270587ed546ee92505056dab56493f7960c01c4e6394d71d1b2e7db6 + checksum: 10/69b73f38cdd4f881b09b939a711e76646da34f4834f4ce141d7a49a6bb1926eab1c594148970a8aa9360398dff800f63aade4e81fafdd7c8d8a8489ea93bfec1 languageName: node linkType: hard @@ -482,14 +716,25 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/parser@npm:7.25.9" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/parser@npm:7.25.4" dependencies: - "@babel/types": "npm:^7.25.9" + "@babel/types": "npm:^7.25.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10/343b8a76c43549e370fe96f4f6d564382a6cdff60e9c3b8a594c51e4cefd58ec9945e82e8c4dfbf15ac865a04e4b29806531440760748e28568e6aec21bc9cb5 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.2": + version: 7.26.2 + resolution: "@babel/parser@npm:7.26.2" + dependencies: + "@babel/types": "npm:^7.26.0" bin: parser: ./bin/babel-parser.js - checksum: 10/702af8c40bb1236e3e3e6187b99e1290bd4bc1500aa53593ea63df8fe99f07ff1efef147b1d58886b264aff0972c4b9440ace442c8db9a6e079f318d46773421 + checksum: 10/8baee43752a3678ad9f9e360ec845065eeee806f1fdc8e0f348a8a0e13eef0959dabed4a197c978896c493ea205c804d0a1187cc52e4a1ba017c7935bab4983d languageName: node linkType: hard @@ -516,6 +761,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.15" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/8910ca21a7ec7c06f7b247d4b86c97c5aa15ef321518f44f6f490c5912fdf82c605aaa02b90892e375d82ccbedeadfdeadd922c1b836c9dd4c596871bf654753 + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.9" @@ -527,6 +783,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.22.15" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" + "@babel/plugin-transform-optional-chaining": "npm:^7.22.15" + peerDependencies: + "@babel/core": ^7.13.0 + checksum: 10/fbefedc0da014c37f1a50a8094ce7dbbf2181ae93243f23d6ecba2499b5b20196c2124d6a4dfe3e9e0125798e80593103e456352a4beb4e5c6f7c75efb80fdac + languageName: node + linkType: hard + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.9" @@ -583,7 +852,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-properties@npm:^7.8.3": +"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -594,6 +863,39 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-class-static-block@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948 + languageName: node + linkType: hard + +"@babel/plugin-syntax-dynamic-import@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd + languageName: node + linkType: hard + +"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a + languageName: node + linkType: hard + "@babel/plugin-syntax-flow@npm:^7.24.1": version: 7.24.1 resolution: "@babel/plugin-syntax-flow@npm:7.24.1" @@ -605,29 +907,51 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.25.9" +"@babel/plugin-syntax-import-assertions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/2b8b5572db04a7bef1e6cd20debf447e4eef7cb012616f5eceb8fa3e23ce469b8f76ee74fd6d1e158ba17a8f58b0aec579d092fb67c5a30e83ccfbc5754916c1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-assertions@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.26.0" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/2f0c70bb379135ee205402caa42c0dda4d5d8fb64ff4ad163cab94bd8291c1a63b9dc9cf293758cecee223080d2d61e83f92c6d2a264621e24a07258c48968db + checksum: 10/b58f2306df4a690ca90b763d832ec05202c50af787158ff8b50cdf3354359710bce2e1eb2b5135fcabf284756ac8eadf09ca74764aa7e76d12a5cac5f6b21e67 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.25.9" +"@babel/plugin-syntax-import-attributes@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/197b3c5ea2a9649347f033342cb222ab47f4645633695205c0250c6bf2af29e643753b8bb24a2db39948bef08e7c540babfd365591eb57fc110cb30b425ffc47 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-attributes@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/0ea00b9100d383680c7142e61e3aa7101e3657ec5e1bfa990871eee4ae17e2c4a0da084e8f611d349bb9612908e911e1400418eb59caa5184226b08f513c1a0a + checksum: 10/c122aa577166c80ee67f75aebebeef4150a132c4d3109d25d7fc058bf802946f883e330f20b78c1d3e3a5ada631c8780c263d2d01b5dbaecc69efefeedd42916 languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.8.3": +"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -649,7 +973,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.25.9, @babel/plugin-syntax-jsx@npm:^7.7.2": +"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.24.7, @babel/plugin-syntax-jsx@npm:^7.7.2": + version: 7.24.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a93516ae5b34868ab892a95315027d4e5e38e8bd1cfca6158f2974b0901cbb32bbe64ea10ad5b25f919ddc40c6d8113c4823372909c9c9922170c12b0b1acecb + languageName: node + linkType: hard + +"@babel/plugin-syntax-jsx@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-syntax-jsx@npm:7.25.9" dependencies: @@ -660,7 +995,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -682,7 +1017,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.8.3": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -726,7 +1061,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.8.3": +"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b317174783e6e96029b743ccff2a67d63d38756876e7e5d0ba53a322e38d9ca452c13354a57de1ad476b4c066dbae699e0ca157441da611117a47af88985ecda + languageName: node + linkType: hard + +"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -737,7 +1083,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.25.9, @babel/plugin-syntax-typescript@npm:^7.7.2": +"@babel/plugin-syntax-typescript@npm:^7.24.7, @babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.25.4 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/0771b45a35fd536cd3b3a48e5eda0f53e2d4f4a0ca07377cc247efa39eaf6002ed1c478106aad2650e54aefaebcb4f34f3284c4ae9252695dbd944bf66addfb0 + languageName: node + linkType: hard + +"@babel/plugin-syntax-typescript@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-syntax-typescript@npm:7.25.9" dependencies: @@ -760,6 +1117,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-arrow-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/35abb6c57062802c7ce8bd96b2ef2883e3124370c688bbd67609f7d2453802fb73944df8808f893b6c67de978eb2bcf87bbfe325e46d6f39b5fcb09ece11d01a + languageName: node + linkType: hard + "@babel/plugin-transform-arrow-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.9" @@ -771,6 +1139,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-generator-functions@npm:^7.23.2": + version: 7.23.2 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.2" + dependencies: + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-remap-async-to-generator": "npm:^7.22.20" + "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/e1abae0edcda7304d7c17702ac25a127578791b89c4f767d60589249fa3e50ec33f8c9ff39d3d8d41f00b29947654eaddd4fd586e04c4d598122db745fab2868 + languageName: node + linkType: hard + "@babel/plugin-transform-async-generator-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.9" @@ -784,6 +1166,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-to-generator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.22.5" + dependencies: + "@babel/helper-module-imports": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-remap-async-to-generator": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b95f23f99dcb379a9f0a1c2a3bbea3f8dc0e1b16dc1ac8b484fe378370169290a7a63d520959a9ba1232837cf74a80e23f6facbe14fd42a3cda6d3c2d7168e62 + languageName: node + linkType: hard + "@babel/plugin-transform-async-to-generator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9" @@ -797,6 +1192,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoped-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/416b1341858e8ca4e524dee66044735956ced5f478b2c3b9bc11ec2285b0c25d7dbb96d79887169eb938084c95d0a89338c8b2fe70d473bd9dc92e5d9db1732c + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoped-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.9" @@ -808,6 +1214,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoping@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.23.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/9f60c71a0b72c7bdc0734ab363cf8ad40c4366456d9429ab3f2caedf6566c12f1ae8190478827222e93c60855b6c746a2c0e24381646fe7220d4666c332dc090 + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoping@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9" @@ -819,7 +1236,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.22.5, @babel/plugin-transform-class-properties@npm:^7.25.9": +"@babel/plugin-transform-class-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-class-properties@npm:7.22.5" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b830152dfc2ff2f647f0abe76e6251babdfbef54d18c4b2c73a6bf76b1a00050a5d998dac80dc901a48514e95604324943a9dd39317073fe0928b559e0e0c579 + languageName: node + linkType: hard + +"@babel/plugin-transform-class-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-class-properties@npm:7.25.9" dependencies: @@ -831,15 +1260,47 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-class-static-block@npm:7.25.9" +"@babel/plugin-transform-class-static-block@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-class-static-block@npm:7.22.11" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.22.11" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 10/69f040506fad66f1c6918d288d0e0edbc5c8a07c8b4462c1184ad2f9f08995d68b057126c213871c0853ae0c72afc60ec87492049dfacb20902e32346a448bcb + languageName: node + linkType: hard + +"@babel/plugin-transform-class-static-block@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/plugin-transform-class-static-block@npm:7.26.0" dependencies: "@babel/helper-create-class-features-plugin": "npm:^7.25.9" "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.12.0 - checksum: 10/01dbb32e443086cf98e986a0d3532f74916ed85ef4823139d155d69c6fbf4ae80ae862f83abba57d815bb6aebd349b18cdec93ef08be42ead4248f3a294c8a08 + checksum: 10/60cba3f125a7bc4f90706af0a011697c7ffd2eddfba336ed6f84c5f358c44c3161af18b0202475241a96dee7964d96dd3a342f46dbf85b75b38bb789326e1766 + languageName: node + linkType: hard + +"@babel/plugin-transform-classes@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-transform-classes@npm:7.22.15" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-environment-visitor": "npm:^7.22.5" + "@babel/helper-function-name": "npm:^7.22.5" + "@babel/helper-optimise-call-expression": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-replace-supers": "npm:^7.22.9" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + globals: "npm:^11.1.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/21d7a171055634b4c407e42fc99ef340bde70d5582d47f7bcdc9781d09b3736607d346f56c3abb1e8b9b62516e1af25ab9023a295be0c347c963d6a20f74b55f languageName: node linkType: hard @@ -859,6 +1320,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-computed-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-computed-properties@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/template": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a3efa8de19e4c52f01a99301d864819a7997a7845044d9cef5b67b0fb1e5e3e610ecc23053a8b5cf8fe40fcad93c15a586eaeffd22b89eeaa038339c37919661 + languageName: node + linkType: hard + "@babel/plugin-transform-computed-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-computed-properties@npm:7.25.9" @@ -871,6 +1344,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-destructuring@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/plugin-transform-destructuring@npm:7.23.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/924b1c0fc11c9782a9a63ae6d181b9b069250a5567c705c24409e2f1e39ac47e61846cd17b0ab45641dc77050e7b900fc80a536f8abe7dff49b4e777e7b9b952 + languageName: node + linkType: hard + "@babel/plugin-transform-destructuring@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-destructuring@npm:7.25.9" @@ -882,6 +1366,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dotall-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/409b658d11e3082c8f69e9cdef2d96e4d6d11256f005772425fb230cc48fd05945edbfbcb709dab293a1a2f01f9c8a5bb7b4131e632b23264039d9f95864b453 + languageName: node + linkType: hard + "@babel/plugin-transform-dotall-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.9" @@ -894,6 +1390,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-keys@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bb1280fbabaab6fab2ede585df34900712698210a3bd413f4df5bae6d8c24be36b496c92722ae676a7a67d060a4624f4d6c23b923485f906bfba8773c69f55b4 + languageName: node + linkType: hard + "@babel/plugin-transform-duplicate-keys@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.9" @@ -917,6 +1424,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dynamic-import@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/78fc9c532210bf9e8f231747f542318568ac360ee6c27e80853962c984283c73da3f8f8aebe83c2096090a435b356b092ed85de617a156cbe0729d847632be45 + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.9" @@ -928,6 +1447,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-exponentiation-operator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.22.5" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/f2d660c1b1d51ad5fec1cd5ad426a52187204068c4158f8c4aa977b31535c61b66898d532603eef21c15756827be8277f724c869b888d560f26d7fe848bb5eae + languageName: node + linkType: hard + "@babel/plugin-transform-exponentiation-operator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.25.9" @@ -940,6 +1471,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-export-namespace-from@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/73af5883a321ed56a4bfd43c8a7de0164faebe619287706896fc6ee2f7a4e69042adaa1338c0b8b4bdb9f7e5fdceb016fb1d40694cb43ca3b8827429e8aac4bf + languageName: node + linkType: hard + "@babel/plugin-transform-export-namespace-from@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.9" @@ -963,6 +1506,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-for-of@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-transform-for-of@npm:7.22.15" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d6ac155fcc8dc3d37a092325e5b7df738a7a953c4a47520c0c02fbc30433e6a5ac38197690845ebb931870af958ac95d36132d5accf41ed4bb0765a7618371fc + languageName: node + linkType: hard + "@babel/plugin-transform-for-of@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-for-of@npm:7.25.9" @@ -975,6 +1529,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-function-name@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-function-name@npm:7.22.5" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.22.5" + "@babel/helper-function-name": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/cff3b876357999cb8ae30e439c3ec6b0491a53b0aa6f722920a4675a6dd5b53af97a833051df4b34791fe5b3dd326ccf769d5c8e45b322aa50ee11a660b17845 + languageName: node + linkType: hard + "@babel/plugin-transform-function-name@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-function-name@npm:7.25.9" @@ -988,6 +1555,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-json-strings@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-json-strings@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/50665e5979e66358c50e90a26db53c55917f78175127ac2fa05c7888d156d418ffb930ec0a109353db0a7c5f57c756ce01bfc9825d24cbfd2b3ec453f2ed8cba + languageName: node + linkType: hard + "@babel/plugin-transform-json-strings@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-json-strings@npm:7.25.9" @@ -999,6 +1578,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-literals@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ec37cc2ffb32667af935ab32fe28f00920ec8a1eb999aa6dc6602f2bebd8ba205a558aeedcdccdebf334381d5c57106c61f52332045730393e73410892a9735b + languageName: node + linkType: hard + "@babel/plugin-transform-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-literals@npm:7.25.9" @@ -1010,6 +1600,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-logical-assignment-operators@npm:^7.22.11": + version: 7.23.4 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.23.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/2ae1dc9b4ff3bf61a990ff3accdecb2afe3a0ca649b3e74c010078d1cdf29ea490f50ac0a905306a2bcf9ac177889a39ac79bdcc3a0fdf220b3b75fac18d39b5 + languageName: node + linkType: hard + "@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.9" @@ -1021,6 +1623,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-member-expression-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ec4b0e07915ddd4fda0142fd104ee61015c208608a84cfa13643a95d18760b1dc1ceb6c6e0548898b8c49e5959a994e46367260176dbabc4467f729b21868504 + languageName: node + linkType: hard + "@babel/plugin-transform-member-expression-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.9" @@ -1032,6 +1645,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-amd@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/plugin-transform-modules-amd@npm:7.23.0" + dependencies: + "@babel/helper-module-transforms": "npm:^7.23.0" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d06fbee89044a0c4d9d65c2bb26b45482266d14d64601a36996615ca75f1e1cc40ac95d09821601606eacbeeef39b3b634118f6197cda6431c8440975926a5d5 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-amd@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-amd@npm:7.25.9" @@ -1044,7 +1669,20 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.25.9": +"@babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" + dependencies: + "@babel/helper-module-transforms": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-simple-access": "npm:^7.24.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/18e5d229767c7b5b6ff0cbf1a8d2d555965b90201839d0ac2dc043b56857624ea344e59f733f028142a8c1d54923b82e2a0185694ef36f988d797bfbaf59819c + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-commonjs@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.9" dependencies: @@ -1057,6 +1695,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-systemjs@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.0" + dependencies: + "@babel/helper-hoist-variables": "npm:^7.22.5" + "@babel/helper-module-transforms": "npm:^7.23.0" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-validator-identifier": "npm:^7.22.20" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/43a61fd72ba90afafcf6734345df00cbaf1f244ca456f8e8532813b87a985ddfeca7fc6ea758c12350abcfeba02835875b44dc6b3118c2dac7469a3f298c79ad + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.9" @@ -1071,6 +1723,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-umd@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-umd@npm:7.22.5" + dependencies: + "@babel/helper-module-transforms": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b955d066c68b60c1179bfb0b744e2fad32dbe86d0673bd94637439cfe425d1e3ff579bd47a417233609aac1624f4fe69915bee73e6deb2af6188fda8aaa5db63 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-umd@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-umd@npm:7.25.9" @@ -1083,6 +1747,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 + languageName: node + linkType: hard + "@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.9" @@ -1095,6 +1771,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-new-target@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-new-target@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/6b72112773487a881a1d6ffa680afde08bad699252020e86122180ee7a88854d5da3f15d9bca3331cf2e025df045604494a8208a2e63b486266b07c14e2ffbf3 + languageName: node + linkType: hard + "@babel/plugin-transform-new-target@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-new-target@npm:7.25.9" @@ -1106,7 +1793,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/167babecc8b8fe70796a7b7d34af667ebbf43da166c21689502e5e8cc93180b7a85979c77c9f64b7cce431b36718bd0a6df9e5e0ffea4ae22afb22cfef886372 + languageName: node + linkType: hard + +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.9" dependencies: @@ -1117,6 +1816,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-numeric-separator@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/af064d06a4a041767ec396a5f258103f64785df290e038bba9f0ef454e6c914f2ac45d862bbdad8fac2c7ad47fa4e95356f29053c60c100a0160b02a995fe2a3 + languageName: node + linkType: hard + "@babel/plugin-transform-numeric-separator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.9" @@ -1128,6 +1839,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-rest-spread@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.22.15" + dependencies: + "@babel/compat-data": "npm:^7.22.9" + "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" + "@babel/plugin-transform-parameters": "npm:^7.22.15" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/04b9f4bbabf4bbd019b47c60b294d873fe5d2f6063628a5b311d88da9e81b0a8622756dd42c7030359925479b7a3cd743dee46e73d84e03afd907d8cfd44ddea + languageName: node + linkType: hard + "@babel/plugin-transform-object-rest-spread@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.9" @@ -1141,6 +1867,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-super@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-object-super@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-replace-supers": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b71887877d74cb64dbccb5c0324fa67e31171e6a5311991f626650e44a4083e5436a1eaa89da78c0474fb095d4ec322d63ee778b202d33aa2e4194e1ed8e62d7 + languageName: node + linkType: hard + "@babel/plugin-transform-object-super@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-object-super@npm:7.25.9" @@ -1153,6 +1891,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-catch-binding@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.22.11" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/f17abd90e1de67c84d63afea29c8021c74abb2794d3a6eeafb0bbe7372d3db32aefca386e392116ec63884537a4a2815d090d26264d259bacc08f6e3ed05294c + languageName: node + linkType: hard + "@babel/plugin-transform-optional-catch-binding@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.9" @@ -1164,7 +1914,20 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.23.0, @babel/plugin-transform-optional-chaining@npm:^7.25.9": +"@babel/plugin-transform-optional-chaining@npm:^7.22.15, @babel/plugin-transform-optional-chaining@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fb1103c6489b91df06c483a97fc12515c2f3840f573cbecb27959307c0a838fdd1502a34ada43805c4fb7f7dab3d1c0d1ab8428775d098af6778a7b00f494c27 + languageName: node + linkType: hard + +"@babel/plugin-transform-optional-chaining@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.9" dependencies: @@ -1176,6 +1939,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-parameters@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/plugin-transform-parameters@npm:7.22.15" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fa9f2340fe48b88c344ff38cd86318f61e48bedafdc567a1607106a1c3a65c0db845792f406b1320f89745192fe1ae6739b0bc4eb646ff60cd797ca85752d462 + languageName: node + linkType: hard + "@babel/plugin-transform-parameters@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-parameters@npm:7.25.9" @@ -1187,7 +1961,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.22.5, @babel/plugin-transform-private-methods@npm:^7.25.9": +"@babel/plugin-transform-private-methods@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-private-methods@npm:7.22.5" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/321479b4fcb6d3b3ef622ab22fd24001e43d46e680e8e41324c033d5810c84646e470f81b44cbcbef5c22e99030784f7cac92f1829974da7a47a60a7139082c3 + languageName: node + linkType: hard + +"@babel/plugin-transform-private-methods@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-private-methods@npm:7.25.9" dependencies: @@ -1199,6 +1985,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-property-in-object@npm:^7.22.11": + version: 7.22.11 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.22.11" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-create-class-features-plugin": "npm:^7.22.11" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b00623d107069c91a164d5cf7486c0929a4ee3023fcddbc8844e21b5e66f369271e1aa51921c7d87b80d9927bc75d63afcfe4d577872457ddb0443a5b86bacca + languageName: node + linkType: hard + "@babel/plugin-transform-private-property-in-object@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.9" @@ -1212,6 +2012,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-property-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-property-literals@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/796176a3176106f77fcb8cd04eb34a8475ce82d6d03a88db089531b8f0453a2fb8b0c6ec9a52c27948bc0ea478becec449893741fc546dfc3930ab927e3f9f2e + languageName: node + linkType: hard + "@babel/plugin-transform-property-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-property-literals@npm:7.25.9" @@ -1223,6 +2034,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-display-name@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-display-name@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a12bfd1e4e93055efca3ace3c34722571bda59d9740dca364d225d9c6e3ca874f134694d21715c42cc63d79efd46db9665bd4a022998767f9245f1e29d5d204d + languageName: node + linkType: hard + "@babel/plugin-transform-react-display-name@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-display-name@npm:7.25.9" @@ -1234,6 +2056,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 + languageName: node + linkType: hard + "@babel/plugin-transform-react-jsx-development@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.9" @@ -1245,6 +2078,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5": + version: 7.22.15 + resolution: "@babel/plugin-transform-react-jsx@npm:7.22.15" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-module-imports": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/plugin-syntax-jsx": "npm:^7.22.5" + "@babel/types": "npm:^7.22.15" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a436bfbffe723d162e5816d510dca7349a1fc572c501d73f1e17bbca7eb899d7a6a14d8fc2ae5993dd79fdd77bcc68d295e59a3549bed03b8579c767f6e3c9dc + languageName: node + linkType: hard + "@babel/plugin-transform-react-jsx@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-jsx@npm:7.25.9" @@ -1260,6 +2108,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-pure-annotations@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.22.5" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/092021c4f404e267002099ec20b3f12dd730cb90b0d83c5feed3dc00dbe43b9c42c795a18e7c6c7d7bddea20c7dd56221b146aec81b37f2e7eb5137331c61120 + languageName: node + linkType: hard + "@babel/plugin-transform-react-pure-annotations@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.9" @@ -1272,6 +2132,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regenerator@npm:^7.22.10": + version: 7.22.10 + resolution: "@babel/plugin-transform-regenerator@npm:7.22.10" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + regenerator-transform: "npm:^0.15.2" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/e13678d62d6fa96f11cb8b863f00e8693491e7adc88bfca3f2820f80cbac8336e7dec3a596eee6a1c4663b7ececc3564f2cd7fb44ed6d4ce84ac2bb7f39ecc6e + languageName: node + linkType: hard + "@babel/plugin-transform-regenerator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-regenerator@npm:7.25.9" @@ -1284,6 +2156,29 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.26.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.25.9" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/726deca486bbd4b176f8a966eb0f4aabc19d9def3b8dabb8b3a656778eca0df1fda3f3c92b213aa5a184232fdafd5b7bd73b4e24ca4345c498ef6baff2bda4e1 + languageName: node + linkType: hard + +"@babel/plugin-transform-reserved-words@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-reserved-words@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/3ffd7dbc425fe8132bfec118b9817572799cab1473113a635d25ab606c1f5a2341a636c04cf6b22df3813320365ed5a965b5eeb3192320a10e4cc2c137bd8bfc + languageName: node + linkType: hard + "@babel/plugin-transform-reserved-words@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-reserved-words@npm:7.25.9" @@ -1295,6 +2190,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-shorthand-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a5ac902c56ea8effa99f681340ee61bac21094588f7aef0bc01dff98246651702e677552fa6d10e548c4ac22a3ffad047dd2f8c8f0540b68316c2c203e56818b + languageName: node + linkType: hard + "@babel/plugin-transform-shorthand-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.9" @@ -1306,6 +2212,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-spread@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-spread@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/f9fd247b3fa8953416c8808c124c3a5db5cd697abbf791aae0143a0587fff6b386045f94c62bcd1b6783a1fd275629cc194f25f6c0aafc9f05f12a56fd5f94bf + languageName: node + linkType: hard + "@babel/plugin-transform-spread@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-spread@npm:7.25.9" @@ -1318,6 +2236,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-sticky-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/63b2c575e3e7f96c32d52ed45ee098fb7d354b35c2223b8c8e76840b32cc529ee0c0ceb5742fd082e56e91e3d82842a367ce177e82b05039af3d602c9627a729 + languageName: node + linkType: hard + "@babel/plugin-transform-sticky-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.9" @@ -1329,6 +2258,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-template-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-template-literals@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/27e9bb030654cb425381c69754be4abe6a7c75b45cd7f962cd8d604b841b2f0fb7b024f2efc1c25cc53f5b16d79d5e8cfc47cacbdaa983895b3aeefa3e7e24ff + languageName: node + linkType: hard + "@babel/plugin-transform-template-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-template-literals@npm:7.25.9" @@ -1340,6 +2280,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typeof-symbol@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/82a53a63ffc3010b689ca9a54e5f53b2718b9f4b4a9818f36f9b7dba234f38a01876680553d2716a645a61920b5e6e4aaf8d4a0064add379b27ca0b403049512 + languageName: node + linkType: hard + "@babel/plugin-transform-typeof-symbol@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.9" @@ -1351,6 +2302,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/plugin-transform-typescript@npm:7.25.2" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.24.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/plugin-syntax-typescript": "npm:^7.24.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/50e017ffd131c08661daa22b6c759999bb7a6cdfbf683291ee4bcbea4ae839440b553d2f8896bcf049aca1d267b39f3b09e8336059e919e83149b5ad859671f6 + languageName: node + linkType: hard + "@babel/plugin-transform-typescript@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-typescript@npm:7.25.9" @@ -1366,6 +2332,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-escapes@npm:^7.22.10": + version: 7.22.10 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.22.10" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/807f40ed1324c8cb107c45358f1903384ca3f0ef1d01c5a3c5c9b271c8d8eec66936a3dcc8d75ddfceea9421420368c2e77ae3adef0a50557e778dfe296bf382 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.9" @@ -1377,6 +2354,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-property-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/2495e5f663cb388e3d888b4ba3df419ac436a5012144ac170b622ddfc221f9ea9bdba839fa2bc0185cb776b578030666406452ec7791cbf0e7a3d4c88ae9574c + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-property-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.9" @@ -1389,6 +2378,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/6b5d1404c8c623b0ec9bd436c00d885a17d6a34f3f2597996343ddb9d94f6379705b21582dfd4cec2c47fd34068872e74ab6b9580116c0566b3f9447e2a7fa06 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9" @@ -1401,6 +2402,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-sets-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/c042070f980b139547f8b0179efbc049ac5930abec7fc26ed7a41d89a048d8ab17d362200e204b6f71c3c20d6991a0e74415e1a412a49adc8131c2a40c04822e + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.9" @@ -1413,11 +2426,101 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:^7.23.2, @babel/preset-env@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/preset-env@npm:7.25.9" +"@babel/preset-env@npm:^7.23.2": + version: 7.23.2 + resolution: "@babel/preset-env@npm:7.23.2" dependencies: - "@babel/compat-data": "npm:^7.25.9" + "@babel/compat-data": "npm:^7.23.2" + "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-validator-option": "npm:^7.22.15" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.22.15" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.22.15" + "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/plugin-syntax-class-properties": "npm:^7.12.13" + "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" + "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" + "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" + "@babel/plugin-syntax-import-assertions": "npm:^7.22.5" + "@babel/plugin-syntax-import-attributes": "npm:^7.22.5" + "@babel/plugin-syntax-import-meta": "npm:^7.10.4" + "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" + "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" + "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" + "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" + "@babel/plugin-transform-arrow-functions": "npm:^7.22.5" + "@babel/plugin-transform-async-generator-functions": "npm:^7.23.2" + "@babel/plugin-transform-async-to-generator": "npm:^7.22.5" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.22.5" + "@babel/plugin-transform-block-scoping": "npm:^7.23.0" + "@babel/plugin-transform-class-properties": "npm:^7.22.5" + "@babel/plugin-transform-class-static-block": "npm:^7.22.11" + "@babel/plugin-transform-classes": "npm:^7.22.15" + "@babel/plugin-transform-computed-properties": "npm:^7.22.5" + "@babel/plugin-transform-destructuring": "npm:^7.23.0" + "@babel/plugin-transform-dotall-regex": "npm:^7.22.5" + "@babel/plugin-transform-duplicate-keys": "npm:^7.22.5" + "@babel/plugin-transform-dynamic-import": "npm:^7.22.11" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.22.5" + "@babel/plugin-transform-export-namespace-from": "npm:^7.22.11" + "@babel/plugin-transform-for-of": "npm:^7.22.15" + "@babel/plugin-transform-function-name": "npm:^7.22.5" + "@babel/plugin-transform-json-strings": "npm:^7.22.11" + "@babel/plugin-transform-literals": "npm:^7.22.5" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.22.11" + "@babel/plugin-transform-member-expression-literals": "npm:^7.22.5" + "@babel/plugin-transform-modules-amd": "npm:^7.23.0" + "@babel/plugin-transform-modules-commonjs": "npm:^7.23.0" + "@babel/plugin-transform-modules-systemjs": "npm:^7.23.0" + "@babel/plugin-transform-modules-umd": "npm:^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.22.5" + "@babel/plugin-transform-new-target": "npm:^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.22.11" + "@babel/plugin-transform-numeric-separator": "npm:^7.22.11" + "@babel/plugin-transform-object-rest-spread": "npm:^7.22.15" + "@babel/plugin-transform-object-super": "npm:^7.22.5" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.22.11" + "@babel/plugin-transform-optional-chaining": "npm:^7.23.0" + "@babel/plugin-transform-parameters": "npm:^7.22.15" + "@babel/plugin-transform-private-methods": "npm:^7.22.5" + "@babel/plugin-transform-private-property-in-object": "npm:^7.22.11" + "@babel/plugin-transform-property-literals": "npm:^7.22.5" + "@babel/plugin-transform-regenerator": "npm:^7.22.10" + "@babel/plugin-transform-reserved-words": "npm:^7.22.5" + "@babel/plugin-transform-shorthand-properties": "npm:^7.22.5" + "@babel/plugin-transform-spread": "npm:^7.22.5" + "@babel/plugin-transform-sticky-regex": "npm:^7.22.5" + "@babel/plugin-transform-template-literals": "npm:^7.22.5" + "@babel/plugin-transform-typeof-symbol": "npm:^7.22.5" + "@babel/plugin-transform-unicode-escapes": "npm:^7.22.10" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.22.5" + "@babel/plugin-transform-unicode-regex": "npm:^7.22.5" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.22.5" + "@babel/preset-modules": "npm:0.1.6-no-external-plugins" + "@babel/types": "npm:^7.23.0" + babel-plugin-polyfill-corejs2: "npm:^0.4.6" + babel-plugin-polyfill-corejs3: "npm:^0.8.5" + babel-plugin-polyfill-regenerator: "npm:^0.5.3" + core-js-compat: "npm:^3.31.0" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7bc8aeed59047f99af2f608f3143044517582b6bd7b041e3c7a12eface47e0313a57e78fad2e0d450cda2ce6c58451d67493f3d3677c5c1031cf59b7db1161c3 + languageName: node + linkType: hard + +"@babel/preset-env@npm:^7.25.9": + version: 7.26.0 + resolution: "@babel/preset-env@npm:7.26.0" + dependencies: + "@babel/compat-data": "npm:^7.26.0" "@babel/helper-compilation-targets": "npm:^7.25.9" "@babel/helper-plugin-utils": "npm:^7.25.9" "@babel/helper-validator-option": "npm:^7.25.9" @@ -1427,8 +2530,8 @@ __metadata: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9" "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.25.9" - "@babel/plugin-syntax-import-attributes": "npm:^7.25.9" + "@babel/plugin-syntax-import-assertions": "npm:^7.26.0" + "@babel/plugin-syntax-import-attributes": "npm:^7.26.0" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" "@babel/plugin-transform-arrow-functions": "npm:^7.25.9" "@babel/plugin-transform-async-generator-functions": "npm:^7.25.9" @@ -1436,7 +2539,7 @@ __metadata: "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.9" "@babel/plugin-transform-block-scoping": "npm:^7.25.9" "@babel/plugin-transform-class-properties": "npm:^7.25.9" - "@babel/plugin-transform-class-static-block": "npm:^7.25.9" + "@babel/plugin-transform-class-static-block": "npm:^7.26.0" "@babel/plugin-transform-classes": "npm:^7.25.9" "@babel/plugin-transform-computed-properties": "npm:^7.25.9" "@babel/plugin-transform-destructuring": "npm:^7.25.9" @@ -1469,6 +2572,7 @@ __metadata: "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9" "@babel/plugin-transform-property-literals": "npm:^7.25.9" "@babel/plugin-transform-regenerator": "npm:^7.25.9" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0" "@babel/plugin-transform-reserved-words": "npm:^7.25.9" "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9" "@babel/plugin-transform-spread": "npm:^7.25.9" @@ -1487,7 +2591,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/7a9ca1a19949426498fdffc37eed919f9581226ea45b18be764d29ce81bbf8c8f2f37152300c3524b7a3861831d33f10d481810f3011dff702f780d3f79aa789 + checksum: 10/a7a80314f845deea713985a6316361c476621c76cfe5c6c28e8b9558f01634b49bbfdd3581ef94b5d6cff5c2b8830468aa53a73f5b5c1224db2dfea5db7e676f languageName: node linkType: hard @@ -1517,7 +2621,23 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:^7.22.15, @babel/preset-react@npm:^7.25.9": +"@babel/preset-react@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/preset-react@npm:7.22.15" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-validator-option": "npm:^7.22.15" + "@babel/plugin-transform-react-display-name": "npm:^7.22.5" + "@babel/plugin-transform-react-jsx": "npm:^7.22.15" + "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/f9296e45346c3b6ab8296952edde5f1774cc9fdbdbefbc76047278fc3e889d3e15740f038ce017aca562d89f32fcbb6c11783d464fc6ae3066433178fa58513c + languageName: node + linkType: hard + +"@babel/preset-react@npm:^7.25.9": version: 7.25.9 resolution: "@babel/preset-react@npm:7.25.9" dependencies: @@ -1533,9 +2653,24 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.23.0, @babel/preset-typescript@npm:^7.24.7, @babel/preset-typescript@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/preset-typescript@npm:7.25.9" +"@babel/preset-typescript@npm:^7.23.0, @babel/preset-typescript@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/preset-typescript@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-validator-option": "npm:^7.24.7" + "@babel/plugin-syntax-jsx": "npm:^7.24.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.7" + "@babel/plugin-transform-typescript": "npm:^7.24.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/995e9783f8e474581e7533d6b10ec1fbea69528cc939ad8582b5937e13548e5215d25a8e2c845e7b351fdaa13139896b5e42ab3bde83918ea4e41773f10861ac + languageName: node + linkType: hard + +"@babel/preset-typescript@npm:^7.25.9": + version: 7.26.0 + resolution: "@babel/preset-typescript@npm:7.26.0" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" "@babel/helper-validator-option": "npm:^7.25.9" @@ -1544,11 +2679,26 @@ __metadata: "@babel/plugin-transform-typescript": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/bcb730ffc777e941eb34ade5052815b7091a0f1c49c6ae9515ebc3ffbfb52b2195dff3d289498b767e9ee898fc30ed100496f4f336a8be51725f2b4a73d7227a + checksum: 10/81a60826160163a3daae017709f42147744757b725b50c9024ef3ee5a402ee45fd2e93eaecdaaa22c81be91f7940916249cfb7711366431cfcacc69c95878c03 + languageName: node + linkType: hard + +"@babel/register@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/register@npm:7.22.15" + dependencies: + clone-deep: "npm:^4.0.1" + find-cache-dir: "npm:^2.0.0" + make-dir: "npm:^2.1.0" + pirates: "npm:^4.0.5" + source-map-support: "npm:^0.5.16" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/5497be6773608cd2d874210edd14499fce464ddbea170219da55955afe4c9173adb591164193458fd639e43b7d1314088a6186f4abf241476c59b3f0da6afd6f languageName: node linkType: hard -"@babel/register@npm:^7.22.15, @babel/register@npm:^7.25.9": +"@babel/register@npm:^7.25.9": version: 7.25.9 resolution: "@babel/register@npm:7.25.9" dependencies: @@ -1563,6 +2713,13 @@ __metadata: languageName: node linkType: hard +"@babel/regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "@babel/regjsgen@npm:0.8.0" + checksum: 10/c57fb730b17332b7572574b74364a77d70faa302a281a62819476fa3b09822974fd75af77aea603ad77378395be64e81f89f0e800bf86cbbf21652d49ce12ee8 + languageName: node + linkType: hard + "@babel/runtime-corejs3@npm:^7.10.2": version: 7.11.2 resolution: "@babel/runtime-corejs3@npm:7.11.2" @@ -1591,7 +2748,18 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/parser": "npm:^7.25.0" + "@babel/types": "npm:^7.25.0" + checksum: 10/07ebecf6db8b28244b7397628e09c99e7a317b959b926d90455c7253c88df3677a5a32d1501d9749fe292a263ff51a4b6b5385bcabd5dadd3a48036f4d4949e0 + languageName: node + linkType: hard + +"@babel/template@npm:^7.25.9": version: 7.25.9 resolution: "@babel/template@npm:7.25.9" dependencies: @@ -1620,7 +2788,22 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.25.9": +"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/traverse@npm:7.25.4" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/generator": "npm:^7.25.4" + "@babel/parser": "npm:^7.25.4" + "@babel/template": "npm:^7.25.0" + "@babel/types": "npm:^7.25.4" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10/a85c16047ab8e454e2e758c75c31994cec328bd6d8b4b22e915fa7393a03b3ab96d1218f43dc7ef77c957cc488dc38100bdf504d08a80a131e89b2e49cfa2be5 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.25.9": version: 7.25.9 resolution: "@babel/traverse@npm:7.25.9" dependencies: @@ -1646,7 +2829,18 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.13.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.13.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.25.4 + resolution: "@babel/types@npm:7.25.4" + dependencies: + "@babel/helper-string-parser": "npm:^7.24.8" + "@babel/helper-validator-identifier": "npm:^7.24.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10/d4a1194612d0a2a6ce9a0be325578b43d74e5f5278c67409468ba0a924341f0ad349ef0245ee8a36da3766efe5cc59cd6bb52547674150f97d8dc4c8cfa5d6b8 + languageName: node + linkType: hard + +"@babel/types@npm:^7.20.0, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0": version: 7.26.0 resolution: "@babel/types@npm:7.26.0" dependencies: @@ -4663,120 +5857,12 @@ __metadata: 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" - dependencies: - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^9.0.0" - checksum: 10/3d32d42c6e98fc4719b2b53597e573764b80936c7cc31d884c87729c4c4f74a30e93096db87aaa7cbcec9d3bb7d22b1adfc98a8bcb4c7c2f17bfbddaa4367d34 - languageName: node - linkType: hard - -"@metamask/account-watcher@npm:^4.1.1": - version: 4.1.1 - resolution: "@metamask/account-watcher@npm:4.1.1" - dependencies: - "@ethereumjs/tx": "npm:^5.1.0" - "@ethereumjs/util": "npm:^9.0.1" - "@metamask/keyring-api": "npm:^8.1.3" - "@metamask/snaps-sdk": "npm:^6.2.1" - "@metamask/utils": "npm:^8.3.0" - ethers: "npm:^5.7.2" - uuid: "npm:^9.0.0" - checksum: 10/a1b53cdcd3a5844c1edd2e91bf6d2e5a1f3914f795c928f9611c56bc4133c8338e4ae491cb2fda7273e59830a1d613ce17997a0639bb82ec5c71c2f0b260d88e - languageName: node - linkType: hard - -"@metamask/accounts-controller@npm:^17.2.0": - version: 17.2.0 - resolution: "@metamask/accounts-controller@npm:17.2.0" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@metamask/base-controller": "npm:^6.0.0" - "@metamask/eth-snap-keyring": "npm:^4.3.1" - "@metamask/keyring-api": "npm:^8.0.0" - "@metamask/keyring-controller": "npm:^17.1.0" - "@metamask/snaps-sdk": "npm:^4.2.0" - "@metamask/snaps-utils": "npm:^7.4.0" - "@metamask/utils": "npm:^8.3.0" - deepmerge: "npm:^4.2.2" - ethereum-cryptography: "npm:^2.1.2" - immer: "npm:^9.0.6" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/keyring-controller": ^17.0.0 - "@metamask/snaps-controllers": ^8.1.1 - checksum: 10/aa2bb7162d3df6a31824607405990947d64af2b4a11515526e4882985088832919fb26afb45e27330d9262f40f27a89805871052af595facb75fb4a510c83cb1 - languageName: node - linkType: hard - -"@metamask/accounts-controller@npm:^18.2.2": - version: 18.2.2 - resolution: "@metamask/accounts-controller@npm:18.2.2" - dependencies: - "@ethereumjs/util": "npm:^8.1.0" - "@metamask/base-controller": "npm:^7.0.1" - "@metamask/eth-snap-keyring": "npm:^4.3.6" - "@metamask/keyring-api": "npm:^8.1.3" - "@metamask/snaps-sdk": "npm:^6.5.0" - "@metamask/snaps-utils": "npm:^8.1.1" - "@metamask/utils": "npm:^9.1.0" - deepmerge: "npm:^4.2.2" - ethereum-cryptography: "npm:^2.1.2" - immer: "npm:^9.0.6" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/keyring-controller": ^17.0.0 - "@metamask/snaps-controllers": ^9.7.0 - checksum: 10/095be37c94a577304425f80600d4ef847c83c702ccf3d6b1591602d1fe292bdd3273131e336d6108bd713bff38812dfc4d7b21d4075669cde24e12f117f2dd81 - languageName: node - linkType: hard - -"@metamask/address-book-controller@npm:^6.0.0": - version: 6.0.0 - resolution: "@metamask/address-book-controller@npm:6.0.0" - dependencies: - "@metamask/base-controller": "npm:^7.0.0" - "@metamask/controller-utils": "npm:^11.2.0" - "@metamask/utils": "npm:^9.1.0" - checksum: 10/e699b97fc798a363390d673b766737dc10f82a1eefcf119823d8f4370846d6708b3b2eadd177c8b2cb826afa7e38b51cf978a0d55cd51e92e7a9ffe83f5f0803 - languageName: node - linkType: hard - -"@metamask/announcement-controller@npm:^7.0.0": - version: 7.0.0 - resolution: "@metamask/announcement-controller@npm:7.0.0" - dependencies: - "@metamask/base-controller": "npm:^6.0.0" - checksum: 10/0f8c9112a6514fd2dc4c135d1ab0445f627451d0583ef2eb92f52f133a448fd97b67d5aa615b7409f4380a01590546376ccc6b728d94cf32a4b62686e18c0a4d - languageName: node - linkType: hard - -"@metamask/api-specs@npm:^0.9.3": - version: 0.9.3 - resolution: "@metamask/api-specs@npm:0.9.3" - checksum: 10/803852ba43a0fbabb43aeba2ca63e43d22a99d35710700aa04c92cc85184c93024b052b2ee43831762341848de42d172c99485fa7b659249e75255ff8d29d0b2 - languageName: node - linkType: hard - -"@metamask/approval-controller@npm:^7.0.0, @metamask/approval-controller@npm:^7.0.2": - version: 7.0.2 - resolution: "@metamask/approval-controller@npm:7.0.2" - dependencies: - "@metamask/base-controller": "npm:^6.0.2" - "@metamask/rpc-errors": "npm:^6.3.1" - "@metamask/utils": "npm:^9.1.0" - nanoid: "npm:^3.1.31" - checksum: 10/0ce1f607f11b5c8c9d6a462e89935388187f87d5627814882c8ce808b2e84bd727028f92708ac99c59c638578aadd5e91cb2799d8c8e4be497ee646f39821ea6 - languageName: node - linkType: hard - -"@metamask/assets-controllers@npm:42.0.0": - version: 42.0.0 - resolution: "@metamask/assets-controllers@npm:42.0.0" +"@metamask-previews/assets-controllers@npm:42.0.0-preview-651fe366": + version: 42.0.0-preview-651fe366 + resolution: "@metamask-previews/assets-controllers@npm:42.0.0-preview-651fe366" dependencies: "@ethereumjs/util": "npm:^8.1.0" + "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/address": "npm:^5.7.0" "@ethersproject/bignumber": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" @@ -4806,15 +5892,125 @@ __metadata: "@metamask/keyring-controller": ^17.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/preferences-controller": ^13.0.0 - checksum: 10/64d2bd43139ee5c19bd665b07212cd5d5dd41b457dedde3b5db31442292c4d064dc015011f5f001bb423683675fb20898ff652e91d2339ad1d21cc45fa93487a + checksum: 10/879898c343d2c5c35d5abb98053e1c5b634e1791d49c8f0e8f0db226999139c59b192feb6fd04ff34c1d9b6de5c03628b846eca6ffe804ee8f6c37fe47432511 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/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" + dependencies: + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^9.0.0" + checksum: 10/3d32d42c6e98fc4719b2b53597e573764b80936c7cc31d884c87729c4c4f74a30e93096db87aaa7cbcec9d3bb7d22b1adfc98a8bcb4c7c2f17bfbddaa4367d34 + languageName: node + linkType: hard + +"@metamask/account-watcher@npm:^4.1.1": + version: 4.1.1 + resolution: "@metamask/account-watcher@npm:4.1.1" + dependencies: + "@ethereumjs/tx": "npm:^5.1.0" + "@ethereumjs/util": "npm:^9.0.1" + "@metamask/keyring-api": "npm:^8.1.3" + "@metamask/snaps-sdk": "npm:^6.2.1" + "@metamask/utils": "npm:^8.3.0" + ethers: "npm:^5.7.2" + uuid: "npm:^9.0.0" + checksum: 10/a1b53cdcd3a5844c1edd2e91bf6d2e5a1f3914f795c928f9611c56bc4133c8338e4ae491cb2fda7273e59830a1d613ce17997a0639bb82ec5c71c2f0b260d88e + languageName: node + linkType: hard + +"@metamask/accounts-controller@npm:^17.2.0": + version: 17.2.0 + resolution: "@metamask/accounts-controller@npm:17.2.0" dependencies: "@ethereumjs/util": "npm:^8.1.0" + "@metamask/base-controller": "npm:^6.0.0" + "@metamask/eth-snap-keyring": "npm:^4.3.1" + "@metamask/keyring-api": "npm:^8.0.0" + "@metamask/keyring-controller": "npm:^17.1.0" + "@metamask/snaps-sdk": "npm:^4.2.0" + "@metamask/snaps-utils": "npm:^7.4.0" + "@metamask/utils": "npm:^8.3.0" + deepmerge: "npm:^4.2.2" + ethereum-cryptography: "npm:^2.1.2" + immer: "npm:^9.0.6" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/keyring-controller": ^17.0.0 + "@metamask/snaps-controllers": ^8.1.1 + checksum: 10/aa2bb7162d3df6a31824607405990947d64af2b4a11515526e4882985088832919fb26afb45e27330d9262f40f27a89805871052af595facb75fb4a510c83cb1 + languageName: node + linkType: hard + +"@metamask/accounts-controller@npm:^18.2.2": + version: 18.2.2 + resolution: "@metamask/accounts-controller@npm:18.2.2" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@metamask/base-controller": "npm:^7.0.1" + "@metamask/eth-snap-keyring": "npm:^4.3.6" + "@metamask/keyring-api": "npm:^8.1.3" + "@metamask/snaps-sdk": "npm:^6.5.0" + "@metamask/snaps-utils": "npm:^8.1.1" + "@metamask/utils": "npm:^9.1.0" + deepmerge: "npm:^4.2.2" + ethereum-cryptography: "npm:^2.1.2" + immer: "npm:^9.0.6" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/keyring-controller": ^17.0.0 + "@metamask/snaps-controllers": ^9.7.0 + checksum: 10/095be37c94a577304425f80600d4ef847c83c702ccf3d6b1591602d1fe292bdd3273131e336d6108bd713bff38812dfc4d7b21d4075669cde24e12f117f2dd81 + languageName: node + linkType: hard + +"@metamask/address-book-controller@npm:^6.0.0": + version: 6.0.0 + resolution: "@metamask/address-book-controller@npm:6.0.0" + dependencies: + "@metamask/base-controller": "npm:^7.0.0" + "@metamask/controller-utils": "npm:^11.2.0" + "@metamask/utils": "npm:^9.1.0" + checksum: 10/e699b97fc798a363390d673b766737dc10f82a1eefcf119823d8f4370846d6708b3b2eadd177c8b2cb826afa7e38b51cf978a0d55cd51e92e7a9ffe83f5f0803 + languageName: node + linkType: hard + +"@metamask/announcement-controller@npm:^7.0.0": + version: 7.0.0 + resolution: "@metamask/announcement-controller@npm:7.0.0" + dependencies: + "@metamask/base-controller": "npm:^6.0.0" + checksum: 10/0f8c9112a6514fd2dc4c135d1ab0445f627451d0583ef2eb92f52f133a448fd97b67d5aa615b7409f4380a01590546376ccc6b728d94cf32a4b62686e18c0a4d + languageName: node + linkType: hard + +"@metamask/api-specs@npm:^0.9.3": + version: 0.9.3 + resolution: "@metamask/api-specs@npm:0.9.3" + checksum: 10/803852ba43a0fbabb43aeba2ca63e43d22a99d35710700aa04c92cc85184c93024b052b2ee43831762341848de42d172c99485fa7b659249e75255ff8d29d0b2 + languageName: node + linkType: hard + +"@metamask/approval-controller@npm:^7.0.0, @metamask/approval-controller@npm:^7.0.2": + version: 7.0.2 + resolution: "@metamask/approval-controller@npm:7.0.2" + dependencies: + "@metamask/base-controller": "npm:^6.0.2" + "@metamask/rpc-errors": "npm:^6.3.1" + "@metamask/utils": "npm:^9.1.0" + nanoid: "npm:^3.1.31" + checksum: 10/0ce1f607f11b5c8c9d6a462e89935388187f87d5627814882c8ce808b2e84bd727028f92708ac99c59c638578aadd5e91cb2799d8c8e4be497ee646f39821ea6 + languageName: node + linkType: hard + +"@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@42.0.0-preview-651fe366#./.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch::locator=metamask-crx%40workspace%3A.": + version: 42.0.0-preview-651fe366 + resolution: "@metamask/assets-controllers@patch:@metamask-previews/assets-controllers@npm%3A42.0.0-preview-651fe366#./.yarn/patches/@metamask-assets-controllers-npm-42.0.0-57b3d695bb.patch::version=42.0.0-preview-651fe366&hash=e14ff8&locator=metamask-crx%40workspace%3A." + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/address": "npm:^5.7.0" "@ethersproject/bignumber": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" @@ -4844,7 +6040,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/89d4bb17cf30e35229083a97135e9dc72644aee35b0b4915e2e79e8e0bf09c2d0e17c381f76aa559952db5488f9301e32cb654cb5e080b835e98b8c808daa250 languageName: node linkType: hard @@ -4882,7 +6078,17 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1, @metamask/base-controller@npm:^7.0.2": +"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1": + version: 7.0.1 + resolution: "@metamask/base-controller@npm:7.0.1" + dependencies: + "@metamask/utils": "npm:^9.1.0" + immer: "npm:^9.0.6" + checksum: 10/774b6d68ac95a5ec187e890d321bede50065f8a6f1ba7b49a19f5971366274054ac0e401548b51d3b014d0bca5d650409fb554dd13ce120e7fb3495b4e8e67b1 + languageName: node + linkType: hard + +"@metamask/base-controller@npm:^7.0.2": version: 7.0.2 resolution: "@metamask/base-controller@npm:7.0.2" dependencies: @@ -4925,7 +6131,24 @@ __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, @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": + version: 11.3.0 + resolution: "@metamask/controller-utils@npm:11.3.0" + 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/3200228d1f4ea5fa095228db4e5050529caf0470e072382eb8f7571bb9b07515516ca9e846b7751388399d9ae967e4985dafd6120902ef6c998e98f4eb36d964 + languageName: node + linkType: hard + +"@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: @@ -5490,7 +6713,18 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-engine@npm:^10.0.0, @metamask/json-rpc-engine@npm:^10.0.1": +"@metamask/json-rpc-engine@npm:^10.0.0": + version: 10.0.0 + resolution: "@metamask/json-rpc-engine@npm:10.0.0" + dependencies: + "@metamask/rpc-errors": "npm:^7.0.0" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^9.1.0" + checksum: 10/2c401a4a64392aeb11c4f7ca8d7b458ba1106cff1e0b3dba8b3e0cc90e82f8c55ac2dc9fdfcd914b289e3298fb726d637cf21382336dde2c207cf76129ce5eab + languageName: node + linkType: hard + +"@metamask/json-rpc-engine@npm:^10.0.1": version: 10.0.1 resolution: "@metamask/json-rpc-engine@npm:10.0.1" dependencies: @@ -5534,15 +6768,27 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-middleware-stream@npm:^8.0.1, @metamask/json-rpc-middleware-stream@npm:^8.0.2, @metamask/json-rpc-middleware-stream@npm:^8.0.4": - version: 8.0.4 - resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.4" +"@metamask/json-rpc-middleware-stream@npm:^8.0.1, @metamask/json-rpc-middleware-stream@npm:^8.0.2": + version: 8.0.2 + resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.2" dependencies: - "@metamask/json-rpc-engine": "npm:^10.0.0" + "@metamask/json-rpc-engine": "npm:^9.0.2" "@metamask/safe-event-emitter": "npm:^3.0.0" "@metamask/utils": "npm:^9.1.0" readable-stream: "npm:^3.6.2" - checksum: 10/93c842e1ac8e624c65d888cb3539b38ade5b8415ea45f649d78dad91e7139f11fa96bbf89136998d21def7711b3f710939f8e4498ce31a6cf461892e3f4ba176 + checksum: 10/aaf41cb6fa015494eb0424959d14022b1355c390066898603223e3418d93bd72249b6e54caee3e23b4d6a679f389c2374f687882f2a7202379b4f4b042a84974 + languageName: node + linkType: hard + +"@metamask/json-rpc-middleware-stream@npm:^8.0.4": + version: 8.0.5 + resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.5" + dependencies: + "@metamask/json-rpc-engine": "npm:^10.0.1" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^10.0.0" + readable-stream: "npm:^3.6.2" + checksum: 10/486a4c64d445dc7ac7927ac5b9d01818ecef3fbb23d17eadada4748ed6cae9e259741e3c9380829b04a5c141d0972384647aedfde906dc83501b9d7f700ed621 languageName: node linkType: hard @@ -5861,7 +7107,23 @@ __metadata: languageName: node linkType: hard -"@metamask/phishing-controller@npm:^12.0.2, @metamask/phishing-controller@npm:^12.3.0": +"@metamask/phishing-controller@npm:^12.0.2": + version: 12.0.2 + resolution: "@metamask/phishing-controller@npm:12.0.2" + dependencies: + "@metamask/base-controller": "npm:^7.0.0" + "@metamask/controller-utils": "npm:^11.2.0" + "@noble/hashes": "npm:^1.4.0" + "@types/punycode": "npm:^2.1.0" + eth-phishing-detect: "npm:^1.2.0" + ethereum-cryptography: "npm:^2.1.2" + fastest-levenshtein: "npm:^1.0.16" + punycode: "npm:^2.1.1" + checksum: 10/78781e1b781c838e303677157616fb3b5e581030fe8f0ed8913f6b75fbcb7ee2ba59a44831936cc68cca8b295ef6546761b40ea3277d810b68d8ed39a58d0e29 + languageName: node + linkType: hard + +"@metamask/phishing-controller@npm:^12.3.0": version: 12.3.0 resolution: "@metamask/phishing-controller@npm:12.3.0" dependencies: @@ -6090,7 +7352,17 @@ __metadata: languageName: node linkType: hard -"@metamask/rpc-errors@npm:^7.0.0, @metamask/rpc-errors@npm:^7.0.1": +"@metamask/rpc-errors@npm:^7.0.0": + version: 7.0.0 + resolution: "@metamask/rpc-errors@npm:7.0.0" + dependencies: + "@metamask/utils": "npm:^9.0.0" + fast-safe-stringify: "npm:^2.0.6" + checksum: 10/f25e2a5506d4d0d6193c88aef8f035ec189a1177f8aee8fa01c9a33d73b1536ca7b5eea2fb33a477768bbd2abaf16529e68f0b3cf714387e5d6c9178225354fd + languageName: node + linkType: hard + +"@metamask/rpc-errors@npm:^7.0.1": version: 7.0.1 resolution: "@metamask/rpc-errors@npm:7.0.1" dependencies: @@ -6430,8 +7702,8 @@ __metadata: linkType: hard "@metamask/transaction-controller@npm:^38.1.0": - version: 38.1.0 - resolution: "@metamask/transaction-controller@npm:38.1.0" + version: 38.2.0 + resolution: "@metamask/transaction-controller@npm:38.2.0" dependencies: "@ethereumjs/common": "npm:^3.2.0" "@ethereumjs/tx": "npm:^4.2.0" @@ -6440,7 +7712,7 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/base-controller": "npm:^7.0.2" - "@metamask/controller-utils": "npm:^11.4.1" + "@metamask/controller-utils": "npm:^11.4.2" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" "@metamask/nonce-tracker": "npm:^6.0.0" @@ -6458,7 +7730,7 @@ __metadata: "@metamask/approval-controller": ^7.0.0 "@metamask/gas-fee-controller": ^22.0.0 "@metamask/network-controller": ^22.0.0 - checksum: 10/c1bdca52bbbce42a76ec9c640197534ec6c223b0f5d5815acfa53490dc1175850ea9aeeb6ae3c5ec34218f0bdbbbeb3e8731e2552aa9411e3ed7798a5dea8ab5 + checksum: 10/7856d2998c711bc4f4645a6845ae2b18c5312672f31377c9aeb3614fc3c5825ed3d76971f937cd55a30c26b63b0e69ea0abeb3c88c7e1134c01eac5bbc11b4d0 languageName: node linkType: hard @@ -13243,6 +14515,19 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-corejs2@npm:^0.4.6": + version: 0.4.6 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6" + dependencies: + "@babel/compat-data": "npm:^7.22.6" + "@babel/helper-define-polyfill-provider": "npm:^0.4.3" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/736b1bb8e570be029f941a374c769972af870c96b5c324a5387c6b6994aabdad045ce560c530038c8626f02ec70f711ad7445f2572c32ba81fa0e13402cc23f8 + languageName: node + linkType: hard + "babel-plugin-polyfill-corejs3@npm:^0.10.6": version: 0.10.6 resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" @@ -13255,6 +14540,29 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-corejs3@npm:^0.8.5": + version: 0.8.5 + resolution: "babel-plugin-polyfill-corejs3@npm:0.8.5" + dependencies: + "@babel/helper-define-polyfill-provider": "npm:^0.4.3" + core-js-compat: "npm:^3.32.2" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/5c2ac3615bd064f294a0b36bf6a1939995ec510173602e317fb18b1c015d31f46e2dd885faa3376e4da22785a515e5ba37e069f0008e5eea830d2fe3b0e66a27 + languageName: node + linkType: hard + +"babel-plugin-polyfill-regenerator@npm:^0.5.3": + version: 0.5.3 + resolution: "babel-plugin-polyfill-regenerator@npm:0.5.3" + dependencies: + "@babel/helper-define-polyfill-provider": "npm:^0.4.3" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/2bb546582cda1870d19e646a7183baeb2cccd56e0ef3e4eaeabd28e120daf17cb87399194a9ccdcf32506bcaa68d23e73440fc8ab990a7a0f8c5a77c12d5d4bc + languageName: node + linkType: hard + "babel-plugin-polyfill-regenerator@npm:^0.6.1": version: 0.6.2 resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" @@ -14079,7 +15387,21 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.12.0, browserslist@npm:^4.21.10, browserslist@npm:^4.23.0, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0": +"browserslist@npm:^4.12.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.9, browserslist@npm:^4.22.1, browserslist@npm:^4.23.0": + version: 4.23.0 + resolution: "browserslist@npm:4.23.0" + dependencies: + caniuse-lite: "npm:^1.0.30001587" + electron-to-chromium: "npm:^1.4.668" + node-releases: "npm:^2.0.14" + update-browserslist-db: "npm:^1.0.13" + bin: + browserslist: cli.js + checksum: 10/496c3862df74565dd942b4ae65f502c575cbeba1fa4a3894dad7aa3b16130dc3033bc502d8848147f7b625154a284708253d9598bcdbef5a1e34cf11dc7bad8e + languageName: node + linkType: hard + +"browserslist@npm:^4.24.0, browserslist@npm:^4.24.2": version: 4.24.2 resolution: "browserslist@npm:4.24.2" dependencies: @@ -14529,10 +15851,17 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001669": - version: 1.0.30001669 - resolution: "caniuse-lite@npm:1.0.30001669" - checksum: 10/cd0b481bb997703cb7651e55666b4aa4e7b4ecf9784796e2393179a15e55c71a6abc6ff865c922bbd3bbfa4a4bf0530d8da13989b97ff8c7850c8a5bd4e00491 +"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001587, caniuse-lite@npm:^1.0.30001599": + version: 1.0.30001660 + resolution: "caniuse-lite@npm:1.0.30001660" + checksum: 10/5d83f0b7e2075b7e31f114f739155dc6c21b0afe8cb61180f625a4903b0ccd3d7591a5f81c930f14efddfa57040203ba0890850b8a3738f6c7f17c7dd83b9de8 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001669": + version: 1.0.30001677 + resolution: "caniuse-lite@npm:1.0.30001677" + checksum: 10/e07439bdeade5ffdd974691f44f8549ae0730fcf510acaa32d0b657c10370cd5aad09eeca37248966205fb37fce5f464dbce73ce177b4a1fdc3a34adbcfd7192 languageName: node linkType: hard @@ -15623,12 +16952,21 @@ __metadata: languageName: node linkType: hard +"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.32.2": + version: 3.33.0 + resolution: "core-js-compat@npm:3.33.0" + dependencies: + browserslist: "npm:^4.22.1" + checksum: 10/b1a5f7aab1c6ac0efd86c1412a5b27fb372c4e52c4b8f2c80b05216385125c4de30e4c36e4bcc6bfeec917a56e7736c87fab6a301ff8faaa1ae4acf81643fc9a + languageName: node + linkType: hard + "core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": - version: 3.38.1 - resolution: "core-js-compat@npm:3.38.1" + version: 3.39.0 + resolution: "core-js-compat@npm:3.39.0" dependencies: - browserslist: "npm:^4.23.3" - checksum: 10/4e2f219354fd268895f79486461a12df96f24ed307321482fe2a43529c5a64e7c16bcba654980ba217d603444f5141d43a79058aeac77511085f065c5da72207 + browserslist: "npm:^4.24.2" + checksum: 10/82d5fcb54087f1fc174283c2d30b62908edc828537574f95bb49a5b7f235bcc88ba43f37dbe470c47e17fd9bc01cbc1db905062fd96ba65ff1a03c235f288aca languageName: node linkType: hard @@ -17372,10 +18710,17 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.4.668": + version: 1.4.715 + resolution: "electron-to-chromium@npm:1.4.715" + checksum: 10/0fc9fc9fe2c4082c87672d229437c918f43c19ad81274afcdf2d36fba96bfaaee0d9254c309879fbea8eeb2c13fd1b5cf51e0967d55790206697914cecff9c6b + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.5.41": - version: 1.5.45 - resolution: "electron-to-chromium@npm:1.5.45" - checksum: 10/659b4b979c9c1a63c170c398775daa269acf5c4117f6590ad4677266fa77a680ebf7792e0eb8dc6d4041550e4ec82ad7dd3aac75543d30535b53bc3c1e4d05ff + version: 1.5.50 + resolution: "electron-to-chromium@npm:1.5.50" + checksum: 10/635ca4b593e64697fbebc9fe7f557abcb030e5f6edcefb596ae3f8c9313221a754b513b70f2ba12595a9ee5733442b2b58db9eed7a2fa63e9f7539d581dd4ac0 languageName: node linkType: hard @@ -17968,7 +19313,14 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1, escalade@npm:^3.2.0": +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: 10/afa618e73362576b63f6ca83c975456621095a1ed42ff068174e3f5cea48afc422814dda548c96e6ebb5333e7265140c7292abcc81bbd6ccb1757d50d3a4e182 + languageName: node + linkType: hard + +"escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 @@ -24401,6 +25753,15 @@ __metadata: languageName: node linkType: hard +"jsesc@npm:^2.5.1": + version: 2.5.2 + resolution: "jsesc@npm:2.5.2" + bin: + jsesc: bin/jsesc + checksum: 10/d2096abdcdec56969764b40ffc91d4a23408aa2f351b4d1c13f736f25476643238c43fdbaf38a191c26b1b78fd856d965f5d4d0dde7b89459cd94025190cdf13 + languageName: node + linkType: hard + "jsesc@npm:^3.0.2, jsesc@npm:~3.0.2": version: 3.0.2 resolution: "jsesc@npm:3.0.2" @@ -24410,6 +25771,15 @@ __metadata: languageName: node linkType: hard +"jsesc@npm:~0.5.0": + version: 0.5.0 + resolution: "jsesc@npm:0.5.0" + bin: + jsesc: bin/jsesc + checksum: 10/fab949f585c71e169c5cbe00f049f20de74f067081bbd64a55443bad1c71e1b5a5b448f2359bf2fe06f5ed7c07e2e4a9101843b01c823c30b6afc11f5bfaf724 + languageName: node + linkType: hard + "json-buffer@npm:3.0.0": version: 3.0.0 resolution: "json-buffer@npm:3.0.0" @@ -27282,14 +28652,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.9.1": - version: 2.9.1 - resolution: "mini-css-extract-plugin@npm:2.9.1" + version: 2.9.2 + resolution: "mini-css-extract-plugin@npm:2.9.2" dependencies: schema-utils: "npm:^4.0.0" tapable: "npm:^2.2.1" peerDependencies: webpack: ^5.0.0 - checksum: 10/a4a0c73a054254784b9d39a3a4f117691600355125242dfc46ced0912b4937050823478bdbf403b5392c21e2fb2203902b41677d67c7d668f77b985b594e94c6 + checksum: 10/db6ddb8ba56affa1a295b57857d66bad435d36e48e1f95c75d16fadd6c70e3ba33e8c4141c3fb0e22b4d875315b41c4f58550c6ac73b50bdbe429f768297e3ff languageName: node linkType: hard @@ -28127,6 +29497,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 10/0f7607ec7db5ef1dc616899a5f24ae90c869b6a54c2d4f36ff6d84a282ab9343c7ff3ca3670fe4669171bb1e8a9b3e286e1ef1c131f09a83d70554f855d54f24 + languageName: node + linkType: hard + "node-releases@npm:^2.0.18": version: 2.0.18 resolution: "node-releases@npm:2.0.18" @@ -29393,7 +30770,14 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0": +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: 10/a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.0": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -29489,7 +30873,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.4, pirates@npm:^4.0.6": +"pirates@npm:^4.0.4, pirates@npm:^4.0.5, pirates@npm:^4.0.6": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 10/d02dda76f4fec1cbdf395c36c11cf26f76a644f9f9a1bfa84d3167d0d3154d5289aacc72677aa20d599bb4a6937a471de1b65c995e2aea2d8687cbcd7e43ea5f @@ -31599,6 +32983,15 @@ __metadata: languageName: node linkType: hard +"regenerate-unicode-properties@npm:^10.1.0": + version: 10.1.0 + resolution: "regenerate-unicode-properties@npm:10.1.0" + dependencies: + regenerate: "npm:^1.4.2" + checksum: 10/25b268659898955ad105267b4efba20e361e27b233670694b683728a2800314bec3053918d3bf71b0604376fd76fe9bc9c6f80379cfb6d1e209a58de44101aac + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.2.0": version: 10.2.0 resolution: "regenerate-unicode-properties@npm:10.2.0" @@ -31697,6 +33090,20 @@ __metadata: languageName: node linkType: hard +"regexpu-core@npm:^5.3.1": + version: 5.3.2 + resolution: "regexpu-core@npm:5.3.2" + dependencies: + "@babel/regjsgen": "npm:^0.8.0" + regenerate: "npm:^1.4.2" + regenerate-unicode-properties: "npm:^10.1.0" + regjsparser: "npm:^0.9.1" + unicode-match-property-ecmascript: "npm:^2.0.0" + unicode-match-property-value-ecmascript: "npm:^2.1.0" + checksum: 10/ed0d7c66d84c633fbe8db4939d084c780190eca11f6920807dfb8ebac59e2676952cd8f2008d9c86ae8cf0463ea5fd12c5cff09ef2ce7d51ee6b420a5eb4d177 + languageName: node + linkType: hard + "regexpu-core@npm:^6.1.1": version: 6.1.1 resolution: "regexpu-core@npm:6.1.1" @@ -31756,13 +33163,24 @@ __metadata: linkType: hard "regjsparser@npm:^0.11.0": - version: 0.11.1 - resolution: "regjsparser@npm:0.11.1" + version: 0.11.2 + resolution: "regjsparser@npm:0.11.2" dependencies: jsesc: "npm:~3.0.2" bin: regjsparser: bin/parser - checksum: 10/06295f1666f8e378c3b70eb01578b46e075eee0556865a297497ab40753f04cce526e96513b18e21e66b79c972e7377bd3b5caa86935ed5d736e9b3e0f857363 + checksum: 10/8075eb76d6cde8a3f188696eb18ebf229376944d35e3043f73b889a15156cf539f2801941a5630433060512cbcb2f92f6a194fac44f2e0f1497517e12aa565b3 + languageName: node + linkType: hard + +"regjsparser@npm:^0.9.1": + version: 0.9.1 + resolution: "regjsparser@npm:0.9.1" + dependencies: + jsesc: "npm:~0.5.0" + bin: + regjsparser: bin/parser + checksum: 10/be7757ef76e1db10bf6996001d1021048b5fb12f5cb470a99b8cf7f3ff943f0f0e2291c0dcdbb418b458ddc4ac10e48680a822b69ef487a0284c8b6b77beddc3 languageName: node linkType: hard @@ -36314,6 +37732,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.0.13": + version: 1.0.13 + resolution: "update-browserslist-db@npm:1.0.13" + dependencies: + escalade: "npm:^3.1.1" + picocolors: "npm:^1.0.0" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10/9074b4ef34d2ed931f27d390aafdd391ee7c45ad83c508e8fed6aaae1eb68f81999a768ed8525c6f88d4001a4fbf1b8c0268f099d0e8e72088ec5945ac796acf + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.1.1": version: 1.1.1 resolution: "update-browserslist-db@npm:1.1.1" @@ -37915,7 +39347,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.3.4, yaml@npm:^2.4.1": +"yaml@npm:^2.3.4": version: 2.6.0 resolution: "yaml@npm:2.6.0" bin: @@ -37924,6 +39356,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.4.1": + version: 2.4.1 + resolution: "yaml@npm:2.4.1" + bin: + yaml: bin.mjs + checksum: 10/2c54fd69ef59126758ae710f9756405a7d41abcbb61aca894250d0e81e76057c14dc9bb00a9528f72f99b8f24077f694a6f7fd09cdd6711fcec2eebfbb5df409 + languageName: node + linkType: hard + "yargs-parser@npm:20.2.4": version: 20.2.4 resolution: "yargs-parser@npm:20.2.4" From c2b6afef81724ff1150a324590c2f5e940904661 Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Sun, 3 Nov 2024 18:47:33 -0800 Subject: [PATCH 29/73] Update metamask-controller.js --- app/scripts/metamask-controller.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 358552588947..f230cb1444b2 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1804,6 +1804,8 @@ export default class MetamaskController extends EventEmitter { trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind( this.metaMetricsController, ), + useAccountsAPI: true, + platform: 'extension', }); const addressBookControllerMessenger = From bb1d6bfc5685e80d636e2a7f663a52cdc0928e7c Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Mon, 4 Nov 2024 09:46:48 -0800 Subject: [PATCH 30/73] cleanup --- ui/contexts/tokenRates.tsx | 12 ------------ ui/pages/index.js | 4 +--- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 ui/contexts/tokenRates.tsx diff --git a/ui/contexts/tokenRates.tsx b/ui/contexts/tokenRates.tsx deleted file mode 100644 index d5764a95d675..000000000000 --- a/ui/contexts/tokenRates.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, { ReactElement } from 'react'; -import useTokenRatesPolling from '../hooks/useTokenRatesPolling'; - -export const TokenRatesProvider = ({ - children, -}: { - children: ReactElement; -}) => { - useTokenRatesPolling(); - - return <>{children}; -}; \ No newline at end of file diff --git a/ui/pages/index.js b/ui/pages/index.js index bd3a9efd8578..c30846fff1e6 100644 --- a/ui/pages/index.js +++ b/ui/pages/index.js @@ -51,9 +51,7 @@ class Index extends PureComponent { - - - + From 8e752a1eaa4aca3c501b18c5965bdf41b6e8e79d Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Mon, 4 Nov 2024 09:49:27 -0800 Subject: [PATCH 31/73] yarn --- yarn.lock | 1675 ++++------------------------------------------------- 1 file changed, 118 insertions(+), 1557 deletions(-) diff --git a/yarn.lock b/yarn.lock index da908500d7af..766f013c02b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,38 +88,20 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/code-frame@npm:7.24.7" - dependencies: - "@babel/highlight": "npm:^7.24.7" - picocolors: "npm:^1.0.0" - checksum: 10/4812e94885ba7e3213d49583a155fdffb05292330f0a9b2c41b49288da70cf3c746a3fda0bf1074041a6d741c33f8d7be24be5e96f41ef77395eeddc5c9ff624 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.25.9": - version: 7.26.2 - resolution: "@babel/code-frame@npm:7.26.2" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/code-frame@npm:7.25.9" dependencies: - "@babel/helper-validator-identifier": "npm:^7.25.9" - js-tokens: "npm:^4.0.0" + "@babel/highlight": "npm:^7.25.9" picocolors: "npm:^1.0.0" - checksum: 10/db2c2122af79d31ca916755331bb4bac96feb2b334cdaca5097a6b467fdd41963b89b14b6836a14f083de7ff887fc78fa1b3c10b14e743d33e12dbfe5ee3d223 - languageName: node - linkType: hard - -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.2": - version: 7.23.2 - resolution: "@babel/compat-data@npm:7.23.2" - checksum: 10/c18eccd13975c1434a65d04f721075e30d03ba1608f4872d84e8538c16552b878aaac804ff31243d8c2c0e91524f3bc98de6305e117ba1a55c9956871973b4dc + checksum: 10/96d69a570d0df82daedeb3d26ca508970bb31de83580c36c9605e7e7c0aae307ae17bc42609363016f0bdab12e991cebca3c02bf10765036b136bfe7281aee9a languageName: node linkType: hard -"@babel/compat-data@npm:^7.25.9, @babel/compat-data@npm:^7.26.0": - version: 7.26.2 - resolution: "@babel/compat-data@npm:7.26.2" - checksum: 10/ed9eed6b62ce803ef4a320b1dac76b0302abbb29c49dddf96f3e3207d9717eb34e299a8651bb1582e9c3346ead74b6d595ffced5b3dae718afa08b18741f8402 +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/compat-data@npm:7.25.9" + checksum: 10/76d06c56e1d1ab661dc90870d70d950c7df5514d2abfb115387ea0790ceeb1924ee3a88c959345f235aad219cfb13ff03c4458081ac350d47fc135a7ba2d49d3 languageName: node linkType: hard @@ -195,37 +177,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.22.5, @babel/generator@npm:^7.23.0, @babel/generator@npm:^7.23.6, @babel/generator@npm:^7.25.4, @babel/generator@npm:^7.7.2": - version: 7.25.5 - resolution: "@babel/generator@npm:7.25.5" - dependencies: - "@babel/types": "npm:^7.25.4" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^2.5.1" - checksum: 10/e6d046afe739cfa706c40c127b7436731acb2a3146d408a7d89dbf16448491b35bc09b7d285cc19c2c1f8980d74b5a99df200d67c859bb5260986614685b0770 - languageName: node - linkType: hard - -"@babel/generator@npm:^7.25.9": - version: 7.26.2 - resolution: "@babel/generator@npm:7.26.2" +"@babel/generator@npm:^7.22.5, @babel/generator@npm:^7.23.0, @babel/generator@npm:^7.23.6, @babel/generator@npm:^7.25.9, @babel/generator@npm:^7.7.2": + version: 7.25.9 + resolution: "@babel/generator@npm:7.25.9" dependencies: - "@babel/parser": "npm:^7.26.2" - "@babel/types": "npm:^7.26.0" + "@babel/types": "npm:^7.25.9" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10/71ace82b5b07a554846a003624bfab93275ccf73cdb9f1a37a4c1094bf9dc94bb677c67e8b8c939dbd6c5f0eda2e8f268aa2b0d9c3b9511072565660e717e045 - languageName: node - linkType: hard - -"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" - dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10/a9017bfc1c4e9f2225b967fbf818004703de7cf29686468b54002ffe8d6b56e0808afa20d636819fcf3a34b89ba72f52c11bdf1d69f303928ee10d92752cad95 + checksum: 10/eb36706c62ea77a09604077b84fae4e25d103cce58a15926d9d8b62d90c5fa69e35962515c05e78b5a975848ef772406dd79e2d4e83851bf9f7517b197a1b19d languageName: node linkType: hard @@ -238,15 +198,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" - dependencies: - "@babel/types": "npm:^7.22.15" - checksum: 10/639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a - languageName: node - linkType: hard - "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.25.9" @@ -257,20 +208,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6": - version: 7.22.15 - resolution: "@babel/helper-compilation-targets@npm:7.22.15" - dependencies: - "@babel/compat-data": "npm:^7.22.9" - "@babel/helper-validator-option": "npm:^7.22.15" - browserslist: "npm:^4.21.9" - lru-cache: "npm:^5.1.1" - semver: "npm:^6.3.1" - checksum: 10/9706decaa1591cf44511b6f3447eb9653b50ca3538215fe2e5387a8598c258c062f4622da5b95e61f0415706534deee619bbf53a2889f9bd967949b8f6024e0e - languageName: node - linkType: hard - -"@babel/helper-compilation-targets@npm:^7.25.9": +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-compilation-targets@npm:7.25.9" dependencies: @@ -283,23 +221,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.5, @babel/helper-create-class-features-plugin@npm:^7.25.0": - version: 7.25.4 - resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/helper-replace-supers": "npm:^7.25.0" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.4" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/47218da9fd964af30d41f0635d9e33eed7518e03aa8f10c3eb8a563bb2c14f52be3e3199db5912ae0e26058c23bb511c811e565c55ecec09427b04b867ed13c2 - languageName: node - linkType: hard - "@babel/helper-create-class-features-plugin@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9" @@ -317,20 +238,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - regexpu-core: "npm:^5.3.1" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/886b675e82f1327b4f7a2c69a68eefdb5dbb0b9d4762c2d4f42a694960a9ccf61e1a3bcad601efd92c110033eb1a944fcd1e5cac188aa6b2e2076b541e210e20 - languageName: node - linkType: hard - -"@babel/helper-create-regexp-features-plugin@npm:^7.25.9": +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.9" dependencies: @@ -343,21 +251,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.4.3": - version: 0.4.3 - resolution: "@babel/helper-define-polyfill-provider@npm:0.4.3" - dependencies: - "@babel/helper-compilation-targets": "npm:^7.22.6" - "@babel/helper-plugin-utils": "npm:^7.22.5" - debug: "npm:^4.1.1" - lodash.debounce: "npm:^4.0.8" - resolve: "npm:^1.14.2" - peerDependencies: - "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10/9ab9d6a2cfaffc44f8b7ad661b642b03f31597282557686b7f4c64f67acd3c5844d4eac028e63d238819bcec0549ddef7dc0539d10966ace96f4c61e97b33138 - languageName: node - linkType: hard - "@babel/helper-define-polyfill-provider@npm:^0.6.2": version: 0.6.2 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" @@ -373,7 +266,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.22.5": +"@babel/helper-environment-visitor@npm:^7.22.20": version: 7.24.7 resolution: "@babel/helper-environment-visitor@npm:7.24.7" dependencies: @@ -382,7 +275,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": +"@babel/helper-function-name@npm:^7.23.0": version: 7.24.7 resolution: "@babel/helper-function-name@npm:7.24.7" dependencies: @@ -401,16 +294,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" - dependencies: - "@babel/traverse": "npm:^7.24.8" - "@babel/types": "npm:^7.24.8" - checksum: 10/ac878761cfd0a46c081cda0da75cc186f922cf16e8ecdd0c4fb6dca4330d9fe4871b41a9976224cf9669c9e7fe0421b5c27349f2e99c125fa0be871b327fa770 - languageName: node - linkType: hard - "@babel/helper-member-expression-to-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9" @@ -421,17 +304,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.22.5, @babel/helper-module-imports@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-module-imports@npm:7.24.7" - dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10/df8bfb2bb18413aa151ecd63b7d5deb0eec102f924f9de6bc08022ced7ed8ca7fed914562d2f6fa5b59b74a5d6e255dc35612b2bc3b8abf361e13f61b3704770 - languageName: node - linkType: hard - -"@babel/helper-module-imports@npm:^7.25.9": +"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-module-imports@npm:7.25.9" dependencies: @@ -441,39 +314,17 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0, @babel/helper-module-transforms@npm:^7.24.8": - version: 7.25.2 - resolution: "@babel/helper-module-transforms@npm:7.25.2" - dependencies: - "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-simple-access": "npm:^7.24.7" - "@babel/helper-validator-identifier": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.2" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/a3bcf7815f3e9d8b205e0af4a8d92603d685868e45d119b621357e274996bf916216bb95ab5c6a60fde3775b91941555bf129d608e3d025b04f8aac84589f300 - languageName: node - linkType: hard - "@babel/helper-module-transforms@npm:^7.25.9": - version: 7.26.0 - resolution: "@babel/helper-module-transforms@npm:7.26.0" + version: 7.25.9 + resolution: "@babel/helper-module-transforms@npm:7.25.9" dependencies: "@babel/helper-module-imports": "npm:^7.25.9" + "@babel/helper-simple-access": "npm:^7.25.9" "@babel/helper-validator-identifier": "npm:^7.25.9" "@babel/traverse": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10/9841d2a62f61ad52b66a72d08264f23052d533afc4ce07aec2a6202adac0bfe43014c312f94feacb3291f4c5aafe681955610041ece2c276271adce3f570f2f5 - languageName: node - linkType: hard - -"@babel/helper-optimise-call-expression@npm:^7.22.5, @babel/helper-optimise-call-expression@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" - dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10/da7a7f2d1bb1be4cffd5fa820bd605bc075c7dd014e0458f608bb6f34f450fe9412c8cea93e788227ab396e0e02c162d7b1db3fbcb755a6360e354c485d61df0 + checksum: 10/6a9dc7da67f901a511ef26b99fd1b395946d466495159cbf80c092345ef3238306296ee76b204aea5f2675713130c58760c46b1ff3b6f6b19f7f8afcaa19d8ca languageName: node linkType: hard @@ -486,33 +337,13 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.24.8 - resolution: "@babel/helper-plugin-utils@npm:7.24.8" - checksum: 10/adbc9fc1142800a35a5eb0793296924ee8057fe35c61657774208670468a9fbfbb216f2d0bc46c680c5fefa785e5ff917cc1674b10bd75cdf9a6aa3444780630 - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.25.9": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.25.9 resolution: "@babel/helper-plugin-utils@npm:7.25.9" checksum: 10/e347d87728b1ab10b6976d46403941c8f9008c045ea6d99997a7ffca7b852dc34b6171380f7b17edf94410e0857ff26f3a53d8618f11d73744db86e8ca9b8c64 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.22.20, @babel/helper-remap-async-to-generator@npm:^7.22.5": - version: 7.22.20 - resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-wrap-function": "npm:^7.22.20" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 - languageName: node - linkType: hard - "@babel/helper-remap-async-to-generator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-remap-async-to-generator@npm:7.25.9" @@ -526,19 +357,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.22.5, @babel/helper-replace-supers@npm:^7.22.9, @babel/helper-replace-supers@npm:^7.25.0": - version: 7.25.0 - resolution: "@babel/helper-replace-supers@npm:7.25.0" - dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.24.8" - "@babel/helper-optimise-call-expression": "npm:^7.24.7" - "@babel/traverse": "npm:^7.25.0" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/97c6c17780cb9692132f7243f5a21fb6420104cb8ff8752dc03cfc9a1912a243994c0290c77ff096637ab6f2a7363b63811cfc68c2bad44e6b39460ac2f6a63f - languageName: node - linkType: hard - "@babel/helper-replace-supers@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-replace-supers@npm:7.25.9" @@ -552,16 +370,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-simple-access@npm:7.24.7" - dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10/5083e190186028e48fc358a192e4b93ab320bd016103caffcfda81302a13300ccce46c9cd255ae520c25d2a6a9b47671f93e5fe5678954a2329dc0a685465c49 - languageName: node - linkType: hard - "@babel/helper-simple-access@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-simple-access@npm:7.25.9" @@ -572,16 +380,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5, @babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" - dependencies: - "@babel/traverse": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" - checksum: 10/784a6fdd251a9a7e42ccd04aca087ecdab83eddc60fda76a2950e00eb239cc937d3c914266f0cc476298b52ac3f44ffd04c358e808bd17552a7e008d75494a77 - languageName: node - linkType: hard - "@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9" @@ -601,59 +399,27 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.23.4, @babel/helper-string-parser@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-string-parser@npm:7.24.8" - checksum: 10/6d1bf8f27dd725ce02bdc6dffca3c95fb9ab8a06adc2edbd9c1c9d68500274230d1a609025833ed81981eff560045b6b38f7b4c6fb1ab19fc90e5004e3932535 - languageName: node - linkType: hard - -"@babel/helper-string-parser@npm:^7.25.9": +"@babel/helper-string-parser@npm:^7.23.4, @babel/helper-string-parser@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-string-parser@npm:7.25.9" checksum: 10/c28656c52bd48e8c1d9f3e8e68ecafd09d949c57755b0d353739eb4eae7ba4f7e67e92e4036f1cd43378cc1397a2c943ed7bcaf5949b04ab48607def0258b775 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-validator-identifier@npm:7.24.7" - checksum: 10/86875063f57361471b531dbc2ea10bbf5406e12b06d249b03827d361db4cad2388c6f00936bcd9dc86479f7e2c69ea21412c2228d4b3672588b754b70a449d4b - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:^7.25.9": +"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" checksum: 10/3f9b649be0c2fd457fa1957b694b4e69532a668866b8a0d81eabfa34ba16dbf3107b39e0e7144c55c3c652bf773ec816af8df4a61273a2bb4eb3145ca9cf478e languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5, @babel/helper-validator-option@npm:^7.24.7": - version: 7.24.8 - resolution: "@babel/helper-validator-option@npm:7.24.8" - checksum: 10/a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c - languageName: node - linkType: hard - -"@babel/helper-validator-option@npm:^7.25.9": +"@babel/helper-validator-option@npm:^7.23.5, @babel/helper-validator-option@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-option@npm:7.25.9" checksum: 10/9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-wrap-function@npm:7.22.20" - dependencies: - "@babel/helper-function-name": "npm:^7.22.5" - "@babel/template": "npm:^7.22.15" - "@babel/types": "npm:^7.22.19" - checksum: 10/b22e4666dec3d401bdf8ebd01d448bb3733617dae5aa6fbd1b684a22a35653cca832edd876529fd139577713b44fb89b4f5e52b7315ab218620f78b8a8ae23de - languageName: node - linkType: hard - "@babel/helper-wrap-function@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-wrap-function@npm:7.25.9" @@ -666,12 +432,12 @@ __metadata: linkType: hard "@babel/helpers@npm:^7.25.9": - version: 7.26.0 - resolution: "@babel/helpers@npm:7.26.0" + version: 7.25.9 + resolution: "@babel/helpers@npm:7.25.9" dependencies: "@babel/template": "npm:^7.25.9" - "@babel/types": "npm:^7.26.0" - checksum: 10/fd4757f65d10b64cfdbf4b3adb7ea6ffff9497c53e0786452f495d1f7794da7e0898261b4db65e1c62bbb9a360d7d78a1085635c23dfc3af2ab6dcba06585f86 + "@babel/types": "npm:^7.25.9" + checksum: 10/83c0df8f45850c5621be660b69c33d93c02832162a9109bb9a03de32a2b6477fbbd1e2c8c5c19fadb0d48f07066ff20d2d2da32de62dfda5c0a6a1036cebeb00 languageName: node linkType: hard @@ -686,15 +452,15 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.22.13, @babel/highlight@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/highlight@npm:7.24.7" +"@babel/highlight@npm:^7.22.13, @babel/highlight@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/highlight@npm:7.25.9" dependencies: - "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/helper-validator-identifier": "npm:^7.25.9" chalk: "npm:^2.4.2" js-tokens: "npm:^4.0.0" picocolors: "npm:^1.0.0" - checksum: 10/69b73f38cdd4f881b09b939a711e76646da34f4834f4ce141d7a49a6bb1926eab1c594148970a8aa9360398dff800f63aade4e81fafdd7c8d8a8489ea93bfec1 + checksum: 10/0d165283dd4eb312292cea8fec3ae0d376874b1885f476014f0136784ed5b564b2c2ba2d270587ed546ee92505056dab56493f7960c01c4e6394d71d1b2e7db6 languageName: node linkType: hard @@ -716,25 +482,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/parser@npm:7.25.4" - dependencies: - "@babel/types": "npm:^7.25.4" - bin: - parser: ./bin/babel-parser.js - checksum: 10/343b8a76c43549e370fe96f4f6d564382a6cdff60e9c3b8a594c51e4cefd58ec9945e82e8c4dfbf15ac865a04e4b29806531440760748e28568e6aec21bc9cb5 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.2": - version: 7.26.2 - resolution: "@babel/parser@npm:7.26.2" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.0, @babel/parser@npm:^7.13.9, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.8, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/parser@npm:7.25.9" dependencies: - "@babel/types": "npm:^7.26.0" + "@babel/types": "npm:^7.25.9" bin: parser: ./bin/babel-parser.js - checksum: 10/8baee43752a3678ad9f9e360ec845065eeee806f1fdc8e0f348a8a0e13eef0959dabed4a197c978896c493ea205c804d0a1187cc52e4a1ba017c7935bab4983d + checksum: 10/702af8c40bb1236e3e3e6187b99e1290bd4bc1500aa53593ea63df8fe99f07ff1efef147b1d58886b264aff0972c4b9440ace442c8db9a6e079f318d46773421 languageName: node linkType: hard @@ -761,17 +516,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.15" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/8910ca21a7ec7c06f7b247d4b86c97c5aa15ef321518f44f6f490c5912fdf82c605aaa02b90892e375d82ccbedeadfdeadd922c1b836c9dd4c596871bf654753 - languageName: node - linkType: hard - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.9" @@ -783,19 +527,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.22.15" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" - "@babel/plugin-transform-optional-chaining": "npm:^7.22.15" - peerDependencies: - "@babel/core": ^7.13.0 - checksum: 10/fbefedc0da014c37f1a50a8094ce7dbbf2181ae93243f23d6ecba2499b5b20196c2124d6a4dfe3e9e0125798e80593103e456352a4beb4e5c6f7c75efb80fdac - languageName: node - linkType: hard - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.9" @@ -852,7 +583,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": +"@babel/plugin-syntax-class-properties@npm:^7.8.3": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -863,39 +594,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-static-block@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948 - languageName: node - linkType: hard - -"@babel/plugin-syntax-dynamic-import@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd - languageName: node - linkType: hard - -"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a - languageName: node - linkType: hard - "@babel/plugin-syntax-flow@npm:^7.24.1": version: 7.24.1 resolution: "@babel/plugin-syntax-flow@npm:7.24.1" @@ -907,51 +605,29 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/2b8b5572db04a7bef1e6cd20debf447e4eef7cb012616f5eceb8fa3e23ce469b8f76ee74fd6d1e158ba17a8f58b0aec579d092fb67c5a30e83ccfbc5754916c1 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-assertions@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.26.0" +"@babel/plugin-syntax-import-assertions@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.25.9" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/b58f2306df4a690ca90b763d832ec05202c50af787158ff8b50cdf3354359710bce2e1eb2b5135fcabf284756ac8eadf09ca74764aa7e76d12a5cac5f6b21e67 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-attributes@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/197b3c5ea2a9649347f033342cb222ab47f4645633695205c0250c6bf2af29e643753b8bb24a2db39948bef08e7c540babfd365591eb57fc110cb30b425ffc47 + checksum: 10/2f0c70bb379135ee205402caa42c0dda4d5d8fb64ff4ad163cab94bd8291c1a63b9dc9cf293758cecee223080d2d61e83f92c6d2a264621e24a07258c48968db languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0" +"@babel/plugin-syntax-import-attributes@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.25.9" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/c122aa577166c80ee67f75aebebeef4150a132c4d3109d25d7fc058bf802946f883e330f20b78c1d3e3a5ada631c8780c263d2d01b5dbaecc69efefeedd42916 + checksum: 10/0ea00b9100d383680c7142e61e3aa7101e3657ec5e1bfa990871eee4ae17e2c4a0da084e8f611d349bb9612908e911e1400418eb59caa5184226b08f513c1a0a languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": +"@babel/plugin-syntax-import-meta@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -973,18 +649,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.24.7, @babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.24.7 - resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a93516ae5b34868ab892a95315027d4e5e38e8bd1cfca6158f2974b0901cbb32bbe64ea10ad5b25f919ddc40c6d8113c4823372909c9c9922170c12b0b1acecb - languageName: node - linkType: hard - -"@babel/plugin-syntax-jsx@npm:^7.25.9": +"@babel/plugin-syntax-jsx@npm:^7.25.9, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.25.9 resolution: "@babel/plugin-syntax-jsx@npm:7.25.9" dependencies: @@ -995,7 +660,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -1017,7 +682,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": +"@babel/plugin-syntax-numeric-separator@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -1061,18 +726,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b317174783e6e96029b743ccff2a67d63d38756876e7e5d0ba53a322e38d9ca452c13354a57de1ad476b4c066dbae699e0ca157441da611117a47af88985ecda - languageName: node - linkType: hard - -"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": +"@babel/plugin-syntax-top-level-await@npm:^7.8.3": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -1083,18 +737,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.24.7, @babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.25.4 - resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.8" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/0771b45a35fd536cd3b3a48e5eda0f53e2d4f4a0ca07377cc247efa39eaf6002ed1c478106aad2650e54aefaebcb4f34f3284c4ae9252695dbd944bf66addfb0 - languageName: node - linkType: hard - -"@babel/plugin-syntax-typescript@npm:^7.25.9": +"@babel/plugin-syntax-typescript@npm:^7.25.9, @babel/plugin-syntax-typescript@npm:^7.7.2": version: 7.25.9 resolution: "@babel/plugin-syntax-typescript@npm:7.25.9" dependencies: @@ -1117,17 +760,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/35abb6c57062802c7ce8bd96b2ef2883e3124370c688bbd67609f7d2453802fb73944df8808f893b6c67de978eb2bcf87bbfe325e46d6f39b5fcb09ece11d01a - languageName: node - linkType: hard - "@babel/plugin-transform-arrow-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.9" @@ -1139,20 +771,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.23.2": - version: 7.23.2 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.2" - dependencies: - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-remap-async-to-generator": "npm:^7.22.20" - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/e1abae0edcda7304d7c17702ac25a127578791b89c4f767d60589249fa3e50ec33f8c9ff39d3d8d41f00b29947654eaddd4fd586e04c4d598122db745fab2868 - languageName: node - linkType: hard - "@babel/plugin-transform-async-generator-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.9" @@ -1166,19 +784,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.22.5" - dependencies: - "@babel/helper-module-imports": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-remap-async-to-generator": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b95f23f99dcb379a9f0a1c2a3bbea3f8dc0e1b16dc1ac8b484fe378370169290a7a63d520959a9ba1232837cf74a80e23f6facbe14fd42a3cda6d3c2d7168e62 - languageName: node - linkType: hard - "@babel/plugin-transform-async-to-generator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9" @@ -1192,17 +797,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/416b1341858e8ca4e524dee66044735956ced5f478b2c3b9bc11ec2285b0c25d7dbb96d79887169eb938084c95d0a89338c8b2fe70d473bd9dc92e5d9db1732c - languageName: node - linkType: hard - "@babel/plugin-transform-block-scoped-functions@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.25.9" @@ -1214,17 +808,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.23.0" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/9f60c71a0b72c7bdc0734ab363cf8ad40c4366456d9429ab3f2caedf6566c12f1ae8190478827222e93c60855b6c746a2c0e24381646fe7220d4666c332dc090 - languageName: node - linkType: hard - "@babel/plugin-transform-block-scoping@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9" @@ -1236,19 +819,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-class-properties@npm:7.22.5" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b830152dfc2ff2f647f0abe76e6251babdfbef54d18c4b2c73a6bf76b1a00050a5d998dac80dc901a48514e95604324943a9dd39317073fe0928b559e0e0c579 - languageName: node - linkType: hard - -"@babel/plugin-transform-class-properties@npm:^7.25.9": +"@babel/plugin-transform-class-properties@npm:^7.22.5, @babel/plugin-transform-class-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-class-properties@npm:7.25.9" dependencies: @@ -1260,47 +831,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-class-static-block@npm:7.22.11" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.22.11" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.12.0 - checksum: 10/69f040506fad66f1c6918d288d0e0edbc5c8a07c8b4462c1184ad2f9f08995d68b057126c213871c0853ae0c72afc60ec87492049dfacb20902e32346a448bcb - languageName: node - linkType: hard - -"@babel/plugin-transform-class-static-block@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-transform-class-static-block@npm:7.26.0" +"@babel/plugin-transform-class-static-block@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/plugin-transform-class-static-block@npm:7.25.9" dependencies: "@babel/helper-create-class-features-plugin": "npm:^7.25.9" "@babel/helper-plugin-utils": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.12.0 - checksum: 10/60cba3f125a7bc4f90706af0a011697c7ffd2eddfba336ed6f84c5f358c44c3161af18b0202475241a96dee7964d96dd3a342f46dbf85b75b38bb789326e1766 - languageName: node - linkType: hard - -"@babel/plugin-transform-classes@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-classes@npm:7.22.15" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-compilation-targets": "npm:^7.22.15" - "@babel/helper-environment-visitor": "npm:^7.22.5" - "@babel/helper-function-name": "npm:^7.22.5" - "@babel/helper-optimise-call-expression": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-replace-supers": "npm:^7.22.9" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - globals: "npm:^11.1.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/21d7a171055634b4c407e42fc99ef340bde70d5582d47f7bcdc9781d09b3736607d346f56c3abb1e8b9b62516e1af25ab9023a295be0c347c963d6a20f74b55f + checksum: 10/01dbb32e443086cf98e986a0d3532f74916ed85ef4823139d155d69c6fbf4ae80ae862f83abba57d815bb6aebd349b18cdec93ef08be42ead4248f3a294c8a08 languageName: node linkType: hard @@ -1320,18 +859,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-computed-properties@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/template": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a3efa8de19e4c52f01a99301d864819a7997a7845044d9cef5b67b0fb1e5e3e610ecc23053a8b5cf8fe40fcad93c15a586eaeffd22b89eeaa038339c37919661 - languageName: node - linkType: hard - "@babel/plugin-transform-computed-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-computed-properties@npm:7.25.9" @@ -1344,17 +871,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-destructuring@npm:7.23.0" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/924b1c0fc11c9782a9a63ae6d181b9b069250a5567c705c24409e2f1e39ac47e61846cd17b0ab45641dc77050e7b900fc80a536f8abe7dff49b4e777e7b9b952 - languageName: node - linkType: hard - "@babel/plugin-transform-destructuring@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-destructuring@npm:7.25.9" @@ -1366,18 +882,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.22.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/409b658d11e3082c8f69e9cdef2d96e4d6d11256f005772425fb230cc48fd05945edbfbcb709dab293a1a2f01f9c8a5bb7b4131e632b23264039d9f95864b453 - languageName: node - linkType: hard - "@babel/plugin-transform-dotall-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.9" @@ -1390,17 +894,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/bb1280fbabaab6fab2ede585df34900712698210a3bd413f4df5bae6d8c24be36b496c92722ae676a7a67d060a4624f4d6c23b923485f906bfba8773c69f55b4 - languageName: node - linkType: hard - "@babel/plugin-transform-duplicate-keys@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.9" @@ -1424,18 +917,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/78fc9c532210bf9e8f231747f542318568ac360ee6c27e80853962c984283c73da3f8f8aebe83c2096090a435b356b092ed85de617a156cbe0729d847632be45 - languageName: node - linkType: hard - "@babel/plugin-transform-dynamic-import@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.9" @@ -1447,18 +928,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.22.5" - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f2d660c1b1d51ad5fec1cd5ad426a52187204068c4158f8c4aa977b31535c61b66898d532603eef21c15756827be8277f724c869b888d560f26d7fe848bb5eae - languageName: node - linkType: hard - "@babel/plugin-transform-exponentiation-operator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.25.9" @@ -1471,18 +940,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/73af5883a321ed56a4bfd43c8a7de0164faebe619287706896fc6ee2f7a4e69042adaa1338c0b8b4bdb9f7e5fdceb016fb1d40694cb43ca3b8827429e8aac4bf - languageName: node - linkType: hard - "@babel/plugin-transform-export-namespace-from@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.9" @@ -1506,17 +963,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-for-of@npm:7.22.15" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/d6ac155fcc8dc3d37a092325e5b7df738a7a953c4a47520c0c02fbc30433e6a5ac38197690845ebb931870af958ac95d36132d5accf41ed4bb0765a7618371fc - languageName: node - linkType: hard - "@babel/plugin-transform-for-of@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-for-of@npm:7.25.9" @@ -1529,19 +975,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-function-name@npm:7.22.5" - dependencies: - "@babel/helper-compilation-targets": "npm:^7.22.5" - "@babel/helper-function-name": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/cff3b876357999cb8ae30e439c3ec6b0491a53b0aa6f722920a4675a6dd5b53af97a833051df4b34791fe5b3dd326ccf769d5c8e45b322aa50ee11a660b17845 - languageName: node - linkType: hard - "@babel/plugin-transform-function-name@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-function-name@npm:7.25.9" @@ -1555,18 +988,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-json-strings@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/50665e5979e66358c50e90a26db53c55917f78175127ac2fa05c7888d156d418ffb930ec0a109353db0a7c5f57c756ce01bfc9825d24cbfd2b3ec453f2ed8cba - languageName: node - linkType: hard - "@babel/plugin-transform-json-strings@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-json-strings@npm:7.25.9" @@ -1578,17 +999,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-literals@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ec37cc2ffb32667af935ab32fe28f00920ec8a1eb999aa6dc6602f2bebd8ba205a558aeedcdccdebf334381d5c57106c61f52332045730393e73410892a9735b - languageName: node - linkType: hard - "@babel/plugin-transform-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-literals@npm:7.25.9" @@ -1600,18 +1010,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.22.11": - version: 7.23.4 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.23.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/2ae1dc9b4ff3bf61a990ff3accdecb2afe3a0ca649b3e74c010078d1cdf29ea490f50ac0a905306a2bcf9ac177889a39ac79bdcc3a0fdf220b3b75fac18d39b5 - languageName: node - linkType: hard - "@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.9" @@ -1623,17 +1021,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ec4b0e07915ddd4fda0142fd104ee61015c208608a84cfa13643a95d18760b1dc1ceb6c6e0548898b8c49e5959a994e46367260176dbabc4467f729b21868504 - languageName: node - linkType: hard - "@babel/plugin-transform-member-expression-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.9" @@ -1645,18 +1032,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-modules-amd@npm:7.23.0" - dependencies: - "@babel/helper-module-transforms": "npm:^7.23.0" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/d06fbee89044a0c4d9d65c2bb26b45482266d14d64601a36996615ca75f1e1cc40ac95d09821601606eacbeeef39b3b634118f6197cda6431c8440975926a5d5 - languageName: node - linkType: hard - "@babel/plugin-transform-modules-amd@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-amd@npm:7.25.9" @@ -1669,20 +1044,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.24.7": - version: 7.24.8 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" - dependencies: - "@babel/helper-module-transforms": "npm:^7.24.8" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-simple-access": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/18e5d229767c7b5b6ff0cbf1a8d2d555965b90201839d0ac2dc043b56857624ea344e59f733f028142a8c1d54923b82e2a0185694ef36f988d797bfbaf59819c - languageName: node - linkType: hard - -"@babel/plugin-transform-modules-commonjs@npm:^7.25.9": +"@babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.9" dependencies: @@ -1695,20 +1057,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.0" - dependencies: - "@babel/helper-hoist-variables": "npm:^7.22.5" - "@babel/helper-module-transforms": "npm:^7.23.0" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-validator-identifier": "npm:^7.22.20" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/43a61fd72ba90afafcf6734345df00cbaf1f244ca456f8e8532813b87a985ddfeca7fc6ea758c12350abcfeba02835875b44dc6b3118c2dac7469a3f298c79ad - languageName: node - linkType: hard - "@babel/plugin-transform-modules-systemjs@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.9" @@ -1723,18 +1071,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-modules-umd@npm:7.22.5" - dependencies: - "@babel/helper-module-transforms": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b955d066c68b60c1179bfb0b744e2fad32dbe86d0673bd94637439cfe425d1e3ff579bd47a417233609aac1624f4fe69915bee73e6deb2af6188fda8aaa5db63 - languageName: node - linkType: hard - "@babel/plugin-transform-modules-umd@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-modules-umd@npm:7.25.9" @@ -1747,18 +1083,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 - languageName: node - linkType: hard - "@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.9" @@ -1771,17 +1095,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-new-target@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/6b72112773487a881a1d6ffa680afde08bad699252020e86122180ee7a88854d5da3f15d9bca3331cf2e025df045604494a8208a2e63b486266b07c14e2ffbf3 - languageName: node - linkType: hard - "@babel/plugin-transform-new-target@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-new-target@npm:7.25.9" @@ -1793,19 +1106,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/167babecc8b8fe70796a7b7d34af667ebbf43da166c21689502e5e8cc93180b7a85979c77c9f64b7cce431b36718bd0a6df9e5e0ffea4ae22afb22cfef886372 - languageName: node - linkType: hard - -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.25.9" dependencies: @@ -1816,18 +1117,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/af064d06a4a041767ec396a5f258103f64785df290e038bba9f0ef454e6c914f2ac45d862bbdad8fac2c7ad47fa4e95356f29053c60c100a0160b02a995fe2a3 - languageName: node - linkType: hard - "@babel/plugin-transform-numeric-separator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.9" @@ -1839,21 +1128,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.22.15" - dependencies: - "@babel/compat-data": "npm:^7.22.9" - "@babel/helper-compilation-targets": "npm:^7.22.15" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-transform-parameters": "npm:^7.22.15" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/04b9f4bbabf4bbd019b47c60b294d873fe5d2f6063628a5b311d88da9e81b0a8622756dd42c7030359925479b7a3cd743dee46e73d84e03afd907d8cfd44ddea - languageName: node - linkType: hard - "@babel/plugin-transform-object-rest-spread@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.9" @@ -1867,18 +1141,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-object-super@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-replace-supers": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b71887877d74cb64dbccb5c0324fa67e31171e6a5311991f626650e44a4083e5436a1eaa89da78c0474fb095d4ec322d63ee778b202d33aa2e4194e1ed8e62d7 - languageName: node - linkType: hard - "@babel/plugin-transform-object-super@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-object-super@npm:7.25.9" @@ -1891,18 +1153,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.22.11" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f17abd90e1de67c84d63afea29c8021c74abb2794d3a6eeafb0bbe7372d3db32aefca386e392116ec63884537a4a2815d090d26264d259bacc08f6e3ed05294c - languageName: node - linkType: hard - "@babel/plugin-transform-optional-catch-binding@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.9" @@ -1914,20 +1164,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.22.15, @babel/plugin-transform-optional-chaining@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.0" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/fb1103c6489b91df06c483a97fc12515c2f3840f573cbecb27959307c0a838fdd1502a34ada43805c4fb7f7dab3d1c0d1ab8428775d098af6778a7b00f494c27 - languageName: node - linkType: hard - -"@babel/plugin-transform-optional-chaining@npm:^7.25.9": +"@babel/plugin-transform-optional-chaining@npm:^7.23.0, @babel/plugin-transform-optional-chaining@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.9" dependencies: @@ -1939,17 +1176,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-parameters@npm:7.22.15" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/fa9f2340fe48b88c344ff38cd86318f61e48bedafdc567a1607106a1c3a65c0db845792f406b1320f89745192fe1ae6739b0bc4eb646ff60cd797ca85752d462 - languageName: node - linkType: hard - "@babel/plugin-transform-parameters@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-parameters@npm:7.25.9" @@ -1961,19 +1187,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-private-methods@npm:7.22.5" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/321479b4fcb6d3b3ef622ab22fd24001e43d46e680e8e41324c033d5810c84646e470f81b44cbcbef5c22e99030784f7cac92f1829974da7a47a60a7139082c3 - languageName: node - linkType: hard - -"@babel/plugin-transform-private-methods@npm:^7.25.9": +"@babel/plugin-transform-private-methods@npm:^7.22.5, @babel/plugin-transform-private-methods@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-private-methods@npm:7.25.9" dependencies: @@ -1985,20 +1199,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.22.11" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-create-class-features-plugin": "npm:^7.22.11" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b00623d107069c91a164d5cf7486c0929a4ee3023fcddbc8844e21b5e66f369271e1aa51921c7d87b80d9927bc75d63afcfe4d577872457ddb0443a5b86bacca - languageName: node - linkType: hard - "@babel/plugin-transform-private-property-in-object@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.9" @@ -2012,17 +1212,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-property-literals@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/796176a3176106f77fcb8cd04eb34a8475ce82d6d03a88db089531b8f0453a2fb8b0c6ec9a52c27948bc0ea478becec449893741fc546dfc3930ab927e3f9f2e - languageName: node - linkType: hard - "@babel/plugin-transform-property-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-property-literals@npm:7.25.9" @@ -2034,17 +1223,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-react-display-name@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a12bfd1e4e93055efca3ace3c34722571bda59d9740dca364d225d9c6e3ca874f134694d21715c42cc63d79efd46db9665bd4a022998767f9245f1e29d5d204d - languageName: node - linkType: hard - "@babel/plugin-transform-react-display-name@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-display-name@npm:7.25.9" @@ -2056,17 +1234,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" - dependencies: - "@babel/plugin-transform-react-jsx": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 - languageName: node - linkType: hard - "@babel/plugin-transform-react-jsx-development@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.9" @@ -2078,21 +1245,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/plugin-transform-react-jsx@npm:7.22.15" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-module-imports": "npm:^7.22.15" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/plugin-syntax-jsx": "npm:^7.22.5" - "@babel/types": "npm:^7.22.15" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a436bfbffe723d162e5816d510dca7349a1fc572c501d73f1e17bbca7eb899d7a6a14d8fc2ae5993dd79fdd77bcc68d295e59a3549bed03b8579c767f6e3c9dc - languageName: node - linkType: hard - "@babel/plugin-transform-react-jsx@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-jsx@npm:7.25.9" @@ -2108,18 +1260,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.22.5" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/092021c4f404e267002099ec20b3f12dd730cb90b0d83c5feed3dc00dbe43b9c42c795a18e7c6c7d7bddea20c7dd56221b146aec81b37f2e7eb5137331c61120 - languageName: node - linkType: hard - "@babel/plugin-transform-react-pure-annotations@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.9" @@ -2132,18 +1272,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.22.10": - version: 7.22.10 - resolution: "@babel/plugin-transform-regenerator@npm:7.22.10" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - regenerator-transform: "npm:^0.15.2" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/e13678d62d6fa96f11cb8b863f00e8693491e7adc88bfca3f2820f80cbac8336e7dec3a596eee6a1c4663b7ececc3564f2cd7fb44ed6d4ce84ac2bb7f39ecc6e - languageName: node - linkType: hard - "@babel/plugin-transform-regenerator@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-regenerator@npm:7.25.9" @@ -2156,29 +1284,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.26.0" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/726deca486bbd4b176f8a966eb0f4aabc19d9def3b8dabb8b3a656778eca0df1fda3f3c92b213aa5a184232fdafd5b7bd73b4e24ca4345c498ef6baff2bda4e1 - languageName: node - linkType: hard - -"@babel/plugin-transform-reserved-words@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-reserved-words@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/3ffd7dbc425fe8132bfec118b9817572799cab1473113a635d25ab606c1f5a2341a636c04cf6b22df3813320365ed5a965b5eeb3192320a10e4cc2c137bd8bfc - languageName: node - linkType: hard - "@babel/plugin-transform-reserved-words@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-reserved-words@npm:7.25.9" @@ -2190,17 +1295,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a5ac902c56ea8effa99f681340ee61bac21094588f7aef0bc01dff98246651702e677552fa6d10e548c4ac22a3ffad047dd2f8c8f0540b68316c2c203e56818b - languageName: node - linkType: hard - "@babel/plugin-transform-shorthand-properties@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.9" @@ -2212,18 +1306,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-spread@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f9fd247b3fa8953416c8808c124c3a5db5cd697abbf791aae0143a0587fff6b386045f94c62bcd1b6783a1fd275629cc194f25f6c0aafc9f05f12a56fd5f94bf - languageName: node - linkType: hard - "@babel/plugin-transform-spread@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-spread@npm:7.25.9" @@ -2236,17 +1318,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/63b2c575e3e7f96c32d52ed45ee098fb7d354b35c2223b8c8e76840b32cc529ee0c0ceb5742fd082e56e91e3d82842a367ce177e82b05039af3d602c9627a729 - languageName: node - linkType: hard - "@babel/plugin-transform-sticky-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.9" @@ -2258,17 +1329,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-template-literals@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/27e9bb030654cb425381c69754be4abe6a7c75b45cd7f962cd8d604b841b2f0fb7b024f2efc1c25cc53f5b16d79d5e8cfc47cacbdaa983895b3aeefa3e7e24ff - languageName: node - linkType: hard - "@babel/plugin-transform-template-literals@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-template-literals@npm:7.25.9" @@ -2280,17 +1340,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/82a53a63ffc3010b689ca9a54e5f53b2718b9f4b4a9818f36f9b7dba234f38a01876680553d2716a645a61920b5e6e4aaf8d4a0064add379b27ca0b403049512 - languageName: node - linkType: hard - "@babel/plugin-transform-typeof-symbol@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.25.9" @@ -2302,21 +1351,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.24.7": - version: 7.25.2 - resolution: "@babel/plugin-transform-typescript@npm:7.25.2" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.25.0" - "@babel/helper-plugin-utils": "npm:^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" - "@babel/plugin-syntax-typescript": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/50e017ffd131c08661daa22b6c759999bb7a6cdfbf683291ee4bcbea4ae839440b553d2f8896bcf049aca1d267b39f3b09e8336059e919e83149b5ad859671f6 - languageName: node - linkType: hard - "@babel/plugin-transform-typescript@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-typescript@npm:7.25.9" @@ -2332,17 +1366,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.22.10": - version: 7.22.10 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.22.10" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/807f40ed1324c8cb107c45358f1903384ca3f0ef1d01c5a3c5c9b271c8d8eec66936a3dcc8d75ddfceea9421420368c2e77ae3adef0a50557e778dfe296bf382 - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-escapes@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.9" @@ -2354,18 +1377,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.22.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/2495e5f663cb388e3d888b4ba3df419ac436a5012144ac170b622ddfc221f9ea9bdba839fa2bc0185cb776b578030666406452ec7791cbf0e7a3d4c88ae9574c - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-property-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.9" @@ -2378,18 +1389,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.22.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/6b5d1404c8c623b0ec9bd436c00d885a17d6a34f3f2597996343ddb9d94f6379705b21582dfd4cec2c47fd34068872e74ab6b9580116c0566b3f9447e2a7fa06 - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9" @@ -2402,18 +1401,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.22.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.22.5" - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/c042070f980b139547f8b0179efbc049ac5930abec7fc26ed7a41d89a048d8ab17d362200e204b6f71c3c20d6991a0e74415e1a412a49adc8131c2a40c04822e - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.9" @@ -2426,101 +1413,11 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:^7.23.2": - version: 7.23.2 - resolution: "@babel/preset-env@npm:7.23.2" - dependencies: - "@babel/compat-data": "npm:^7.23.2" - "@babel/helper-compilation-targets": "npm:^7.22.15" - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-validator-option": "npm:^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.22.15" - "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/plugin-syntax-class-properties": "npm:^7.12.13" - "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" - "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" - "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" - "@babel/plugin-syntax-import-assertions": "npm:^7.22.5" - "@babel/plugin-syntax-import-attributes": "npm:^7.22.5" - "@babel/plugin-syntax-import-meta": "npm:^7.10.4" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" - "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" - "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.22.5" - "@babel/plugin-transform-async-generator-functions": "npm:^7.23.2" - "@babel/plugin-transform-async-to-generator": "npm:^7.22.5" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.22.5" - "@babel/plugin-transform-block-scoping": "npm:^7.23.0" - "@babel/plugin-transform-class-properties": "npm:^7.22.5" - "@babel/plugin-transform-class-static-block": "npm:^7.22.11" - "@babel/plugin-transform-classes": "npm:^7.22.15" - "@babel/plugin-transform-computed-properties": "npm:^7.22.5" - "@babel/plugin-transform-destructuring": "npm:^7.23.0" - "@babel/plugin-transform-dotall-regex": "npm:^7.22.5" - "@babel/plugin-transform-duplicate-keys": "npm:^7.22.5" - "@babel/plugin-transform-dynamic-import": "npm:^7.22.11" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.22.5" - "@babel/plugin-transform-export-namespace-from": "npm:^7.22.11" - "@babel/plugin-transform-for-of": "npm:^7.22.15" - "@babel/plugin-transform-function-name": "npm:^7.22.5" - "@babel/plugin-transform-json-strings": "npm:^7.22.11" - "@babel/plugin-transform-literals": "npm:^7.22.5" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.22.11" - "@babel/plugin-transform-member-expression-literals": "npm:^7.22.5" - "@babel/plugin-transform-modules-amd": "npm:^7.23.0" - "@babel/plugin-transform-modules-commonjs": "npm:^7.23.0" - "@babel/plugin-transform-modules-systemjs": "npm:^7.23.0" - "@babel/plugin-transform-modules-umd": "npm:^7.22.5" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.22.5" - "@babel/plugin-transform-new-target": "npm:^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.22.11" - "@babel/plugin-transform-numeric-separator": "npm:^7.22.11" - "@babel/plugin-transform-object-rest-spread": "npm:^7.22.15" - "@babel/plugin-transform-object-super": "npm:^7.22.5" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.22.11" - "@babel/plugin-transform-optional-chaining": "npm:^7.23.0" - "@babel/plugin-transform-parameters": "npm:^7.22.15" - "@babel/plugin-transform-private-methods": "npm:^7.22.5" - "@babel/plugin-transform-private-property-in-object": "npm:^7.22.11" - "@babel/plugin-transform-property-literals": "npm:^7.22.5" - "@babel/plugin-transform-regenerator": "npm:^7.22.10" - "@babel/plugin-transform-reserved-words": "npm:^7.22.5" - "@babel/plugin-transform-shorthand-properties": "npm:^7.22.5" - "@babel/plugin-transform-spread": "npm:^7.22.5" - "@babel/plugin-transform-sticky-regex": "npm:^7.22.5" - "@babel/plugin-transform-template-literals": "npm:^7.22.5" - "@babel/plugin-transform-typeof-symbol": "npm:^7.22.5" - "@babel/plugin-transform-unicode-escapes": "npm:^7.22.10" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.22.5" - "@babel/plugin-transform-unicode-regex": "npm:^7.22.5" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.22.5" - "@babel/preset-modules": "npm:0.1.6-no-external-plugins" - "@babel/types": "npm:^7.23.0" - babel-plugin-polyfill-corejs2: "npm:^0.4.6" - babel-plugin-polyfill-corejs3: "npm:^0.8.5" - babel-plugin-polyfill-regenerator: "npm:^0.5.3" - core-js-compat: "npm:^3.31.0" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/7bc8aeed59047f99af2f608f3143044517582b6bd7b041e3c7a12eface47e0313a57e78fad2e0d450cda2ce6c58451d67493f3d3677c5c1031cf59b7db1161c3 - languageName: node - linkType: hard - -"@babel/preset-env@npm:^7.25.9": - version: 7.26.0 - resolution: "@babel/preset-env@npm:7.26.0" +"@babel/preset-env@npm:^7.23.2, @babel/preset-env@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/preset-env@npm:7.25.9" dependencies: - "@babel/compat-data": "npm:^7.26.0" + "@babel/compat-data": "npm:^7.25.9" "@babel/helper-compilation-targets": "npm:^7.25.9" "@babel/helper-plugin-utils": "npm:^7.25.9" "@babel/helper-validator-option": "npm:^7.25.9" @@ -2530,8 +1427,8 @@ __metadata: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9" "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.26.0" - "@babel/plugin-syntax-import-attributes": "npm:^7.26.0" + "@babel/plugin-syntax-import-assertions": "npm:^7.25.9" + "@babel/plugin-syntax-import-attributes": "npm:^7.25.9" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" "@babel/plugin-transform-arrow-functions": "npm:^7.25.9" "@babel/plugin-transform-async-generator-functions": "npm:^7.25.9" @@ -2539,7 +1436,7 @@ __metadata: "@babel/plugin-transform-block-scoped-functions": "npm:^7.25.9" "@babel/plugin-transform-block-scoping": "npm:^7.25.9" "@babel/plugin-transform-class-properties": "npm:^7.25.9" - "@babel/plugin-transform-class-static-block": "npm:^7.26.0" + "@babel/plugin-transform-class-static-block": "npm:^7.25.9" "@babel/plugin-transform-classes": "npm:^7.25.9" "@babel/plugin-transform-computed-properties": "npm:^7.25.9" "@babel/plugin-transform-destructuring": "npm:^7.25.9" @@ -2572,7 +1469,6 @@ __metadata: "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9" "@babel/plugin-transform-property-literals": "npm:^7.25.9" "@babel/plugin-transform-regenerator": "npm:^7.25.9" - "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0" "@babel/plugin-transform-reserved-words": "npm:^7.25.9" "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9" "@babel/plugin-transform-spread": "npm:^7.25.9" @@ -2591,7 +1487,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/a7a80314f845deea713985a6316361c476621c76cfe5c6c28e8b9558f01634b49bbfdd3581ef94b5d6cff5c2b8830468aa53a73f5b5c1224db2dfea5db7e676f + checksum: 10/7a9ca1a19949426498fdffc37eed919f9581226ea45b18be764d29ce81bbf8c8f2f37152300c3524b7a3861831d33f10d481810f3011dff702f780d3f79aa789 languageName: node linkType: hard @@ -2621,23 +1517,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/preset-react@npm:7.22.15" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - "@babel/helper-validator-option": "npm:^7.22.15" - "@babel/plugin-transform-react-display-name": "npm:^7.22.5" - "@babel/plugin-transform-react-jsx": "npm:^7.22.15" - "@babel/plugin-transform-react-jsx-development": "npm:^7.22.5" - "@babel/plugin-transform-react-pure-annotations": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f9296e45346c3b6ab8296952edde5f1774cc9fdbdbefbc76047278fc3e889d3e15740f038ce017aca562d89f32fcbb6c11783d464fc6ae3066433178fa58513c - languageName: node - linkType: hard - -"@babel/preset-react@npm:^7.25.9": +"@babel/preset-react@npm:^7.22.15, @babel/preset-react@npm:^7.25.9": version: 7.25.9 resolution: "@babel/preset-react@npm:7.25.9" dependencies: @@ -2653,24 +1533,9 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.23.0, @babel/preset-typescript@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/preset-typescript@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.7" - "@babel/plugin-transform-typescript": "npm:^7.24.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/995e9783f8e474581e7533d6b10ec1fbea69528cc939ad8582b5937e13548e5215d25a8e2c845e7b351fdaa13139896b5e42ab3bde83918ea4e41773f10861ac - languageName: node - linkType: hard - -"@babel/preset-typescript@npm:^7.25.9": - version: 7.26.0 - resolution: "@babel/preset-typescript@npm:7.26.0" +"@babel/preset-typescript@npm:^7.23.0, @babel/preset-typescript@npm:^7.24.7, @babel/preset-typescript@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/preset-typescript@npm:7.25.9" dependencies: "@babel/helper-plugin-utils": "npm:^7.25.9" "@babel/helper-validator-option": "npm:^7.25.9" @@ -2679,26 +1544,11 @@ __metadata: "@babel/plugin-transform-typescript": "npm:^7.25.9" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10/81a60826160163a3daae017709f42147744757b725b50c9024ef3ee5a402ee45fd2e93eaecdaaa22c81be91f7940916249cfb7711366431cfcacc69c95878c03 - languageName: node - linkType: hard - -"@babel/register@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/register@npm:7.22.15" - dependencies: - clone-deep: "npm:^4.0.1" - find-cache-dir: "npm:^2.0.0" - make-dir: "npm:^2.1.0" - pirates: "npm:^4.0.5" - source-map-support: "npm:^0.5.16" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/5497be6773608cd2d874210edd14499fce464ddbea170219da55955afe4c9173adb591164193458fd639e43b7d1314088a6186f4abf241476c59b3f0da6afd6f + checksum: 10/bcb730ffc777e941eb34ade5052815b7091a0f1c49c6ae9515ebc3ffbfb52b2195dff3d289498b767e9ee898fc30ed100496f4f336a8be51725f2b4a73d7227a languageName: node linkType: hard -"@babel/register@npm:^7.25.9": +"@babel/register@npm:^7.22.15, @babel/register@npm:^7.25.9": version: 7.25.9 resolution: "@babel/register@npm:7.25.9" dependencies: @@ -2713,13 +1563,6 @@ __metadata: languageName: node linkType: hard -"@babel/regjsgen@npm:^0.8.0": - version: 0.8.0 - resolution: "@babel/regjsgen@npm:0.8.0" - checksum: 10/c57fb730b17332b7572574b74364a77d70faa302a281a62819476fa3b09822974fd75af77aea603ad77378395be64e81f89f0e800bf86cbbf21652d49ce12ee8 - languageName: node - linkType: hard - "@babel/runtime-corejs3@npm:^7.10.2": version: 7.11.2 resolution: "@babel/runtime-corejs3@npm:7.11.2" @@ -2748,18 +1591,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3": - version: 7.25.0 - resolution: "@babel/template@npm:7.25.0" - dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/parser": "npm:^7.25.0" - "@babel/types": "npm:^7.25.0" - checksum: 10/07ebecf6db8b28244b7397628e09c99e7a317b959b926d90455c7253c88df3677a5a32d1501d9749fe292a263ff51a4b6b5385bcabd5dadd3a48036f4d4949e0 - languageName: node - linkType: hard - -"@babel/template@npm:^7.25.9": +"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.3.3": version: 7.25.9 resolution: "@babel/template@npm:7.25.9" dependencies: @@ -2788,22 +1620,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.4": - version: 7.25.4 - resolution: "@babel/traverse@npm:7.25.4" - dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/generator": "npm:^7.25.4" - "@babel/parser": "npm:^7.25.4" - "@babel/template": "npm:^7.25.0" - "@babel/types": "npm:^7.25.4" - debug: "npm:^4.3.1" - globals: "npm:^11.1.0" - checksum: 10/a85c16047ab8e454e2e758c75c31994cec328bd6d8b4b22e915fa7393a03b3ab96d1218f43dc7ef77c957cc488dc38100bdf504d08a80a131e89b2e49cfa2be5 - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.25.9": +"@babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.25.9": version: 7.25.9 resolution: "@babel/traverse@npm:7.25.9" dependencies: @@ -2829,18 +1646,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.13.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.25.4 - resolution: "@babel/types@npm:7.25.4" - dependencies: - "@babel/helper-string-parser": "npm:^7.24.8" - "@babel/helper-validator-identifier": "npm:^7.24.7" - to-fast-properties: "npm:^2.0.0" - checksum: 10/d4a1194612d0a2a6ce9a0be325578b43d74e5f5278c67409468ba0a924341f0ad349ef0245ee8a36da3766efe5cc59cd6bb52547674150f97d8dc4c8cfa5d6b8 - languageName: node - linkType: hard - -"@babel/types@npm:^7.20.0, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.0, @babel/types@npm:^7.13.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.26.0 resolution: "@babel/types@npm:7.26.0" dependencies: @@ -6078,17 +4884,7 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1": - version: 7.0.1 - resolution: "@metamask/base-controller@npm:7.0.1" - dependencies: - "@metamask/utils": "npm:^9.1.0" - immer: "npm:^9.0.6" - checksum: 10/774b6d68ac95a5ec187e890d321bede50065f8a6f1ba7b49a19f5971366274054ac0e401548b51d3b014d0bca5d650409fb554dd13ce120e7fb3495b4e8e67b1 - languageName: node - linkType: hard - -"@metamask/base-controller@npm:^7.0.2": +"@metamask/base-controller@npm:^7.0.0, @metamask/base-controller@npm:^7.0.1, @metamask/base-controller@npm:^7.0.2": version: 7.0.2 resolution: "@metamask/base-controller@npm:7.0.2" dependencies: @@ -6131,24 +4927,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": - version: 11.3.0 - resolution: "@metamask/controller-utils@npm:11.3.0" - 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/3200228d1f4ea5fa095228db4e5050529caf0470e072382eb8f7571bb9b07515516ca9e846b7751388399d9ae967e4985dafd6120902ef6c998e98f4eb36d964 - languageName: node - linkType: hard - -"@metamask/controller-utils@npm:^11.4.0, @metamask/controller-utils@npm:^11.4.1, @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: @@ -6713,18 +5492,7 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-engine@npm:^10.0.0": - version: 10.0.0 - resolution: "@metamask/json-rpc-engine@npm:10.0.0" - dependencies: - "@metamask/rpc-errors": "npm:^7.0.0" - "@metamask/safe-event-emitter": "npm:^3.0.0" - "@metamask/utils": "npm:^9.1.0" - checksum: 10/2c401a4a64392aeb11c4f7ca8d7b458ba1106cff1e0b3dba8b3e0cc90e82f8c55ac2dc9fdfcd914b289e3298fb726d637cf21382336dde2c207cf76129ce5eab - languageName: node - linkType: hard - -"@metamask/json-rpc-engine@npm:^10.0.1": +"@metamask/json-rpc-engine@npm:^10.0.0, @metamask/json-rpc-engine@npm:^10.0.1": version: 10.0.1 resolution: "@metamask/json-rpc-engine@npm:10.0.1" dependencies: @@ -6768,27 +5536,15 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-middleware-stream@npm:^8.0.1, @metamask/json-rpc-middleware-stream@npm:^8.0.2": - version: 8.0.2 - resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.2" +"@metamask/json-rpc-middleware-stream@npm:^8.0.1, @metamask/json-rpc-middleware-stream@npm:^8.0.2, @metamask/json-rpc-middleware-stream@npm:^8.0.4": + version: 8.0.4 + resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.4" dependencies: - "@metamask/json-rpc-engine": "npm:^9.0.2" + "@metamask/json-rpc-engine": "npm:^10.0.0" "@metamask/safe-event-emitter": "npm:^3.0.0" "@metamask/utils": "npm:^9.1.0" readable-stream: "npm:^3.6.2" - checksum: 10/aaf41cb6fa015494eb0424959d14022b1355c390066898603223e3418d93bd72249b6e54caee3e23b4d6a679f389c2374f687882f2a7202379b4f4b042a84974 - languageName: node - linkType: hard - -"@metamask/json-rpc-middleware-stream@npm:^8.0.4": - version: 8.0.5 - resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.5" - dependencies: - "@metamask/json-rpc-engine": "npm:^10.0.1" - "@metamask/safe-event-emitter": "npm:^3.0.0" - "@metamask/utils": "npm:^10.0.0" - readable-stream: "npm:^3.6.2" - checksum: 10/486a4c64d445dc7ac7927ac5b9d01818ecef3fbb23d17eadada4748ed6cae9e259741e3c9380829b04a5c141d0972384647aedfde906dc83501b9d7f700ed621 + checksum: 10/93c842e1ac8e624c65d888cb3539b38ade5b8415ea45f649d78dad91e7139f11fa96bbf89136998d21def7711b3f710939f8e4498ce31a6cf461892e3f4ba176 languageName: node linkType: hard @@ -7107,23 +5863,7 @@ __metadata: languageName: node linkType: hard -"@metamask/phishing-controller@npm:^12.0.2": - version: 12.0.2 - resolution: "@metamask/phishing-controller@npm:12.0.2" - dependencies: - "@metamask/base-controller": "npm:^7.0.0" - "@metamask/controller-utils": "npm:^11.2.0" - "@noble/hashes": "npm:^1.4.0" - "@types/punycode": "npm:^2.1.0" - eth-phishing-detect: "npm:^1.2.0" - ethereum-cryptography: "npm:^2.1.2" - fastest-levenshtein: "npm:^1.0.16" - punycode: "npm:^2.1.1" - checksum: 10/78781e1b781c838e303677157616fb3b5e581030fe8f0ed8913f6b75fbcb7ee2ba59a44831936cc68cca8b295ef6546761b40ea3277d810b68d8ed39a58d0e29 - languageName: node - linkType: hard - -"@metamask/phishing-controller@npm:^12.3.0": +"@metamask/phishing-controller@npm:^12.0.2, @metamask/phishing-controller@npm:^12.3.0": version: 12.3.0 resolution: "@metamask/phishing-controller@npm:12.3.0" dependencies: @@ -7352,17 +6092,7 @@ __metadata: languageName: node linkType: hard -"@metamask/rpc-errors@npm:^7.0.0": - version: 7.0.0 - resolution: "@metamask/rpc-errors@npm:7.0.0" - dependencies: - "@metamask/utils": "npm:^9.0.0" - fast-safe-stringify: "npm:^2.0.6" - checksum: 10/f25e2a5506d4d0d6193c88aef8f035ec189a1177f8aee8fa01c9a33d73b1536ca7b5eea2fb33a477768bbd2abaf16529e68f0b3cf714387e5d6c9178225354fd - languageName: node - linkType: hard - -"@metamask/rpc-errors@npm:^7.0.1": +"@metamask/rpc-errors@npm:^7.0.0, @metamask/rpc-errors@npm:^7.0.1": version: 7.0.1 resolution: "@metamask/rpc-errors@npm:7.0.1" dependencies: @@ -7702,8 +6432,8 @@ __metadata: linkType: hard "@metamask/transaction-controller@npm:^38.1.0": - version: 38.2.0 - resolution: "@metamask/transaction-controller@npm:38.2.0" + version: 38.1.0 + resolution: "@metamask/transaction-controller@npm:38.1.0" dependencies: "@ethereumjs/common": "npm:^3.2.0" "@ethereumjs/tx": "npm:^4.2.0" @@ -7712,7 +6442,7 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/base-controller": "npm:^7.0.2" - "@metamask/controller-utils": "npm:^11.4.2" + "@metamask/controller-utils": "npm:^11.4.1" "@metamask/eth-query": "npm:^4.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" "@metamask/nonce-tracker": "npm:^6.0.0" @@ -7730,7 +6460,7 @@ __metadata: "@metamask/approval-controller": ^7.0.0 "@metamask/gas-fee-controller": ^22.0.0 "@metamask/network-controller": ^22.0.0 - checksum: 10/7856d2998c711bc4f4645a6845ae2b18c5312672f31377c9aeb3614fc3c5825ed3d76971f937cd55a30c26b63b0e69ea0abeb3c88c7e1134c01eac5bbc11b4d0 + checksum: 10/c1bdca52bbbce42a76ec9c640197534ec6c223b0f5d5815acfa53490dc1175850ea9aeeb6ae3c5ec34218f0bdbbbeb3e8731e2552aa9411e3ed7798a5dea8ab5 languageName: node linkType: hard @@ -14515,19 +13245,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.6": - version: 0.4.6 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6" - dependencies: - "@babel/compat-data": "npm:^7.22.6" - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10/736b1bb8e570be029f941a374c769972af870c96b5c324a5387c6b6994aabdad045ce560c530038c8626f02ec70f711ad7445f2572c32ba81fa0e13402cc23f8 - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs3@npm:^0.10.6": version: 0.10.6 resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" @@ -14540,29 +13257,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.8.5": - version: 0.8.5 - resolution: "babel-plugin-polyfill-corejs3@npm:0.8.5" - dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" - core-js-compat: "npm:^3.32.2" - peerDependencies: - "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10/5c2ac3615bd064f294a0b36bf6a1939995ec510173602e317fb18b1c015d31f46e2dd885faa3376e4da22785a515e5ba37e069f0008e5eea830d2fe3b0e66a27 - languageName: node - linkType: hard - -"babel-plugin-polyfill-regenerator@npm:^0.5.3": - version: 0.5.3 - resolution: "babel-plugin-polyfill-regenerator@npm:0.5.3" - dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" - peerDependencies: - "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10/2bb546582cda1870d19e646a7183baeb2cccd56e0ef3e4eaeabd28e120daf17cb87399194a9ccdcf32506bcaa68d23e73440fc8ab990a7a0f8c5a77c12d5d4bc - languageName: node - linkType: hard - "babel-plugin-polyfill-regenerator@npm:^0.6.1": version: 0.6.2 resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" @@ -15387,21 +14081,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.12.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.9, browserslist@npm:^4.22.1, browserslist@npm:^4.23.0": - version: 4.23.0 - resolution: "browserslist@npm:4.23.0" - dependencies: - caniuse-lite: "npm:^1.0.30001587" - electron-to-chromium: "npm:^1.4.668" - node-releases: "npm:^2.0.14" - update-browserslist-db: "npm:^1.0.13" - bin: - browserslist: cli.js - checksum: 10/496c3862df74565dd942b4ae65f502c575cbeba1fa4a3894dad7aa3b16130dc3033bc502d8848147f7b625154a284708253d9598bcdbef5a1e34cf11dc7bad8e - languageName: node - linkType: hard - -"browserslist@npm:^4.24.0, browserslist@npm:^4.24.2": +"browserslist@npm:^4.12.0, browserslist@npm:^4.21.10, browserslist@npm:^4.23.0, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0": version: 4.24.2 resolution: "browserslist@npm:4.24.2" dependencies: @@ -15851,17 +14531,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001587, caniuse-lite@npm:^1.0.30001599": - version: 1.0.30001660 - resolution: "caniuse-lite@npm:1.0.30001660" - checksum: 10/5d83f0b7e2075b7e31f114f739155dc6c21b0afe8cb61180f625a4903b0ccd3d7591a5f81c930f14efddfa57040203ba0890850b8a3738f6c7f17c7dd83b9de8 - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001669": - version: 1.0.30001677 - resolution: "caniuse-lite@npm:1.0.30001677" - checksum: 10/e07439bdeade5ffdd974691f44f8549ae0730fcf510acaa32d0b657c10370cd5aad09eeca37248966205fb37fce5f464dbce73ce177b4a1fdc3a34adbcfd7192 +"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001669": + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 10/cd0b481bb997703cb7651e55666b4aa4e7b4ecf9784796e2393179a15e55c71a6abc6ff865c922bbd3bbfa4a4bf0530d8da13989b97ff8c7850c8a5bd4e00491 languageName: node linkType: hard @@ -16952,21 +15625,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.32.2": - version: 3.33.0 - resolution: "core-js-compat@npm:3.33.0" - dependencies: - browserslist: "npm:^4.22.1" - checksum: 10/b1a5f7aab1c6ac0efd86c1412a5b27fb372c4e52c4b8f2c80b05216385125c4de30e4c36e4bcc6bfeec917a56e7736c87fab6a301ff8faaa1ae4acf81643fc9a - languageName: node - linkType: hard - "core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": - version: 3.39.0 - resolution: "core-js-compat@npm:3.39.0" + version: 3.38.1 + resolution: "core-js-compat@npm:3.38.1" dependencies: - browserslist: "npm:^4.24.2" - checksum: 10/82d5fcb54087f1fc174283c2d30b62908edc828537574f95bb49a5b7f235bcc88ba43f37dbe470c47e17fd9bc01cbc1db905062fd96ba65ff1a03c235f288aca + browserslist: "npm:^4.23.3" + checksum: 10/4e2f219354fd268895f79486461a12df96f24ed307321482fe2a43529c5a64e7c16bcba654980ba217d603444f5141d43a79058aeac77511085f065c5da72207 languageName: node linkType: hard @@ -18710,17 +17374,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.668": - version: 1.4.715 - resolution: "electron-to-chromium@npm:1.4.715" - checksum: 10/0fc9fc9fe2c4082c87672d229437c918f43c19ad81274afcdf2d36fba96bfaaee0d9254c309879fbea8eeb2c13fd1b5cf51e0967d55790206697914cecff9c6b - languageName: node - linkType: hard - "electron-to-chromium@npm:^1.5.41": - version: 1.5.50 - resolution: "electron-to-chromium@npm:1.5.50" - checksum: 10/635ca4b593e64697fbebc9fe7f557abcb030e5f6edcefb596ae3f8c9313221a754b513b70f2ba12595a9ee5733442b2b58db9eed7a2fa63e9f7539d581dd4ac0 + version: 1.5.45 + resolution: "electron-to-chromium@npm:1.5.45" + checksum: 10/659b4b979c9c1a63c170c398775daa269acf5c4117f6590ad4677266fa77a680ebf7792e0eb8dc6d4041550e4ec82ad7dd3aac75543d30535b53bc3c1e4d05ff languageName: node linkType: hard @@ -19313,14 +17970,7 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1": - version: 3.1.1 - resolution: "escalade@npm:3.1.1" - checksum: 10/afa618e73362576b63f6ca83c975456621095a1ed42ff068174e3f5cea48afc422814dda548c96e6ebb5333e7265140c7292abcc81bbd6ccb1757d50d3a4e182 - languageName: node - linkType: hard - -"escalade@npm:^3.2.0": +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 @@ -25753,15 +24403,6 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^2.5.1": - version: 2.5.2 - resolution: "jsesc@npm:2.5.2" - bin: - jsesc: bin/jsesc - checksum: 10/d2096abdcdec56969764b40ffc91d4a23408aa2f351b4d1c13f736f25476643238c43fdbaf38a191c26b1b78fd856d965f5d4d0dde7b89459cd94025190cdf13 - languageName: node - linkType: hard - "jsesc@npm:^3.0.2, jsesc@npm:~3.0.2": version: 3.0.2 resolution: "jsesc@npm:3.0.2" @@ -25771,15 +24412,6 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" - bin: - jsesc: bin/jsesc - checksum: 10/fab949f585c71e169c5cbe00f049f20de74f067081bbd64a55443bad1c71e1b5a5b448f2359bf2fe06f5ed7c07e2e4a9101843b01c823c30b6afc11f5bfaf724 - languageName: node - linkType: hard - "json-buffer@npm:3.0.0": version: 3.0.0 resolution: "json-buffer@npm:3.0.0" @@ -28652,14 +27284,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.9.1": - version: 2.9.2 - resolution: "mini-css-extract-plugin@npm:2.9.2" + version: 2.9.1 + resolution: "mini-css-extract-plugin@npm:2.9.1" dependencies: schema-utils: "npm:^4.0.0" tapable: "npm:^2.2.1" peerDependencies: webpack: ^5.0.0 - checksum: 10/db6ddb8ba56affa1a295b57857d66bad435d36e48e1f95c75d16fadd6c70e3ba33e8c4141c3fb0e22b4d875315b41c4f58550c6ac73b50bdbe429f768297e3ff + checksum: 10/a4a0c73a054254784b9d39a3a4f117691600355125242dfc46ced0912b4937050823478bdbf403b5392c21e2fb2203902b41677d67c7d668f77b985b594e94c6 languageName: node linkType: hard @@ -29497,13 +28129,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 10/0f7607ec7db5ef1dc616899a5f24ae90c869b6a54c2d4f36ff6d84a282ab9343c7ff3ca3670fe4669171bb1e8a9b3e286e1ef1c131f09a83d70554f855d54f24 - languageName: node - linkType: hard - "node-releases@npm:^2.0.18": version: 2.0.18 resolution: "node-releases@npm:2.0.18" @@ -30770,14 +29395,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: 10/a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 - languageName: node - linkType: hard - -"picocolors@npm:^1.1.0": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -30873,7 +29491,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.4, pirates@npm:^4.0.5, pirates@npm:^4.0.6": +"pirates@npm:^4.0.4, pirates@npm:^4.0.6": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 10/d02dda76f4fec1cbdf395c36c11cf26f76a644f9f9a1bfa84d3167d0d3154d5289aacc72677aa20d599bb4a6937a471de1b65c995e2aea2d8687cbcd7e43ea5f @@ -32983,15 +31601,6 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.1.0": - version: 10.1.0 - resolution: "regenerate-unicode-properties@npm:10.1.0" - dependencies: - regenerate: "npm:^1.4.2" - checksum: 10/25b268659898955ad105267b4efba20e361e27b233670694b683728a2800314bec3053918d3bf71b0604376fd76fe9bc9c6f80379cfb6d1e209a58de44101aac - languageName: node - linkType: hard - "regenerate-unicode-properties@npm:^10.2.0": version: 10.2.0 resolution: "regenerate-unicode-properties@npm:10.2.0" @@ -33090,20 +31699,6 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^5.3.1": - version: 5.3.2 - resolution: "regexpu-core@npm:5.3.2" - dependencies: - "@babel/regjsgen": "npm:^0.8.0" - regenerate: "npm:^1.4.2" - regenerate-unicode-properties: "npm:^10.1.0" - regjsparser: "npm:^0.9.1" - unicode-match-property-ecmascript: "npm:^2.0.0" - unicode-match-property-value-ecmascript: "npm:^2.1.0" - checksum: 10/ed0d7c66d84c633fbe8db4939d084c780190eca11f6920807dfb8ebac59e2676952cd8f2008d9c86ae8cf0463ea5fd12c5cff09ef2ce7d51ee6b420a5eb4d177 - languageName: node - linkType: hard - "regexpu-core@npm:^6.1.1": version: 6.1.1 resolution: "regexpu-core@npm:6.1.1" @@ -33163,24 +31758,13 @@ __metadata: linkType: hard "regjsparser@npm:^0.11.0": - version: 0.11.2 - resolution: "regjsparser@npm:0.11.2" + version: 0.11.1 + resolution: "regjsparser@npm:0.11.1" dependencies: jsesc: "npm:~3.0.2" bin: regjsparser: bin/parser - checksum: 10/8075eb76d6cde8a3f188696eb18ebf229376944d35e3043f73b889a15156cf539f2801941a5630433060512cbcb2f92f6a194fac44f2e0f1497517e12aa565b3 - languageName: node - linkType: hard - -"regjsparser@npm:^0.9.1": - version: 0.9.1 - resolution: "regjsparser@npm:0.9.1" - dependencies: - jsesc: "npm:~0.5.0" - bin: - regjsparser: bin/parser - checksum: 10/be7757ef76e1db10bf6996001d1021048b5fb12f5cb470a99b8cf7f3ff943f0f0e2291c0dcdbb418b458ddc4ac10e48680a822b69ef487a0284c8b6b77beddc3 + checksum: 10/06295f1666f8e378c3b70eb01578b46e075eee0556865a297497ab40753f04cce526e96513b18e21e66b79c972e7377bd3b5caa86935ed5d736e9b3e0f857363 languageName: node linkType: hard @@ -37732,20 +36316,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.13": - version: 1.0.13 - resolution: "update-browserslist-db@npm:1.0.13" - dependencies: - escalade: "npm:^3.1.1" - picocolors: "npm:^1.0.0" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10/9074b4ef34d2ed931f27d390aafdd391ee7c45ad83c508e8fed6aaae1eb68f81999a768ed8525c6f88d4001a4fbf1b8c0268f099d0e8e72088ec5945ac796acf - languageName: node - linkType: hard - "update-browserslist-db@npm:^1.1.1": version: 1.1.1 resolution: "update-browserslist-db@npm:1.1.1" @@ -39347,7 +37917,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.3.4": +"yaml@npm:^2.3.4, yaml@npm:^2.4.1": version: 2.6.0 resolution: "yaml@npm:2.6.0" bin: @@ -39356,15 +37926,6 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.4.1": - version: 2.4.1 - resolution: "yaml@npm:2.4.1" - bin: - yaml: bin.mjs - checksum: 10/2c54fd69ef59126758ae710f9756405a7d41abcbb61aca894250d0e81e76057c14dc9bb00a9528f72f99b8f24077f694a6f7fd09cdd6711fcec2eebfbb5df409 - languageName: node - linkType: hard - "yargs-parser@npm:20.2.4": version: 20.2.4 resolution: "yargs-parser@npm:20.2.4" From febc7f12ea23d0e05f7273c761af7dd51713502d Mon Sep 17 00:00:00 2001 From: Brian Bergeron Date: Fri, 8 Nov 2024 08:29:23 -0800 Subject: [PATCH 32/73] fix typo --- ui/hooks/useAccountTotalFiatBalance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/hooks/useAccountTotalFiatBalance.js b/ui/hooks/useAccountTotalFiatBalance.js index 1fc702a42f4a..64d9df02737d 100644 --- a/ui/hooks/useAccountTotalFiatBalance.js +++ b/ui/hooks/useAccountTotalFiatBalance.js @@ -55,7 +55,7 @@ export const useAccountTotalFiatBalance = ( const nativeCurrency = useSelector(getNativeCurrency); const loading = false; - const { loading:tokensWithBalances } = useTokenTracker({ + const { tokensWithBalances } = useTokenTracker({ chainId: currentChainId, tokens, address: account.address, From 31303e632f2440f1cba33aa8887b8aeb0566fc12 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 12 Nov 2024 09:40:26 +0100 Subject: [PATCH 33/73] feat: cross-chain aggregated balances and percentages --- .../controllers/account-tracker-controller.ts | 1 + privacy-snapshot.json | 3 + ...entage-overview-cross-chains.test.tsx.snap | 23 + ...-percentage-overview-cross-chains.test.tsx | 584 ++++++++++++++++++ ...gated-percentage-overview-cross-chains.tsx | 197 ++++++ .../app/wallet-overview/coin-overview.tsx | 39 +- ui/ducks/metamask/metamask.js | 4 + .../useAccountTotalCrossChainFiatBalance.js | 109 ++++ ui/hooks/useTokenBalances.ts | 24 +- ui/selectors/selectors.js | 48 +- 10 files changed, 1013 insertions(+), 19 deletions(-) create mode 100644 ui/components/app/wallet-overview/__snapshots__/aggregated-percentage-overview-cross-chains.test.tsx.snap create mode 100644 ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx create mode 100644 ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx create mode 100644 ui/hooks/useAccountTotalCrossChainFiatBalance.js diff --git a/app/scripts/controllers/account-tracker-controller.ts b/app/scripts/controllers/account-tracker-controller.ts index 5f509a1901bf..b800ea0a8b3c 100644 --- a/app/scripts/controllers/account-tracker-controller.ts +++ b/app/scripts/controllers/account-tracker-controller.ts @@ -675,6 +675,7 @@ export default class AccountTrackerController extends BaseController< let addresses = []; if (useMultiAccountBalanceChecker) { const { accounts } = this.state; + console.log('🚀 ~ updateAccounts ~ accounts:', accounts); addresses = Object.keys(accounts); } else { diff --git a/privacy-snapshot.json b/privacy-snapshot.json index 589504ea2cc7..f6333813954c 100644 --- a/privacy-snapshot.json +++ b/privacy-snapshot.json @@ -29,6 +29,8 @@ "github.com", "goerli.infura.io", "lattice.gridplus.io", + "linea-mainnet.infura.io", + "linea-sepolia.infura.io", "localhost:8000", "localhost:8545", "mainnet.infura.io", @@ -51,6 +53,7 @@ "security-alerts.api.cx.metamask.io", "security-alerts.dev-api.cx.metamask.io", "sentry.io", + "sepolia.infura.io", "snaps.metamask.io", "sourcify.dev", "start.metamask.io", diff --git a/ui/components/app/wallet-overview/__snapshots__/aggregated-percentage-overview-cross-chains.test.tsx.snap b/ui/components/app/wallet-overview/__snapshots__/aggregated-percentage-overview-cross-chains.test.tsx.snap new file mode 100644 index 000000000000..c0c5129a16a4 --- /dev/null +++ b/ui/components/app/wallet-overview/__snapshots__/aggregated-percentage-overview-cross-chains.test.tsx.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AggregatedPercentageOverviewCrossChains render renders correctly 1`] = ` +
+
+

+ +$0.22 +

+

+ (+0.08%) +

+
+
+`; diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx new file mode 100644 index 000000000000..512aa42e866d --- /dev/null +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx @@ -0,0 +1,584 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { getIntlLocale } from '../../../ducks/locale/locale'; +import { + getCurrentCurrency, + getSelectedAccount, + getShouldHideZeroBalanceTokens, + getPreferences, + getMarketData, + getNetworkConfigurationsByChainId, + getAllTokens, +} from '../../../selectors'; +import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; +import { AggregatedPercentageOverview } from './aggregated-percentage-overview'; +import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; + +jest.mock('react-redux', () => ({ + useSelector: jest.fn((selector) => selector()), +})); +const mockUseTokenTracker = jest.fn().mockReturnValue({ + tokensWithBalances: {}, +}); +jest.mock('../../../hooks/useTokenBalances', () => ({ + useTokenTracker: () => mockUseTokenTracker(), +})); + +jest.mock('../../../ducks/locale/locale', () => ({ + getIntlLocale: jest.fn(), +})); + +jest.mock('../../../selectors', () => ({ + getCurrentCurrency: jest.fn(), + getSelectedAccount: jest.fn(), + getPreferences: jest.fn(), + getShouldHideZeroBalanceTokens: jest.fn(), + getMarketData: jest.fn(), + getNetworkConfigurationsByChainId: jest.fn(), + getAllTokens: jest.fn(), +})); + +jest.mock('../../../hooks/useAccountTotalCrossChainFiatBalance', () => ({ + useAccountTotalCrossChainFiatBalance: jest.fn(), +})); + +const mockGetIntlLocale = getIntlLocale as unknown as jest.Mock; +const mockGetCurrentCurrency = getCurrentCurrency as jest.Mock; +const mockGetPreferences = getPreferences as jest.Mock; +const mockGetSelectedAccount = getSelectedAccount as unknown as jest.Mock; +const mockGetShouldHideZeroBalanceTokens = + getShouldHideZeroBalanceTokens as jest.Mock; + +const mockGetMarketData = getMarketData as jest.Mock; +const mockGetNetworkConfigurationsByChainId = + getNetworkConfigurationsByChainId as unknown as jest.Mock; +const mockGetAllTokens = getAllTokens as jest.Mock; + +const allTokens = { + '0x1': { + '0x2990079bcdee240329a520d2444386fc119da21a': [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + aggregators: [ + 'Metamask', + 'Aave', + 'Bancor', + 'Crypto.com', + 'CoinGecko', + '1inch', + 'PMM', + 'Sushiswap', + 'Zerion', + 'Lifi', + 'Socket', + 'Squid', + 'Openswap', + 'UniswapLabs', + 'Coinmarketcap', + ], + decimals: 6, + symbol: 'USDC', + }, + ], + }, + '0xe708': { + '0x2990079bcdee240329a520d2444386fc119da21a': [ + { + address: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + aggregators: ['LineaTeam', 'CoinGecko', 'Lifi', 'Rubic', 'Xswap'], + decimals: 18, + symbol: 'DAI', + }, + { + address: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + aggregators: [ + 'LineaTeam', + 'CoinGecko', + 'Lifi', + 'Squid', + 'Rubic', + 'Xswap', + ], + decimals: 6, + symbol: 'USDT', + }, + ], + }, +}; +const networkConfigsByChainId = { + '0x1': { + blockExplorerUrls: ['https://etherscan.io'], + chainId: '0x1', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Ethereum Mainnet', + nativeCurrency: 'ETH', + rpcEndpoints: [ + { + networkClientId: 'mainnet', + type: 'infura', + url: 'https://mainnet.infura.io/v3/{infuraProjectId}', + }, + ], + }, + '0xaa36a7': { + blockExplorerUrls: ['https://sepolia.etherscan.io'], + chainId: '0xaa36a7', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Sepolia', + nativeCurrency: 'SepoliaETH', + rpcEndpoints: [ + { + networkClientId: 'sepolia', + type: 'infura', + url: 'https://sepolia.infura.io/v3/{infuraProjectId}', + }, + ], + }, + '0xe705': { + blockExplorerUrls: ['https://sepolia.lineascan.build'], + chainId: '0xe705', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Linea Sepolia', + nativeCurrency: 'LineaETH', + rpcEndpoints: [ + { + networkClientId: 'linea-sepolia', + type: 'infura', + url: 'https://linea-sepolia.infura.io/v3/{infuraProjectId}', + }, + ], + }, + '0xe708': { + blockExplorerUrls: ['https://lineascan.build'], + chainId: '0xe708', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Linea Mainnet', + nativeCurrency: 'ETH', + rpcEndpoints: [ + { + networkClientId: 'linea-mainnet', + type: 'infura', + url: 'https://linea-mainnet.infura.io/v3/{infuraProjectId}', + }, + ], + }, +}; +const selectedAccountMock = { + id: 'd51c0116-de36-4e77-b35b-408d4ea82d01', + address: '0x2990079bcdee240329a520d2444386fc119da21a', + options: {}, + methods: [ + 'personal_sign', + 'eth_sign', + 'eth_signTransaction', + 'eth_signTypedData_v1', + 'eth_signTypedData_v3', + 'eth_signTypedData_v4', + ], + type: 'eip155:eoa', + metadata: { + name: 'Account 2', + importTime: 1725467263902, + lastSelected: 1725467263905, + keyring: { + type: 'Simple Key Pair', + }, + }, + balance: '0x0f7e2a03e67666', +}; + +const crossChainMarketDataMock = { + '0x1': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: 0.8551361112650235, + }, + '0x6B175474E89094C44Da98b954EedeAC495271d0F': { + tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + currency: 'ETH', + id: 'dai', + price: 0.00031298237681361845, + pricePercentChange1d: -0.19413664311573345, + }, + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': { + tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + currency: 'ETH', + id: 'usd-coin', + price: 0.00031298237681361845, + pricePercentChange1d: -0.08092791615953396, + }, + '0xdAC17F958D2ee523a2206206994597C13D831ec7': { + tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + currency: 'ETH', + id: 'tether', + price: 0.00031329535919043206, + pricePercentChange1d: -0.09790827980452445, + }, + }, + '0xaa36a7': {}, + '0xe705': {}, + '0xe708': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: 0.8551361112650235, + }, + '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5': { + tokenAddress: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + currency: 'ETH', + id: 'bridged-dai-stablecoin-linea', + price: 0.00031298237681361845, + pricePercentChange1d: -0.22242916875537241, + }, + '0xA219439258ca9da29E9Cc4cE5596924745e12B93': { + tokenAddress: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + currency: 'ETH', + id: 'bridged-tether-linea', + price: 0.0003136083415672457, + pricePercentChange1d: -0.2013707959252836, + }, + }, +}; + +const negativeCrossChainMarketDataMock = { + '0x1': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: -0.8551361112650235, + }, + '0x6B175474E89094C44Da98b954EedeAC495271d0F': { + tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + currency: 'ETH', + id: 'dai', + price: 0.00031298237681361845, + pricePercentChange1d: -0.19413664311573345, + }, + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': { + tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + currency: 'ETH', + id: 'usd-coin', + price: 0.00031298237681361845, + pricePercentChange1d: -0.08092791615953396, + }, + '0xdAC17F958D2ee523a2206206994597C13D831ec7': { + tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + currency: 'ETH', + id: 'tether', + price: 0.00031329535919043206, + pricePercentChange1d: -0.09790827980452445, + }, + }, + '0xaa36a7': {}, + '0xe705': {}, + '0xe708': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: -0.8551361112650235, + }, + '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5': { + tokenAddress: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + currency: 'ETH', + id: 'bridged-dai-stablecoin-linea', + price: 0.00031298237681361845, + pricePercentChange1d: -0.22242916875537241, + }, + '0xA219439258ca9da29E9Cc4cE5596924745e12B93': { + tokenAddress: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + currency: 'ETH', + id: 'bridged-tether-linea', + price: 0.0003136083415672457, + pricePercentChange1d: -0.2013707959252836, + }, + }, +}; +const positiveCrossChainMarketDataMock = { + '0x1': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: 0.8551361112650235, + }, + '0x6B175474E89094C44Da98b954EedeAC495271d0F': { + tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + currency: 'ETH', + id: 'dai', + price: 0.00031298237681361845, + pricePercentChange1d: 0.19413664311573345, + }, + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': { + tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + currency: 'ETH', + id: 'usd-coin', + price: 0.00031298237681361845, + pricePercentChange1d: 0.08092791615953396, + }, + '0xdAC17F958D2ee523a2206206994597C13D831ec7': { + tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + currency: 'ETH', + id: 'tether', + price: 0.00031329535919043206, + pricePercentChange1d: 0.09790827980452445, + }, + }, + '0xaa36a7': {}, + '0xe705': {}, + '0xe708': { + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + currency: 'ETH', + id: 'ethereum', + price: 0.9999974728621198, + pricePercentChange1d: 0.8551361112650235, + }, + '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5': { + tokenAddress: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + currency: 'ETH', + id: 'bridged-dai-stablecoin-linea', + price: 0.00031298237681361845, + pricePercentChange1d: 0.22242916875537241, + }, + '0xA219439258ca9da29E9Cc4cE5596924745e12B93': { + tokenAddress: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + currency: 'ETH', + id: 'bridged-tether-linea', + price: 0.0003136083415672457, + pricePercentChange1d: 0.2013707959252836, + }, + }, +}; +describe('AggregatedPercentageOverviewCrossChains', () => { + beforeEach(() => { + mockGetIntlLocale.mockReturnValue('en-US'); + mockGetCurrentCurrency.mockReturnValue('USD'); + mockGetPreferences.mockReturnValue({ privacyMode: false }); + mockGetSelectedAccount.mockReturnValue(selectedAccountMock); + mockGetShouldHideZeroBalanceTokens.mockReturnValue(false); + + mockGetMarketData.mockReturnValue(crossChainMarketDataMock); + mockGetNetworkConfigurationsByChainId.mockReturnValue( + networkConfigsByChainId, + ); + mockGetAllTokens.mockReturnValue(allTokens); + + jest.clearAllMocks(); + }); + + describe('render', () => { + it('renders correctly', () => { + (useAccountTotalCrossChainFiatBalance as jest.Mock).mockReturnValue({ + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + decimals: 6, + }, + ], + tokenFiatBalances: ['70'], + nativeFiatValue: '69.96', + }, + { + chainId: '0xe708', + tokensWithBalances: [ + { + address: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + symbol: 'DAI', + decimals: 18, + }, + { + address: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + symbol: 'USDT', + decimals: 6, + }, + ], + tokenFiatBalances: ['50', '100'], + nativeFiatValue: '0', + }, + ], + totalFiatBalance: 289.96, + }); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + }); + + it('should display zero percentage and amount if balance is zero across chains', () => { + (useAccountTotalCrossChainFiatBalance as jest.Mock).mockReturnValue({ + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + tokensWithBalances: [], + tokenFiatBalances: [], + nativeFiatValue: '0', + }, + { + chainId: '0xe708', + tokensWithBalances: [], + tokenFiatBalances: [], + nativeFiatValue: '0', + }, + ], + totalFiatBalance: 0, + }); + + render(); + const percentageElement = screen.getByText('(+0.00%)'); + const numberElement = screen.getByText('+$0.00'); + expect(percentageElement).toBeInTheDocument(); + expect(numberElement).toBeInTheDocument(); + }); + + it('should display negative aggregated amount and percentage change with all negative market data cross chains', () => { + (useAccountTotalCrossChainFiatBalance as jest.Mock).mockReturnValue({ + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + decimals: 6, + }, + ], + tokenFiatBalances: ['70'], + nativeFiatValue: '69.96', + }, + { + chainId: '0xe708', + tokensWithBalances: [ + { + address: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + symbol: 'DAI', + decimals: 18, + }, + { + address: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + symbol: 'USDT', + decimals: 6, + }, + ], + tokenFiatBalances: ['50', '100'], + nativeFiatValue: '0', + }, + ], + totalFiatBalance: 289.96, + }); + mockGetMarketData.mockReturnValue(negativeCrossChainMarketDataMock); + const expectedAmountChange = '-$0.97'; + const expectedPercentageChange = '(-0.33%)'; + render(); + const percentageElement = screen.getByText(expectedPercentageChange); + const numberElement = screen.getByText(expectedAmountChange); + expect(percentageElement).toBeInTheDocument(); + expect(numberElement).toBeInTheDocument(); + }); + + it('should display positive aggregated amount and percentage change with all positive market data', () => { + (useAccountTotalCrossChainFiatBalance as jest.Mock).mockReturnValue({ + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + decimals: 6, + }, + ], + tokenFiatBalances: ['70'], + nativeFiatValue: '69.96', + }, + { + chainId: '0xe708', + tokensWithBalances: [ + { + address: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + symbol: 'DAI', + decimals: 18, + }, + { + address: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + symbol: 'USDT', + decimals: 6, + }, + ], + tokenFiatBalances: ['50', '100'], + nativeFiatValue: '0', + }, + ], + totalFiatBalance: 289.96, + }); + mockGetMarketData.mockReturnValue(positiveCrossChainMarketDataMock); + const expectedAmountChange = '+$0.96'; + const expectedPercentageChange = '(+0.33%)'; + render(); + const percentageElement = screen.getByText(expectedPercentageChange); + const numberElement = screen.getByText(expectedAmountChange); + expect(percentageElement).toBeInTheDocument(); + expect(numberElement).toBeInTheDocument(); + }); + + it('should display correct aggregated amount and percentage change with positive and negative market data', () => { + (useAccountTotalCrossChainFiatBalance as jest.Mock).mockReturnValue({ + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + decimals: 6, + }, + ], + tokenFiatBalances: ['70'], + nativeFiatValue: '69.96', + }, + { + chainId: '0xe708', + tokensWithBalances: [ + { + address: '0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5', + symbol: 'DAI', + decimals: 18, + }, + { + address: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + symbol: 'USDT', + decimals: 6, + }, + ], + tokenFiatBalances: ['50', '100'], + nativeFiatValue: '0', + }, + ], + totalFiatBalance: 289.96, + }); + const expectedAmountChange = '+$0.22'; + const expectedPercentageChange = '(+0.08%)'; + render(); + const percentageElement = screen.getByText(expectedPercentageChange); + const numberElement = screen.getByText(expectedAmountChange); + expect(percentageElement).toBeInTheDocument(); + expect(numberElement).toBeInTheDocument(); + }); +}); diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx new file mode 100644 index 000000000000..cc8ba35ab837 --- /dev/null +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx @@ -0,0 +1,197 @@ +import React, { useMemo } from 'react'; +import { useSelector } from 'react-redux'; + +import { zeroAddress, toChecksumAddress } from 'ethereumjs-util'; +import { + getCurrentCurrency, + getSelectedAccount, + getShouldHideZeroBalanceTokens, + getPreferences, + getMarketData, + getNetworkConfigurationsByChainId, + getAllTokens, +} from '../../../selectors'; + +// TODO: Remove restricted import +// eslint-disable-next-line import/no-restricted-paths +import { formatValue, isValidAmount } from '../../../../app/scripts/lib/util'; +import { getIntlLocale } from '../../../ducks/locale/locale'; +import { + Display, + TextColor, + TextVariant, +} from '../../../helpers/constants/design-system'; +import { Box, SensitiveText } from '../../component-library'; +import { getCalculatedTokenAmount1dAgo } from '../../../helpers/utils/util'; +import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; +import { TEST_CHAINS } from '../../../../shared/constants/network'; +import { useTokenTracker } from '../../../hooks/useTokenBalances'; + +export const AggregatedPercentageOverviewCrossChains = () => { + const locale = useSelector(getIntlLocale); + const fiatCurrency = useSelector(getCurrentCurrency); + const { privacyMode } = useSelector(getPreferences); + const selectedAccount = useSelector(getSelectedAccount); + const shouldHideZeroBalanceTokens = useSelector( + getShouldHideZeroBalanceTokens, + ); + const crossChainMarketData = useSelector(getMarketData); + + const allNetworks = useSelector(getNetworkConfigurationsByChainId); + const allChainIDs = Object.entries(allNetworks) + .map(([chainIdElm, _]) => { + return chainIdElm; + }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId as any)); + + const detectedTokens = useSelector(getAllTokens); + const dataTokensWithBalancesCrossChain = allChainIDs.map((singleChain) => { + const tokens = + detectedTokens?.[singleChain]?.[selectedAccount?.address] ?? []; + const { tokensWithBalances } = useTokenTracker({ + chainId: singleChain as `0x${string}`, + tokens, + address: selectedAccount.address, + hideZeroBalanceTokens: shouldHideZeroBalanceTokens, + }); + return { + chainId: singleChain, + tokensWithBalances, + }; + }); + const { + totalFiatBalance: totalFiatCrossChains, + tokenFiatBalancesCrossChains, + } = useAccountTotalCrossChainFiatBalance( + selectedAccount, + dataTokensWithBalancesCrossChain, + ); + + const getPerChainTotalFiat1dAgo = ( + chainId: string, + tokenFiatBalances: { [x: string]: any }, + tokensWithBalances: any[], + ) => { + const totalPerChain1dAgoERC20 = tokensWithBalances.reduce( + (total1dAgo: number, item: { address: string }, idx: string | number) => { + const found = + crossChainMarketData?.[chainId]?.[toChecksumAddress(item.address)]; + + const tokenFiat1dAgo = getCalculatedTokenAmount1dAgo( + tokenFiatBalances[idx], + found?.pricePercentChange1d, + ); + return total1dAgo + Number(tokenFiat1dAgo); + }, + 0, + ); + + return totalPerChain1dAgoERC20; + }; + + const totalFiat1dAgoCrossChains = useMemo(() => { + return tokenFiatBalancesCrossChains.reduce( + (total1dAgoCrossChains: any, item: any) => { + const perChainERC20Total = getPerChainTotalFiat1dAgo( + item.chainId, + item.tokenFiatBalances, + item.tokensWithBalances, + ); + const nativePricePercentChange1d = + crossChainMarketData?.[item.chainId]?.[zeroAddress()] + ?.pricePercentChange1d; + + const nativeFiat1dAgo = getCalculatedTokenAmount1dAgo( + item.nativeFiatValue, + nativePricePercentChange1d, + ); + return ( + total1dAgoCrossChains + perChainERC20Total + Number(nativeFiat1dAgo) + ); + }, + 0, + ); // Initial total1dAgo is 0 + }, [tokenFiatBalancesCrossChains, crossChainMarketData]); + + const totalCrossChainBalance: number = Number(totalFiatCrossChains); + const crossChainTotalBalance1dAgo = totalFiat1dAgoCrossChains; + + const amountChangeCrossChains = + totalCrossChainBalance - crossChainTotalBalance1dAgo; + const percentageChangeCrossChains = + (amountChangeCrossChains / crossChainTotalBalance1dAgo) * 100 || 0; + + const formattedPercentChangeCrossChains = formatValue( + amountChangeCrossChains === 0 ? 0 : percentageChangeCrossChains, + true, + ); + + let formattedAmountChangeCrossChains = ''; + if (isValidAmount(amountChangeCrossChains)) { + formattedAmountChangeCrossChains = + (amountChangeCrossChains as number) >= 0 ? '+' : ''; + + const options = { + notation: 'compact', + compactDisplay: 'short', + maximumFractionDigits: 2, + } as const; + + try { + // For currencies compliant with ISO 4217 Standard + formattedAmountChangeCrossChains += `${Intl.NumberFormat(locale, { + ...options, + style: 'currency', + currency: fiatCurrency, + }).format(amountChangeCrossChains as number)} `; + } catch { + // Non-standard Currency Codes + formattedAmountChangeCrossChains += `${Intl.NumberFormat(locale, { + ...options, + minimumFractionDigits: 2, + style: 'decimal', + }).format(amountChangeCrossChains as number)} `; + } + } + + let color = TextColor.textDefault; + + if (!privacyMode && isValidAmount(amountChangeCrossChains)) { + if ((amountChangeCrossChains as number) === 0) { + color = TextColor.textDefault; + } else if ((amountChangeCrossChains as number) > 0) { + color = TextColor.successDefault; + } else { + color = TextColor.errorDefault; + } + } else { + color = TextColor.textAlternative; + } + + return ( + + + {formattedAmountChangeCrossChains} + + + {formattedPercentChangeCrossChains} + + + ); +}; diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 9f267c96a53d..3536ebad8614 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -55,13 +55,14 @@ import { getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, + getAllTokens, + getNetworkConfigurationsByChainId, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; import { PercentageAndAmountChange } from '../../multichain/token-list-item/price/percentage-and-amount-change/percentage-and-amount-change'; import { getMultichainIsEvm } from '../../../selectors/multichain'; -import { useAccountTotalFiatBalance } from '../../../hooks/useAccountTotalFiatBalance'; import { setAggregatedBalancePopoverShown, setPrivacyMode, @@ -69,9 +70,12 @@ import { import { useTheme } from '../../../hooks/useTheme'; import { getSpecificSettingsRoute } from '../../../helpers/utils/settings-search'; import { useI18nContext } from '../../../hooks/useI18nContext'; +import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; +import { useTokenTracker } from '../../../hooks/useTokenBalances'; +import { TEST_CHAINS } from '../../../../shared/constants/network'; import WalletOverview from './wallet-overview'; import CoinButtons from './coin-buttons'; -import { AggregatedPercentageOverview } from './aggregated-percentage-overview'; +import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; export type CoinOverviewProps = { balance: string; @@ -138,9 +142,31 @@ export const CoinOverview = ({ const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); - const { totalFiatBalance, loading } = useAccountTotalFiatBalance( + const allNetworks = useSelector(getNetworkConfigurationsByChainId); + const allChainIDs = Object.entries(allNetworks) + .map(([chainIdElm, _]) => { + return chainIdElm; + }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId as any)); + + const detectedTokens = useSelector(getAllTokens); + const dataTokensWithBalancesCrossChain = allChainIDs.map((singleChain) => { + const tokens = detectedTokens?.[singleChain]?.[account?.address] ?? []; + const { tokensWithBalances } = useTokenTracker({ + chainId: singleChain as `0x${string}`, + tokens, + address: account.address, + hideZeroBalanceTokens: shouldHideZeroBalanceTokens, + }); + return { + chainId: singleChain, + tokensWithBalances, + }; + }); + const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( selectedAccount, - shouldHideZeroBalanceTokens, + dataTokensWithBalancesCrossChain, ); const { showNativeTokenAsMainBalance } = useSelector(getPreferences); @@ -151,7 +177,7 @@ export const CoinOverview = ({ let balanceToDisplay; if (isNotAggregatedFiatBalance) { balanceToDisplay = balance; - } else if (!loading) { + } else { balanceToDisplay = totalFiatBalance; } @@ -226,7 +252,8 @@ export const CoinOverview = ({ } return ( - + {/* */} + { ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) { + const allNetworks = useSelector(getNetworkConfigurationsByChainId); + + const currencyRates = useSelector(getCurrencyRates); + + const conversionRate = useSelector(getConversionRate); + const currentCurrency = useSelector(getCurrentCurrency); + + const crossChainContractRates = useSelector( + getCrossChainTokenExchangeRates, + shallowEqual, + ); + + const crossChainCachedBalances = useSelector( + getCrossChainMetaMaskCachedBalances, + ); + + // const loading = false; //todo check if loading is still needed + + const mergedCrossChainRates = { + ...crossChainContractRates, // todo add confirmation exchange rates? + }; + + const tokenFiatBalancesCrossChains = dataTokensWithBalancesCrossChain.map( + (singleChainTokenBalances) => { + const { tokensWithBalances } = singleChainTokenBalances; + const tokenFiatBalances = tokensWithBalances.map((token) => { + const tokenExchangeRate = + mergedCrossChainRates[singleChainTokenBalances.chainId][ + toChecksumAddress(token.address) + ]; + + const totalFiatValue = getTokenFiatAmount( + tokenExchangeRate, + conversionRate, + currentCurrency, + token.string, + token.symbol, + false, + false, + ); + + return totalFiatValue; + }); + // todo make sure this is returning the correct value, compare with tickers + const matchedChainSymbol = + allNetworks[singleChainTokenBalances.chainId].nativeCurrency; + const matchedConversionRate = + currencyRates?.[matchedChainSymbol]?.conversionRate; + const balanceCached = + crossChainCachedBalances?.[singleChainTokenBalances.chainId]?.[ + account?.address + ] ?? 0; + const nativeFiatValue = getValueFromWeiHex({ + value: balanceCached, + toCurrency: currentCurrency, + conversionRate: matchedConversionRate, + numberOfDecimals: 2, + }); + return { + ...singleChainTokenBalances, + tokenFiatBalances, + nativeFiatValue, + }; + }, + ); + + const finalTotal = tokenFiatBalancesCrossChains.reduce( + (accumulator, currentValue) => { + const totalFiatBalance = sumDecimals( + currentValue.nativeFiatValue, + ...currentValue.tokenFiatBalances, + ); + // todo clean this + const totalAsNumber = totalFiatBalance.toNumber + ? totalFiatBalance.toNumber() + : Number(totalFiatBalance); + + return accumulator + totalAsNumber; + }, + 0, + ); + + return { + totalFiatBalance: finalTotal.toString(10), + tokenFiatBalancesCrossChains, + }; +}; diff --git a/ui/hooks/useTokenBalances.ts b/ui/hooks/useTokenBalances.ts index 10686f266b62..3b92c93afcba 100644 --- a/ui/hooks/useTokenBalances.ts +++ b/ui/hooks/useTokenBalances.ts @@ -1,9 +1,8 @@ import { useSelector } from 'react-redux'; import BN from 'bn.js'; import { Token } from '@metamask/assets-controllers'; -import { - getNetworkConfigurationsByChainId, -} from '../selectors'; +import { Hex } from '@metamask/utils'; +import { getNetworkConfigurationsByChainId } from '../selectors'; import { tokenBalancesStartPolling, tokenBalancesStopPollingByPollingToken, @@ -11,9 +10,8 @@ import { import { getTokenBalances, getTokens } from '../ducks/metamask/metamask'; import { hexToDecimal } from '../../shared/modules/conversion.utils'; import useMultiPolling from './useMultiPolling'; -import { Hex } from '@metamask/utils'; -export const useTokenBalances = ({chainIds}: {chainIds?: Hex[]} = {}) => { +export const useTokenBalances = ({ chainIds }: { chainIds?: Hex[] } = {}) => { const tokenBalances = useSelector(getTokenBalances); const networkConfigurations = useSelector(getNetworkConfigurationsByChainId); @@ -41,11 +39,11 @@ export const useTokenTracker = ({ address: Hex; hideZeroBalanceTokens?: boolean; }) => { - const { tokenBalances } = useTokenBalances({ chainIds: [chainId] }); const tokensWithBalances = tokens.reduce((acc, token) => { - const hexBalance = tokenBalances[address]?.[chainId]?.[token.address as Hex] ?? '0x0'; + const hexBalance = + tokenBalances[address]?.[chainId]?.[token.address as Hex] ?? '0x0'; if (hexBalance !== '0x0' || !hideZeroBalanceTokens) { const decimalBalance = hexToDecimal(hexBalance); acc.push({ @@ -53,16 +51,18 @@ export const useTokenTracker = ({ symbol: token.symbol, decimals: token.decimals, balance: decimalBalance, - string: stringifyBalance(new BN(decimalBalance), new BN(token.decimals)), + string: stringifyBalance( + new BN(decimalBalance), + new BN(token.decimals), + ), }); } return acc; - }, [] as (Token & { balance: string, string: string })[]) + }, [] as (Token & { balance: string; string: string })[]); return { - tokensWithBalances - } - + tokensWithBalances, + }; }; // From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 8b44dd715aba..f849efa8b4ec 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -449,6 +449,29 @@ export function getMetaMaskCachedBalances(state) { return {}; } +export function getCrossChainMetaMaskCachedBalances(state) { + const allAccountsByChainId = state.metamask.accountsByChainId; + /* return Object.entries(state.metamask.accountsByChainId).reduce( + (accumulator, [key, value]) => { + accumulator[key] = value.balance; + return accumulator; + }, + {}, + ); */ + + return Object.keys(allAccountsByChainId).reduce((acc, topLevelKey) => { + acc[topLevelKey] = Object.keys(allAccountsByChainId[topLevelKey]).reduce( + (innerAcc, innerKey) => { + innerAcc[innerKey] = + allAccountsByChainId[topLevelKey][innerKey].balance; + return innerAcc; + }, + {}, + ); + + return acc; + }, {}); +} /** * @typedef {import('./selectors.types').InternalAccountWithBalance} InternalAccountWithBalance */ @@ -568,7 +591,6 @@ export function getTargetAccount(state, targetAddress) { export const getTokenExchangeRates = (state) => { const chainId = getCurrentChainId(state); const contractMarketData = state.metamask.marketData?.[chainId] ?? {}; - return Object.entries(contractMarketData).reduce( (acc, [address, marketData]) => { acc[address] = marketData?.price ?? null; @@ -578,6 +600,30 @@ export const getTokenExchangeRates = (state) => { ); }; +export const getCrossChainTokenExchangeRates = (state) => { + const contractMarketData = state.metamask.marketData ?? {}; + + return Object.keys(contractMarketData).reduce((acc, topLevelKey) => { + acc[topLevelKey] = Object.keys(contractMarketData[topLevelKey]).reduce( + (innerAcc, innerKey) => { + innerAcc[innerKey] = contractMarketData[topLevelKey][innerKey].price; + return innerAcc; + }, + {}, + ); + + return acc; + }, {}); + + /* return Object.entries(contractMarketData).reduce( + (acc, [address, marketData]) => { + acc[address] = marketData?.price ?? null; + return acc; + }, + {}, + ); */ +}; + /** * Get market data for tokens on the current chain * From 3d19aaaf97f732e6b03e3ce13537533b6719dc6b Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 15 Nov 2024 11:03:08 +0100 Subject: [PATCH 34/73] fix: fix network change error --- ...-percentage-overview-cross-chains.test.tsx | 9 +-- ...gated-percentage-overview-cross-chains.tsx | 34 ++--------- .../app/wallet-overview/coin-overview.tsx | 33 +++------- .../useAccountTotalCrossChainFiatBalance.js | 4 +- ui/hooks/useGetFormattedTokensPerChain.js | 60 +++++++++++++++++++ ui/hooks/useTokenBalances.ts | 7 ++- 6 files changed, 86 insertions(+), 61 deletions(-) create mode 100644 ui/hooks/useGetFormattedTokensPerChain.js diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx index 512aa42e866d..735c7928e02e 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx @@ -18,11 +18,12 @@ import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage jest.mock('react-redux', () => ({ useSelector: jest.fn((selector) => selector()), })); -const mockUseTokenTracker = jest.fn().mockReturnValue({ - tokensWithBalances: {}, + +const mockUseGetFormattedTokensPerChain = jest.fn().mockReturnValue({ + formattedTokensWithBalancesPerChain: {}, }); -jest.mock('../../../hooks/useTokenBalances', () => ({ - useTokenTracker: () => mockUseTokenTracker(), +jest.mock('../../../hooks/useGetFormattedTokensPerChain', () => ({ + useGetFormattedTokensPerChain: () => mockUseGetFormattedTokensPerChain(), })); jest.mock('../../../ducks/locale/locale', () => ({ diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx index cc8ba35ab837..5ed68f9f03e5 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx @@ -8,8 +8,6 @@ import { getShouldHideZeroBalanceTokens, getPreferences, getMarketData, - getNetworkConfigurationsByChainId, - getAllTokens, } from '../../../selectors'; // TODO: Remove restricted import @@ -24,8 +22,7 @@ import { import { Box, SensitiveText } from '../../component-library'; import { getCalculatedTokenAmount1dAgo } from '../../../helpers/utils/util'; import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; -import { TEST_CHAINS } from '../../../../shared/constants/network'; -import { useTokenTracker } from '../../../hooks/useTokenBalances'; +import { useGetFormattedTokensPerChain } from '../../../hooks/useGetFormattedTokensPerChain'; export const AggregatedPercentageOverviewCrossChains = () => { const locale = useSelector(getIntlLocale); @@ -37,35 +34,16 @@ export const AggregatedPercentageOverviewCrossChains = () => { ); const crossChainMarketData = useSelector(getMarketData); - const allNetworks = useSelector(getNetworkConfigurationsByChainId); - const allChainIDs = Object.entries(allNetworks) - .map(([chainIdElm, _]) => { - return chainIdElm; - }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId as any)); - - const detectedTokens = useSelector(getAllTokens); - const dataTokensWithBalancesCrossChain = allChainIDs.map((singleChain) => { - const tokens = - detectedTokens?.[singleChain]?.[selectedAccount?.address] ?? []; - const { tokensWithBalances } = useTokenTracker({ - chainId: singleChain as `0x${string}`, - tokens, - address: selectedAccount.address, - hideZeroBalanceTokens: shouldHideZeroBalanceTokens, - }); - return { - chainId: singleChain, - tokensWithBalances, - }; - }); + const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( + selectedAccount, + shouldHideZeroBalanceTokens, + ); const { totalFiatBalance: totalFiatCrossChains, tokenFiatBalancesCrossChains, } = useAccountTotalCrossChainFiatBalance( selectedAccount, - dataTokensWithBalancesCrossChain, + formattedTokensWithBalancesPerChain, ); const getPerChainTotalFiat1dAgo = ( diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 3536ebad8614..eec35630fe5c 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -55,8 +55,6 @@ import { getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, - getAllTokens, - getNetworkConfigurationsByChainId, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; @@ -71,8 +69,8 @@ import { useTheme } from '../../../hooks/useTheme'; import { getSpecificSettingsRoute } from '../../../helpers/utils/settings-search'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; -import { useTokenTracker } from '../../../hooks/useTokenBalances'; -import { TEST_CHAINS } from '../../../../shared/constants/network'; + +import { useGetFormattedTokensPerChain } from '../../../hooks/useGetFormattedTokensPerChain'; import WalletOverview from './wallet-overview'; import CoinButtons from './coin-buttons'; import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; @@ -142,31 +140,14 @@ export const CoinOverview = ({ const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); - const allNetworks = useSelector(getNetworkConfigurationsByChainId); - const allChainIDs = Object.entries(allNetworks) - .map(([chainIdElm, _]) => { - return chainIdElm; - }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId as any)); - const detectedTokens = useSelector(getAllTokens); - const dataTokensWithBalancesCrossChain = allChainIDs.map((singleChain) => { - const tokens = detectedTokens?.[singleChain]?.[account?.address] ?? []; - const { tokensWithBalances } = useTokenTracker({ - chainId: singleChain as `0x${string}`, - tokens, - address: account.address, - hideZeroBalanceTokens: shouldHideZeroBalanceTokens, - }); - return { - chainId: singleChain, - tokensWithBalances, - }; - }); + const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( + account, + shouldHideZeroBalanceTokens, + ); const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( selectedAccount, - dataTokensWithBalancesCrossChain, + formattedTokensWithBalancesPerChain, ); const { showNativeTokenAsMainBalance } = useSelector(getPreferences); diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.js b/ui/hooks/useAccountTotalCrossChainFiatBalance.js index 2cb63a224c12..911f1586b21c 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.js +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.js @@ -18,7 +18,7 @@ import { getTokenFiatAmount } from '../helpers/utils/token-util'; export const useAccountTotalCrossChainFiatBalance = ( account, - dataTokensWithBalancesCrossChain, + formattedTokensWithBalancesPerChain, ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); @@ -42,7 +42,7 @@ export const useAccountTotalCrossChainFiatBalance = ( ...crossChainContractRates, // todo add confirmation exchange rates? }; - const tokenFiatBalancesCrossChains = dataTokensWithBalancesCrossChain.map( + const tokenFiatBalancesCrossChains = formattedTokensWithBalancesPerChain.map( (singleChainTokenBalances) => { const { tokensWithBalances } = singleChainTokenBalances; const tokenFiatBalances = tokensWithBalances.map((token) => { diff --git a/ui/hooks/useGetFormattedTokensPerChain.js b/ui/hooks/useGetFormattedTokensPerChain.js new file mode 100644 index 000000000000..b7b1f95e3213 --- /dev/null +++ b/ui/hooks/useGetFormattedTokensPerChain.js @@ -0,0 +1,60 @@ +import { useSelector } from 'react-redux'; +import { BN } from 'bn.js'; +import { getNetworkConfigurationsByChainId, getAllTokens } from '../selectors'; +import { hexToDecimal } from '../../shared/modules/conversion.utils'; + +import { TEST_CHAINS } from '../../shared/constants/network'; +import { stringifyBalance, useTokenBalances } from './useTokenBalances'; + +export const useGetFormattedTokensPerChain = ( + account, + shouldHideZeroBalanceTokens, +) => { + const allNetworks = useSelector(getNetworkConfigurationsByChainId); + // We want to filter out test chains + const allChainIDs = Object.entries(allNetworks) + .map(([chainIdElm, _]) => { + return chainIdElm; + }) + .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId)); + + const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported + const currentTokenBalances = useTokenBalances({ chainIds: allChainIDs }); // returns tokens with balances only after clicking on network + + // We will calculate aggregated balance only after the user imports the tokens to the wallet + // we need to format the balances we get from useTokenBalances and match them with symbol and decimals we get from getAllTokens + + const formattedTokensWithBalancesPerChain = allChainIDs.map((singleChain) => { + const tokens = importedTokens?.[singleChain]?.[account?.address] ?? []; + + const tokensWithBalances = tokens.reduce((acc, token) => { + const hexBalance = + currentTokenBalances.tokenBalances[account.address]?.[singleChain]?.[ + token.address + ] ?? '0x0'; + if (hexBalance !== '0x0' || !shouldHideZeroBalanceTokens) { + const decimalBalance = hexToDecimal(hexBalance); + acc.push({ + address: token.address, + symbol: token.symbol, + decimals: token.decimals, + balance: decimalBalance, + string: stringifyBalance( + new BN(decimalBalance), + new BN(token.decimals), + ), + }); + } + return acc; + }, []); + + return { + chainId: singleChain, + tokensWithBalances, + }; + }); + + return { + formattedTokensWithBalancesPerChain, + }; +}; diff --git a/ui/hooks/useTokenBalances.ts b/ui/hooks/useTokenBalances.ts index 3b92c93afcba..b9e7c9a7018f 100644 --- a/ui/hooks/useTokenBalances.ts +++ b/ui/hooks/useTokenBalances.ts @@ -67,7 +67,11 @@ export const useTokenTracker = ({ // From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js // Ensures backwards compatibility with display formatting. -function stringifyBalance(balance: BN, bnDecimals: BN, balanceDecimals = 3) { +export function stringifyBalance( + balance: BN, + bnDecimals: BN, + balanceDecimals = 3, +) { if (balance.eq(new BN(0))) { return '0'; } @@ -105,5 +109,6 @@ function stringifyBalance(balance: BN, bnDecimals: BN, balanceDecimals = 3) { } return `${whole}${withOnlySigZeroes}`; } + return `${whole}.${fractional}`; } From e6e60fdda6aa43ad2ee9665af72a10c75f5abb42 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 15 Nov 2024 11:49:28 +0100 Subject: [PATCH 35/73] fix: fix conversion rate --- .../useAccountTotalCrossChainFiatBalance.js | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.js b/ui/hooks/useAccountTotalCrossChainFiatBalance.js index 911f1586b21c..3c1c78b8188d 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.js +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.js @@ -10,10 +10,7 @@ import { getValueFromWeiHex, sumDecimals, } from '../../shared/modules/conversion.utils'; -import { - getConversionRate, - getCurrencyRates, -} from '../ducks/metamask/metamask'; +import { getCurrencyRates } from '../ducks/metamask/metamask'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; export const useAccountTotalCrossChainFiatBalance = ( @@ -21,10 +18,7 @@ export const useAccountTotalCrossChainFiatBalance = ( formattedTokensWithBalancesPerChain, ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); - const currencyRates = useSelector(getCurrencyRates); - - const conversionRate = useSelector(getConversionRate); const currentCurrency = useSelector(getCurrentCurrency); const crossChainContractRates = useSelector( @@ -45,12 +39,15 @@ export const useAccountTotalCrossChainFiatBalance = ( const tokenFiatBalancesCrossChains = formattedTokensWithBalancesPerChain.map( (singleChainTokenBalances) => { const { tokensWithBalances } = singleChainTokenBalances; + const matchedChainSymbol = + allNetworks[singleChainTokenBalances.chainId].nativeCurrency; + const conversionRate = + currencyRates?.[matchedChainSymbol]?.conversionRate; const tokenFiatBalances = tokensWithBalances.map((token) => { const tokenExchangeRate = mergedCrossChainRates[singleChainTokenBalances.chainId][ toChecksumAddress(token.address) ]; - const totalFiatValue = getTokenFiatAmount( tokenExchangeRate, conversionRate, @@ -63,11 +60,7 @@ export const useAccountTotalCrossChainFiatBalance = ( return totalFiatValue; }); - // todo make sure this is returning the correct value, compare with tickers - const matchedChainSymbol = - allNetworks[singleChainTokenBalances.chainId].nativeCurrency; - const matchedConversionRate = - currencyRates?.[matchedChainSymbol]?.conversionRate; + const balanceCached = crossChainCachedBalances?.[singleChainTokenBalances.chainId]?.[ account?.address @@ -75,7 +68,7 @@ export const useAccountTotalCrossChainFiatBalance = ( const nativeFiatValue = getValueFromWeiHex({ value: balanceCached, toCurrency: currentCurrency, - conversionRate: matchedConversionRate, + conversionRate, numberOfDecimals: 2, }); return { From e1ea312373696e2becf84dada18ab1425e2fe3a8 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 15 Nov 2024 11:53:53 +0100 Subject: [PATCH 36/73] fix: refactor --- ui/hooks/useGetFormattedTokensPerChain.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ui/hooks/useGetFormattedTokensPerChain.js b/ui/hooks/useGetFormattedTokensPerChain.js index b7b1f95e3213..e2a8f5d5b373 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.js +++ b/ui/hooks/useGetFormattedTokensPerChain.js @@ -12,11 +12,9 @@ export const useGetFormattedTokensPerChain = ( ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); // We want to filter out test chains - const allChainIDs = Object.entries(allNetworks) - .map(([chainIdElm, _]) => { - return chainIdElm; - }) - .filter((singleChainId) => !TEST_CHAINS.includes(singleChainId)); + const allChainIDs = Object.keys(allNetworks).filter( + (singleChainId) => !TEST_CHAINS.includes(singleChainId), + ); const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported const currentTokenBalances = useTokenBalances({ chainIds: allChainIDs }); // returns tokens with balances only after clicking on network From 14eb579fdf9aead0001edfebd761a4a1aa401405 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Fri, 15 Nov 2024 14:40:47 +0100 Subject: [PATCH 37/73] fix: hook account list item with agg balance cross chains --- .../account-list-item/account-list-item.js | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index 9e070b33954b..0672ad9bac78 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -47,15 +47,15 @@ import { import { MetaMetricsContext } from '../../../contexts/metametrics'; import { isAccountConnectedToCurrentTab, - getShowFiatInTestnets, getUseBlockie, + getPreferences, + getShouldHideZeroBalanceTokens, } from '../../../selectors'; import { getMultichainIsTestnet, getMultichainNativeCurrency, getMultichainNativeCurrencyImage, getMultichainNetwork, - getMultichainShouldShowFiat, } from '../../../selectors/multichain'; import { useMultichainAccountTotalFiatBalance } from '../../../hooks/useMultichainAccountTotalFiatBalance'; import { ConnectedStatus } from '../connected-status/connected-status'; @@ -67,6 +67,8 @@ import { useTheme } from '../../../hooks/useTheme'; // eslint-disable-next-line import/no-restricted-paths import { normalizeSafeAddress } from '../../../../app/scripts/lib/multichain/address'; import { useMultichainSelector } from '../../../hooks/useMultichainSelector'; +import { useGetFormattedTokensPerChain } from '../../../hooks/useGetFormattedTokensPerChain'; +import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; import { AccountListItemMenuTypes } from './account-list-item.types'; const MAXIMUM_CURRENCY_DECIMALS = 3; @@ -99,24 +101,36 @@ const AccountListItem = ({ setAccountListItemMenuElement(ref); }; const isTestnet = useMultichainSelector(getMultichainIsTestnet, account); - const isMainnet = !isTestnet; - const shouldShowFiat = useMultichainSelector( - getMultichainShouldShowFiat, - account, - ); - const showFiatInTestnets = useSelector(getShowFiatInTestnets); - const showFiat = - shouldShowFiat && (isMainnet || (isTestnet && showFiatInTestnets)); const accountTotalFiatBalances = useMultichainAccountTotalFiatBalance(account); + // cross chain agg balance + const { showNativeTokenAsMainBalance } = useSelector(getPreferences); + const shouldHideZeroBalanceTokens = useSelector( + getShouldHideZeroBalanceTokens, + ); + const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( + account, + shouldHideZeroBalanceTokens, + ); + const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( + account, + formattedTokensWithBalancesPerChain, + ); + // cross chain agg balance const mappedOrderedTokenList = accountTotalFiatBalances.orderedTokenList.map( (item) => ({ avatarValue: item.iconUrl, }), ); - const balanceToTranslate = isEvmNetwork - ? account.balance - : accountTotalFiatBalances.totalBalance; + let balanceToTranslate; + if (isEvmNetwork) { + balanceToTranslate = + showNativeTokenAsMainBalance || isTestnet // balance in crypto + ? account.balance + : totalFiatBalance; + } else { + balanceToTranslate = accountTotalFiatBalances.totalBalance; + } ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) const custodianIcon = useSelector((state) => @@ -311,7 +325,12 @@ const AccountListItem = ({ ethNumberOfDecimals={MAXIMUM_CURRENCY_DECIMALS} value={balanceToTranslate} type={PRIMARY} - showFiat={showFiat} + // showFiat={showFiat} + showFiat={!isEvmNetwork} + shouldCheckShowNativeToken + isAggregatedFiatOverviewBalance={ + !showNativeTokenAsMainBalance && !isTestnet + } data-testid="first-currency-display" /> From 25e5a2b1ac0bda714db073665998a8f4ace3822c Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 10:30:38 +0100 Subject: [PATCH 38/73] fix: merge conflicts --- 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 a175ee51be97..cc7eaa12d3d1 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -6718,7 +6718,6 @@ export default class MetamaskController extends EventEmitter { this.tokenListController.stopAllPolling(); this.tokenBalancesController.stopAllPolling(); this.appStateController.clearPollingTokens(); - this.tokenBalancesController.stopAllPolling(); } catch (error) { console.error(error); } From 355f908aee1d4607fea5186a51c5145db816ea96 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 10:33:14 +0100 Subject: [PATCH 39/73] fix: merge conflicts --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 09bb90863a00..04098328933f 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,6 @@ "attributions:generate": "./development/generate-attributions.sh" }, "resolutions": { - "@metamask/assets-controllers": "patch:@metamask/assets-controllers@patch%3A@metamask/assets-controllers@npm%253A44.0.0%23~/.yarn/patches/@metamask-assets-controllers-npm-44.0.0-c223d56176.patch%3A%3Aversion=44.0.0&hash=5a94c2#~/.yarn/patches/@metamask-assets-controllers-patch-9e00573eb4.patch", "chokidar": "^3.6.0", "gridplus-sdk/elliptic": "^6.5.7", "gridplus-sdk/secp256k1": "^5.0.1", From b218da982a565990a05cd314f582ab216a8ad590 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 10:39:26 +0100 Subject: [PATCH 40/73] fix: rm comments --- ui/selectors/selectors.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index f80516a27a25..49584c7fc989 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -451,14 +451,6 @@ export function getMetaMaskCachedBalances(state) { export function getCrossChainMetaMaskCachedBalances(state) { const allAccountsByChainId = state.metamask.accountsByChainId; - /* return Object.entries(state.metamask.accountsByChainId).reduce( - (accumulator, [key, value]) => { - accumulator[key] = value.balance; - return accumulator; - }, - {}, - ); */ - return Object.keys(allAccountsByChainId).reduce((acc, topLevelKey) => { acc[topLevelKey] = Object.keys(allAccountsByChainId[topLevelKey]).reduce( (innerAcc, innerKey) => { @@ -614,14 +606,6 @@ export const getCrossChainTokenExchangeRates = (state) => { return acc; }, {}); - - /* return Object.entries(contractMarketData).reduce( - (acc, [address, marketData]) => { - acc[address] = marketData?.price ?? null; - return acc; - }, - {}, - ); */ }; /** From 068ca670159c7dcdf6e63a4d6ff622a644a53f43 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 14:42:05 +0100 Subject: [PATCH 41/73] fix: fix cross chain agg balance with network filter --- ...-percentage-overview-cross-chains.test.tsx | 1 - ...gated-percentage-overview-cross-chains.tsx | 20 ++++- .../app/wallet-overview/coin-overview.tsx | 15 +++- ui/hooks/useGetFormattedTokensPerChain.js | 75 +++++++++++-------- ui/selectors/selectors.js | 12 +++ 5 files changed, 85 insertions(+), 38 deletions(-) diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx index 735c7928e02e..06f3b9a4bec1 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx @@ -12,7 +12,6 @@ import { getAllTokens, } from '../../../selectors'; import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; -import { AggregatedPercentageOverview } from './aggregated-percentage-overview'; import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; jest.mock('react-redux', () => ({ diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx index 5ed68f9f03e5..a35cd7ae4790 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx @@ -48,11 +48,11 @@ export const AggregatedPercentageOverviewCrossChains = () => { const getPerChainTotalFiat1dAgo = ( chainId: string, - tokenFiatBalances: { [x: string]: any }, - tokensWithBalances: any[], + tokenFiatBalances: string[], + tokensWithBalances: { string: string; balance: string; address: string }[], ) => { const totalPerChain1dAgoERC20 = tokensWithBalances.reduce( - (total1dAgo: number, item: { address: string }, idx: string | number) => { + (total1dAgo: number, item: { address: string }, idx: number) => { const found = crossChainMarketData?.[chainId]?.[toChecksumAddress(item.address)]; @@ -70,7 +70,19 @@ export const AggregatedPercentageOverviewCrossChains = () => { const totalFiat1dAgoCrossChains = useMemo(() => { return tokenFiatBalancesCrossChains.reduce( - (total1dAgoCrossChains: any, item: any) => { + ( + total1dAgoCrossChains: number, + item: { + chainId: string; + nativeFiatValue: string; + tokenFiatBalances: string[]; + tokensWithBalances: { + string: string; + balance: string; + address: string; + }[]; + }, + ) => { const perChainERC20Total = getPerChainTotalFiat1dAgo( item.chainId, item.tokenFiatBalances, diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 0fe87b4e0be5..cc02b395daf3 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -55,6 +55,7 @@ import { getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, + getIsTokenNetworkFilterEqualCurrentNetwork, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; @@ -73,6 +74,7 @@ import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountT import { useGetFormattedTokensPerChain } from '../../../hooks/useGetFormattedTokensPerChain'; import WalletOverview from './wallet-overview'; import CoinButtons from './coin-buttons'; +import { AggregatedPercentageOverview } from './aggregated-percentage-overview'; import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; export type CoinOverviewProps = { @@ -138,10 +140,13 @@ export const CoinOverview = ({ const { showFiatInTestnets, privacyMode, showNativeTokenAsMainBalance } = useSelector(getPreferences); + const isTokenNetworkFilterEqualCurrentNetwork = useSelector( + getIsTokenNetworkFilterEqualCurrentNetwork, + ); + const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); - const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( account, shouldHideZeroBalanceTokens, @@ -232,8 +237,12 @@ export const CoinOverview = ({ } return ( - {/* */} - + {isTokenNetworkFilterEqualCurrentNetwork ? ( + + ) : ( + + )} + { ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) { const allNetworks = useSelector(getNetworkConfigurationsByChainId); + const currentChainId = useSelector(getCurrentChainId); // We want to filter out test chains const allChainIDs = Object.keys(allNetworks).filter( (singleChainId) => !TEST_CHAINS.includes(singleChainId), ); + const isTokenNetworkFilterEqualCurrentNetwork = useSelector( + getIsTokenNetworkFilterEqualCurrentNetwork, + ); const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported - const currentTokenBalances = useTokenBalances({ chainIds: allChainIDs }); // returns tokens with balances only after clicking on network + const currentTokenBalances = useTokenBalances({ + chainIds: allChainIDs, + }); // We will calculate aggregated balance only after the user imports the tokens to the wallet // we need to format the balances we get from useTokenBalances and match them with symbol and decimals we get from getAllTokens + const networksToFormat = isTokenNetworkFilterEqualCurrentNetwork + ? [currentChainId] + : allChainIDs; + const formattedTokensWithBalancesPerChain = networksToFormat.map( + (singleChain) => { + const tokens = importedTokens?.[singleChain]?.[account?.address] ?? []; - const formattedTokensWithBalancesPerChain = allChainIDs.map((singleChain) => { - const tokens = importedTokens?.[singleChain]?.[account?.address] ?? []; - - const tokensWithBalances = tokens.reduce((acc, token) => { - const hexBalance = - currentTokenBalances.tokenBalances[account.address]?.[singleChain]?.[ - token.address - ] ?? '0x0'; - if (hexBalance !== '0x0' || !shouldHideZeroBalanceTokens) { - const decimalBalance = hexToDecimal(hexBalance); - acc.push({ - address: token.address, - symbol: token.symbol, - decimals: token.decimals, - balance: decimalBalance, - string: stringifyBalance( - new BN(decimalBalance), - new BN(token.decimals), - ), - }); - } - return acc; - }, []); + const tokensWithBalances = tokens.reduce((acc, token) => { + const hexBalance = + currentTokenBalances.tokenBalances[account.address]?.[singleChain]?.[ + token.address + ] ?? '0x0'; + if (hexBalance !== '0x0' || !shouldHideZeroBalanceTokens) { + const decimalBalance = hexToDecimal(hexBalance); + acc.push({ + address: token.address, + symbol: token.symbol, + decimals: token.decimals, + balance: decimalBalance, + string: stringifyBalance( + new BN(decimalBalance), + new BN(token.decimals), + ), + }); + } + return acc; + }, []); - return { - chainId: singleChain, - tokensWithBalances, - }; - }); + return { + chainId: singleChain, + tokensWithBalances, + }; + }, + ); return { formattedTokensWithBalancesPerChain, diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 49584c7fc989..8a945054fe19 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -984,6 +984,18 @@ export function getPetnamesEnabled(state) { return petnamesEnabled; } +export function getIsTokenNetworkFilterEqualCurrentNetwork(state) { + const chainId = getCurrentChainId(state); + const { tokenNetworkFilter } = getPreferences(state); + if ( + Object.keys(tokenNetworkFilter)?.length === 1 && + Object.keys(tokenNetworkFilter)[0] === chainId + ) { + return true; + } + return false; +} + export function getUseTransactionSimulations(state) { return Boolean(state.metamask.useTransactionSimulations); } From a0d0791c60234a2a938193d6008a330a4743b7d4 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 15:03:43 +0100 Subject: [PATCH 42/73] fix: fix unit test --- test/data/mock-state.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test/data/mock-state.json b/test/data/mock-state.json index 80e5499447d7..2932e5fc56d9 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -379,6 +379,7 @@ "showNativeTokenAsMainBalance": true, "showTestNetworks": true, "smartTransactionsOptInStatus": true, + "tokenNetworkFilter": {}, "tokenSortConfig": { "key": "tokenFiatAmount", "order": "dsc", From 96acc46e9bfcee07859c3e744d0288ad5d28fd4d Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 15:15:23 +0100 Subject: [PATCH 43/73] fix: fix unit test --- ui/components/multichain/pages/send/send.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/components/multichain/pages/send/send.test.js b/ui/components/multichain/pages/send/send.test.js index 5195ee15de5b..bc8db6adf3b6 100644 --- a/ui/components/multichain/pages/send/send.test.js +++ b/ui/components/multichain/pages/send/send.test.js @@ -89,6 +89,7 @@ const baseStore = { }, }, metamask: { + accountsByChainId: {}, permissionHistory: {}, transactions: [ { @@ -168,6 +169,7 @@ const baseStore = { tokens: [], preferences: { showFiatInTestnets: true, + tokenNetworkFilter: {}, }, currentCurrency: 'USD', nativeCurrency: 'ETH', From c0ce3ca5453021c4cfa8e4611ba7c5e184d7be91 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 15:26:20 +0100 Subject: [PATCH 44/73] fix: fix unit test --- ui/pages/routes/routes.component.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/pages/routes/routes.component.test.js b/ui/pages/routes/routes.component.test.js index 8a516fd76d6a..6c08c9130761 100644 --- a/ui/pages/routes/routes.component.test.js +++ b/ui/pages/routes/routes.component.test.js @@ -112,6 +112,7 @@ describe('Routes Component', () => { ...mockSendState.metamask.swapsState, swapsFeatureIsLive: true, }, + accountsByChainId: {}, pendingApprovals: {}, approvalFlows: [], announcements: {}, @@ -123,6 +124,7 @@ describe('Routes Component', () => { order: 'dsc', sortCallback: 'stringNumeric', }, + tokenNetworkFilter: {}, }, }, send: { From 7ae5b8fbe2d67252fc6bf973af3ac51e90811321 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 15:53:34 +0100 Subject: [PATCH 45/73] fix: fix unit test --- ui/components/app/wallet-overview/btc-overview.test.tsx | 1 + ui/components/app/wallet-overview/eth-overview.test.js | 1 + 2 files changed, 2 insertions(+) diff --git a/ui/components/app/wallet-overview/btc-overview.test.tsx b/ui/components/app/wallet-overview/btc-overview.test.tsx index 671e03a87ea8..93c9e09ff0fd 100644 --- a/ui/components/app/wallet-overview/btc-overview.test.tsx +++ b/ui/components/app/wallet-overview/btc-overview.test.tsx @@ -150,6 +150,7 @@ describe('BtcOverview', () => { // The balances won't be available preferences: { showNativeTokenAsMainBalance: false, + tokenNetworkFilter: {}, }, }, }), diff --git a/ui/components/app/wallet-overview/eth-overview.test.js b/ui/components/app/wallet-overview/eth-overview.test.js index a8c490b923c6..40c0b818649c 100644 --- a/ui/components/app/wallet-overview/eth-overview.test.js +++ b/ui/components/app/wallet-overview/eth-overview.test.js @@ -94,6 +94,7 @@ describe('EthOverview', () => { }, preferences: { showNativeTokenAsMainBalance: true, + tokenNetworkFilter: {}, }, useExternalServices: true, useCurrencyRateCheck: true, From 234cf092f5c244d50bef67b368823f60f355bb4d Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 15:59:10 +0100 Subject: [PATCH 46/73] fix: unit test --- .../account-list-item.test.js | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/ui/components/multichain/account-list-item/account-list-item.test.js b/ui/components/multichain/account-list-item/account-list-item.test.js index 09febefb3d83..9422b9205481 100644 --- a/ui/components/multichain/account-list-item/account-list-item.test.js +++ b/ui/components/multichain/account-list-item/account-list-item.test.js @@ -237,7 +237,7 @@ describe('AccountListItem', () => { expect(avatarGroup).not.toBeInTheDocument(); }); - it('renders fiat for EVM account', () => { + it('renders fiat for EVM account when showNativeTokenAsMainBalance is false', () => { const { container } = render( { account: mockAccount, @@ -251,6 +251,7 @@ describe('AccountListItem', () => { }), preferences: { showFiatInTestnets: true, + showNativeTokenAsMainBalance: false, }, }, }, @@ -277,6 +278,47 @@ describe('AccountListItem', () => { expect(avatarGroup).not.toBeInTheDocument(); }); + it('renders token for EVM account when showNativeTokenAsMainBalance is true', () => { + const { container } = render( + { + account: mockAccount, + }, + { + metamask: { + ...mockNetworkState({ + chainId: CHAIN_IDS.SEPOLIA, + nickname: SEPOLIA_DISPLAY_NAME, + ticker: 'ETH', + }), + preferences: { + showFiatInTestnets: true, + showNativeTokenAsMainBalance: true, + }, + }, + }, + ); + + const firstCurrencyDisplay = container.querySelector( + '[data-testid="first-currency-display"]', + ); + const secondCurrencyDisplay = container.querySelector( + '[data-testid="second-currency-display"]', + ); + const avatarGroup = container.querySelector( + '[data-testid="avatar-group"]', + ); + + const expectedBalance = '0.006'; + + expect(firstCurrencyDisplay).toBeInTheDocument(); + expect(firstCurrencyDisplay.firstChild.textContent).toContain( + expectedBalance, + ); + expect(firstCurrencyDisplay.lastChild.textContent).toContain('ETH'); + expect(secondCurrencyDisplay.textContent).toContain(''); + expect(avatarGroup).not.toBeInTheDocument(); + }); + it('renders fiat for non-EVM account', () => { const { container } = render( { From ab32cedcb850aba984aff12f591be60082c13c88 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 16:13:36 +0100 Subject: [PATCH 47/73] fix: fix unit test --- test/data/mock-send-state.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/data/mock-send-state.json b/test/data/mock-send-state.json index 96cd95cfbd84..73468aca6171 100644 --- a/test/data/mock-send-state.json +++ b/test/data/mock-send-state.json @@ -63,6 +63,7 @@ "currentLocale": "en" }, "metamask": { + "accountsByChainId": {}, "ipfsGateway": "", "dismissSeedBackUpReminder": false, "usePhishDetect": true, @@ -131,7 +132,8 @@ "preferences": { "hideZeroBalanceTokens": false, "showFiatInTestnets": false, - "showTestNetworks": true + "showTestNetworks": true, + "tokenNetworkFilter": {} }, "seedPhraseBackedUp": null, "ensResolutionsByAddress": {}, From e01f04bc2690a6f8be846c45e79e1878bd4d5545 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 16:25:47 +0100 Subject: [PATCH 48/73] fix: fix test --- test/integration/data/integration-init-state.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/data/integration-init-state.json b/test/integration/data/integration-init-state.json index a0ae3a8fb146..ed42111c00e1 100644 --- a/test/integration/data/integration-init-state.json +++ b/test/integration/data/integration-init-state.json @@ -784,7 +784,8 @@ "smartTransactionsOptInStatus": true, "petnamesEnabled": false, "showConfirmationAdvancedDetails": false, - "showMultiRpcModal": false + "showMultiRpcModal": false, + "tokenNetworkFilter": {} }, "preventPollingOnNetworkRestart": true, "previousAppVersion": "11.14.4", From df0c3d0e8008f065d9f6b1e6329e2bb462d73240 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 18:45:32 +0100 Subject: [PATCH 49/73] fix: convert to .ts file --- ...> useAccountTotalCrossChainFiatBalance.ts} | 31 +++++++-- ...in.js => useGetFormattedTokensPerChain.ts} | 69 ++++++++++++------- 2 files changed, 67 insertions(+), 33 deletions(-) rename ui/hooks/{useAccountTotalCrossChainFiatBalance.js => useAccountTotalCrossChainFiatBalance.ts} (78%) rename ui/hooks/{useGetFormattedTokensPerChain.js => useGetFormattedTokensPerChain.ts} (52%) diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.js b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts similarity index 78% rename from ui/hooks/useAccountTotalCrossChainFiatBalance.js rename to ui/hooks/useAccountTotalCrossChainFiatBalance.ts index 3c1c78b8188d..01a3abc58dcd 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.js +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -12,10 +12,23 @@ import { } from '../../shared/modules/conversion.utils'; import { getCurrencyRates } from '../ducks/metamask/metamask'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; +import { TokenWithBalance } from '../components/app/assets/asset-list/asset-list'; +import { number } from 'yargs'; + +type AddressBalances = { + [address: string]: number; +}; + +export type Balances = { + [id: string]: AddressBalances; +}; export const useAccountTotalCrossChainFiatBalance = ( - account, - formattedTokensWithBalancesPerChain, + account: { address: string }, + formattedTokensWithBalancesPerChain: { + chainId: string; + tokensWithBalances: TokenWithBalance[]; + }[], ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); const currencyRates = useSelector(getCurrencyRates); @@ -26,13 +39,13 @@ export const useAccountTotalCrossChainFiatBalance = ( shallowEqual, ); - const crossChainCachedBalances = useSelector( + const crossChainCachedBalances: Balances = useSelector( getCrossChainMetaMaskCachedBalances, ); // const loading = false; //todo check if loading is still needed - const mergedCrossChainRates = { + const mergedCrossChainRates: Balances = { ...crossChainContractRates, // todo add confirmation exchange rates? }; @@ -40,7 +53,8 @@ export const useAccountTotalCrossChainFiatBalance = ( (singleChainTokenBalances) => { const { tokensWithBalances } = singleChainTokenBalances; const matchedChainSymbol = - allNetworks[singleChainTokenBalances.chainId].nativeCurrency; + allNetworks[singleChainTokenBalances.chainId as `0x${string}`] + .nativeCurrency; const conversionRate = currencyRates?.[matchedChainSymbol]?.conversionRate; const tokenFiatBalances = tokensWithBalances.map((token) => { @@ -81,11 +95,14 @@ export const useAccountTotalCrossChainFiatBalance = ( const finalTotal = tokenFiatBalancesCrossChains.reduce( (accumulator, currentValue) => { + const tmpCurrentValueFiatBalances = currentValue.tokenFiatBalances.filter( + (value) => value !== undefined, + ); const totalFiatBalance = sumDecimals( currentValue.nativeFiatValue, - ...currentValue.tokenFiatBalances, + ...tmpCurrentValueFiatBalances, ); - // todo clean this + const totalAsNumber = totalFiatBalance.toNumber ? totalFiatBalance.toNumber() : Number(totalFiatBalance); diff --git a/ui/hooks/useGetFormattedTokensPerChain.js b/ui/hooks/useGetFormattedTokensPerChain.ts similarity index 52% rename from ui/hooks/useGetFormattedTokensPerChain.js rename to ui/hooks/useGetFormattedTokensPerChain.ts index 568bc169c240..5b03a3605645 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.js +++ b/ui/hooks/useGetFormattedTokensPerChain.ts @@ -10,25 +10,39 @@ import { hexToDecimal } from '../../shared/modules/conversion.utils'; import { TEST_CHAINS } from '../../shared/constants/network'; import { stringifyBalance, useTokenBalances } from './useTokenBalances'; +import { TokenWithBalance } from '../components/multichain/asset-picker-amount/asset-picker-modal/types'; +import { Token } from '@metamask/assets-controllers'; + +type AddressMapping = { + [chainId: string]: { + [tokenAddress: string]: string; + }; +}; + +type TokenBalancesMapping = { + [address: string]: AddressMapping; +}; export const useGetFormattedTokensPerChain = ( - account, - shouldHideZeroBalanceTokens, + account: { address: string }, + shouldHideZeroBalanceTokens: boolean, ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); const currentChainId = useSelector(getCurrentChainId); // We want to filter out test chains const allChainIDs = Object.keys(allNetworks).filter( - (singleChainId) => !TEST_CHAINS.includes(singleChainId), + (singleChainId) => + !TEST_CHAINS.includes(singleChainId as (typeof TEST_CHAINS)[number]), ); const isTokenNetworkFilterEqualCurrentNetwork = useSelector( getIsTokenNetworkFilterEqualCurrentNetwork, ); const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported - const currentTokenBalances = useTokenBalances({ - chainIds: allChainIDs, - }); + const currentTokenBalances: { tokenBalances: TokenBalancesMapping } = + useTokenBalances({ + chainIds: allChainIDs as `0x${string}`[], + }); // We will calculate aggregated balance only after the user imports the tokens to the wallet // we need to format the balances we get from useTokenBalances and match them with symbol and decimals we get from getAllTokens @@ -39,26 +53,29 @@ export const useGetFormattedTokensPerChain = ( (singleChain) => { const tokens = importedTokens?.[singleChain]?.[account?.address] ?? []; - const tokensWithBalances = tokens.reduce((acc, token) => { - const hexBalance = - currentTokenBalances.tokenBalances[account.address]?.[singleChain]?.[ - token.address - ] ?? '0x0'; - if (hexBalance !== '0x0' || !shouldHideZeroBalanceTokens) { - const decimalBalance = hexToDecimal(hexBalance); - acc.push({ - address: token.address, - symbol: token.symbol, - decimals: token.decimals, - balance: decimalBalance, - string: stringifyBalance( - new BN(decimalBalance), - new BN(token.decimals), - ), - }); - } - return acc; - }, []); + const tokensWithBalances = tokens.reduce( + (acc: TokenWithBalance[], token: Token) => { + const hexBalance = + currentTokenBalances.tokenBalances[account.address]?.[ + singleChain + ]?.[token.address] ?? '0x0'; + if (hexBalance !== '0x0' || !shouldHideZeroBalanceTokens) { + const decimalBalance = hexToDecimal(hexBalance); + acc.push({ + address: token.address, + symbol: token.symbol, + decimals: token.decimals, + balance: decimalBalance, + string: stringifyBalance( + new BN(decimalBalance), + new BN(token.decimals), + ), + }); + } + return acc; + }, + [], + ); return { chainId: singleChain, From 1e8062dfef0c4d90682d23ad529e086c9eb9aa7e Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 19:03:13 +0100 Subject: [PATCH 50/73] fix: lint --- ui/hooks/useAccountTotalCrossChainFiatBalance.ts | 1 - ui/hooks/useGetFormattedTokensPerChain.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index 01a3abc58dcd..98f73623cc04 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -13,7 +13,6 @@ import { import { getCurrencyRates } from '../ducks/metamask/metamask'; import { getTokenFiatAmount } from '../helpers/utils/token-util'; import { TokenWithBalance } from '../components/app/assets/asset-list/asset-list'; -import { number } from 'yargs'; type AddressBalances = { [address: string]: number; diff --git a/ui/hooks/useGetFormattedTokensPerChain.ts b/ui/hooks/useGetFormattedTokensPerChain.ts index 5b03a3605645..4e9206def3b0 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.ts +++ b/ui/hooks/useGetFormattedTokensPerChain.ts @@ -1,5 +1,6 @@ import { useSelector } from 'react-redux'; import { BN } from 'bn.js'; +import { Token } from '@metamask/assets-controllers'; import { getNetworkConfigurationsByChainId, getAllTokens, @@ -9,9 +10,8 @@ import { import { hexToDecimal } from '../../shared/modules/conversion.utils'; import { TEST_CHAINS } from '../../shared/constants/network'; -import { stringifyBalance, useTokenBalances } from './useTokenBalances'; import { TokenWithBalance } from '../components/multichain/asset-picker-amount/asset-picker-modal/types'; -import { Token } from '@metamask/assets-controllers'; +import { stringifyBalance, useTokenBalances } from './useTokenBalances'; type AddressMapping = { [chainId: string]: { From 83c7eba293784e14e8e26708d42ba1a3a8cbf06a Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 19:11:18 +0100 Subject: [PATCH 51/73] fix: fix --- ui/selectors/selectors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 8a945054fe19..a57934c00246 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -986,9 +986,9 @@ export function getPetnamesEnabled(state) { export function getIsTokenNetworkFilterEqualCurrentNetwork(state) { const chainId = getCurrentChainId(state); - const { tokenNetworkFilter } = getPreferences(state); + const { tokenNetworkFilter } = getPreferences(state) || {}; if ( - Object.keys(tokenNetworkFilter)?.length === 1 && + Object.keys(tokenNetworkFilter).length === 1 && Object.keys(tokenNetworkFilter)[0] === chainId ) { return true; From 302a7572b0c18a9696dc62eca31ebce9d6625646 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 20:17:39 +0100 Subject: [PATCH 52/73] fix: fix e2e fixtures --- test/e2e/default-fixture.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/default-fixture.js b/test/e2e/default-fixture.js index fd2d5be42891..c2fba9d63424 100644 --- a/test/e2e/default-fixture.js +++ b/test/e2e/default-fixture.js @@ -225,6 +225,7 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) { sortCallback: 'stringNumeric', }, shouldShowAggregatedBalancePopover: true, + tokenNetworkFilter: {}, }, selectedAddress: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', theme: 'light', From 4d7a1acb812baac991a16f0de50d47fc6e6bc376 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 21:26:22 +0100 Subject: [PATCH 53/73] fix: fix e2e --- ui/selectors/selectors.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index a57934c00246..b57f429cd723 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -986,7 +986,8 @@ export function getPetnamesEnabled(state) { export function getIsTokenNetworkFilterEqualCurrentNetwork(state) { const chainId = getCurrentChainId(state); - const { tokenNetworkFilter } = getPreferences(state) || {}; + const { tokenNetworkFilter: tokenNetworkFilterValue } = getPreferences(state); + const tokenNetworkFilter = tokenNetworkFilterValue || {}; if ( Object.keys(tokenNetworkFilter).length === 1 && Object.keys(tokenNetworkFilter)[0] === chainId From 1520ef4339add2d216b5e567beff8f0c756d83f9 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 22:09:00 +0100 Subject: [PATCH 54/73] fix: rm hardcoded value in network filter --- .../network-filter/network-filter.tsx | 44 +++++++++++++++---- ...gated-percentage-overview-cross-chains.tsx | 1 + .../app/wallet-overview/coin-overview.tsx | 2 + .../account-list-item/account-list-item.js | 5 +++ ui/hooks/useGetFormattedTokensPerChain.ts | 8 +--- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx index cc2d0f38210e..b3ac6ea54417 100644 --- a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx +++ b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx @@ -12,7 +12,6 @@ import { } from '../../../../../selectors'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { SelectableListItem } from '../sort-control/sort-control'; -import { useAccountTotalFiatBalance } from '../../../../../hooks/useAccountTotalFiatBalance'; import { Text } from '../../../../component-library/text/text'; import { Display, @@ -24,6 +23,8 @@ import { Box } from '../../../../component-library/box/box'; import { AvatarNetwork } from '../../../../component-library'; import UserPreferencedCurrencyDisplay from '../../../user-preferenced-currency-display'; import { CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP } from '../../../../../../shared/constants/network'; +import { useGetFormattedTokensPerChain } from '../../../../../hooks/useGetFormattedTokensPerChain'; +import { useAccountTotalCrossChainFiatBalance } from '../../../../../hooks/useAccountTotalCrossChainFiatBalance'; type SortControlProps = { handleClose: () => void; @@ -37,14 +38,33 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { const currentNetwork = useSelector(getCurrentNetwork); const allNetworks = useSelector(getNetworkConfigurationsByChainId); const isTestnet = useSelector(getIsTestnet); - const { tokenNetworkFilter, showNativeTokenAsMainBalance } = - useSelector(getPreferences); + const { tokenNetworkFilter } = useSelector(getPreferences); const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); + const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( + selectedAccount, + shouldHideZeroBalanceTokens, + true, + ); const { totalFiatBalance: selectedAccountBalance } = - useAccountTotalFiatBalance(selectedAccount, shouldHideZeroBalanceTokens); + useAccountTotalCrossChainFiatBalance( + selectedAccount, + formattedTokensWithBalancesPerChain, + ); + + const { formattedTokensWithBalancesPerChain: formattedTokensForAllNetworks } = + useGetFormattedTokensPerChain( + selectedAccount, + shouldHideZeroBalanceTokens, + false, + ); + const { totalFiatBalance: selectedAccountBalanceForAllNetworks } = + useAccountTotalCrossChainFiatBalance( + selectedAccount, + formattedTokensForAllNetworks, + ); // TODO: fetch balances across networks // const multiNetworkAccountBalance = useMultichainAccountBalance() @@ -78,7 +98,16 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { color={TextColor.textDefault} > {/* TODO: Should query cross chain account balance */} - $1,000.00 + + @@ -125,10 +154,9 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { type="PRIMARY" ethNumberOfDecimals={4} hideTitle + showFiat shouldCheckShowNativeToken - isAggregatedFiatOverviewBalance={ - !showNativeTokenAsMainBalance && !isTestnet - } + isAggregatedFiatOverviewBalance={!isTestnet} /> { const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( selectedAccount, shouldHideZeroBalanceTokens, + false, ); const { totalFiatBalance: totalFiatCrossChains, diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index cc02b395daf3..211b8f064235 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -147,9 +147,11 @@ export const CoinOverview = ({ const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); + const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( account, shouldHideZeroBalanceTokens, + isTokenNetworkFilterEqualCurrentNetwork, ); const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( account, diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index 93a4bcd301e9..cc0d77157215 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -50,6 +50,7 @@ import { getUseBlockie, getPreferences, getShouldHideZeroBalanceTokens, + getIsTokenNetworkFilterEqualCurrentNetwork, } from '../../../selectors'; import { getMultichainIsTestnet, @@ -109,9 +110,13 @@ const AccountListItem = ({ const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); + const isTokenNetworkFilterEqualCurrentNetwork = useSelector( + getIsTokenNetworkFilterEqualCurrentNetwork, + ); const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( account, shouldHideZeroBalanceTokens, + isTokenNetworkFilterEqualCurrentNetwork, ); const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( account, diff --git a/ui/hooks/useGetFormattedTokensPerChain.ts b/ui/hooks/useGetFormattedTokensPerChain.ts index 4e9206def3b0..b0acaf414f77 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.ts +++ b/ui/hooks/useGetFormattedTokensPerChain.ts @@ -4,7 +4,6 @@ import { Token } from '@metamask/assets-controllers'; import { getNetworkConfigurationsByChainId, getAllTokens, - getIsTokenNetworkFilterEqualCurrentNetwork, getCurrentChainId, } from '../selectors'; import { hexToDecimal } from '../../shared/modules/conversion.utils'; @@ -26,6 +25,7 @@ type TokenBalancesMapping = { export const useGetFormattedTokensPerChain = ( account: { address: string }, shouldHideZeroBalanceTokens: boolean, + shouldGetTokensPerCurrentChain: boolean, ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); const currentChainId = useSelector(getCurrentChainId); @@ -34,10 +34,6 @@ export const useGetFormattedTokensPerChain = ( (singleChainId) => !TEST_CHAINS.includes(singleChainId as (typeof TEST_CHAINS)[number]), ); - const isTokenNetworkFilterEqualCurrentNetwork = useSelector( - getIsTokenNetworkFilterEqualCurrentNetwork, - ); - const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported const currentTokenBalances: { tokenBalances: TokenBalancesMapping } = useTokenBalances({ @@ -46,7 +42,7 @@ export const useGetFormattedTokensPerChain = ( // We will calculate aggregated balance only after the user imports the tokens to the wallet // we need to format the balances we get from useTokenBalances and match them with symbol and decimals we get from getAllTokens - const networksToFormat = isTokenNetworkFilterEqualCurrentNetwork + const networksToFormat = shouldGetTokensPerCurrentChain ? [currentChainId] : allChainIDs; const formattedTokensWithBalancesPerChain = networksToFormat.map( From b212907d5f74678f9f5aa1ba3645b001d0571a4c Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 22:51:09 +0100 Subject: [PATCH 55/73] fix: fix Sentry e2e --- .../errors-after-init-opt-in-background-state.json | 1 + .../state-snapshots/errors-after-init-opt-in-ui-state.json | 2 +- .../errors-before-init-opt-in-background-state.json | 3 ++- .../state-snapshots/errors-before-init-opt-in-ui-state.json | 1 + 4 files changed, 5 insertions(+), 2 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 e47cfcd806b9..9df8707d1f17 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 @@ -237,6 +237,7 @@ "redesignedConfirmationsEnabled": true, "redesignedTransactionsEnabled": "boolean", "tokenSortConfig": "object", + "tokenNetworkFilter": "object", "shouldShowAggregatedBalancePopover": "boolean" }, "ipfsGateway": "string", 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 7fd8501eb2b8..006277f89160 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 @@ -38,7 +38,7 @@ "redesignedConfirmationsEnabled": true, "redesignedTransactionsEnabled": "boolean", "tokenSortConfig": "object", - "showMultiRpcModal": "boolean", + "tokenNetworkFilter": "object", "shouldShowAggregatedBalancePopover": "boolean" }, "firstTimeFlowType": "import", diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json index fa1a00cbe4ef..91c994e9ab66 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json @@ -119,7 +119,8 @@ "showConfirmationAdvancedDetails": false, "tokenSortConfig": "object", "showMultiRpcModal": "boolean", - "shouldShowAggregatedBalancePopover": "boolean" + "shouldShowAggregatedBalancePopover": "boolean", + "tokenNetworkFilter": "object" }, "selectedAddress": "string", "theme": "light", diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json index b3fa8d117beb..552f089c6604 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json @@ -135,6 +135,7 @@ "isRedesignedConfirmationsDeveloperEnabled": "boolean", "showConfirmationAdvancedDetails": false, "tokenSortConfig": "object", + "tokenNetworkFilter": "object", "showMultiRpcModal": "boolean", "shouldShowAggregatedBalancePopover": "boolean" }, From 3b7f4bff1dc9d6f4528310f26aa36db3b45d9bcb Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Mon, 18 Nov 2024 23:23:56 +0100 Subject: [PATCH 56/73] fix: fix e2e --- ui/hooks/useAccountTotalCrossChainFiatBalance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index 98f73623cc04..b68011b91976 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -58,7 +58,7 @@ export const useAccountTotalCrossChainFiatBalance = ( currencyRates?.[matchedChainSymbol]?.conversionRate; const tokenFiatBalances = tokensWithBalances.map((token) => { const tokenExchangeRate = - mergedCrossChainRates[singleChainTokenBalances.chainId][ + mergedCrossChainRates?.[singleChainTokenBalances.chainId]?.[ toChecksumAddress(token.address) ]; const totalFiatValue = getTokenFiatAmount( From cfaa119f78f8b93c09366b5546ad12c8f8e94a96 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 12:02:18 +0100 Subject: [PATCH 57/73] fix: fix e2e and update types --- .../tests/settings/account-token-list.spec.js | 17 ++++++++++++ ...gated-percentage-overview-cross-chains.tsx | 13 ++++------ .../account-list-item/account-list-item.js | 26 ++++++++++--------- .../useAccountTotalCrossChainFiatBalance.ts | 5 ++-- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/test/e2e/tests/settings/account-token-list.spec.js b/test/e2e/tests/settings/account-token-list.spec.js index 9e4822d0dbbc..29c7db3e91ef 100644 --- a/test/e2e/tests/settings/account-token-list.spec.js +++ b/test/e2e/tests/settings/account-token-list.spec.js @@ -5,6 +5,9 @@ const { logInWithBalanceValidation, unlockWallet, } = require('../../helpers'); +const { + switchToNetworkFlow, +} = require('../../page-objects/flows/network.flow'); const FixtureBuilder = require('../../fixture-builder'); @@ -63,6 +66,20 @@ describe('Settings', function () { ); await driver.delay(1000); assert.equal(await tokenListAmount.getText(), '$42,500.00\nUSD'); + + // switch to Sepolia + // the account list item used to always show account.balance as long as its EVM network. + // Now we are showing aggregated fiat balance on non testnetworks; but if it is a testnetwork we will show account.balance. + // The current test was running initially on localhost + // which is not a testnetwork resulting in the code trying to calculate the aggregated total fiat balance which shows 0.00$ + // If this test switches to mainnet then switches back to localhost; the test will pass because switching to mainnet + // will make the code calculate the aggregate fiat balance on mainnet+Linea mainnet and because this account in this test + // has 42,500.00 native Eth on mainnet then the aggregated total fiat would be 42,500.00. When the user switches back to localhost + // it will show the total that the test is expecting. + + // I think we can slightly modify this test to switch to Sepolia network before checking the account List item value + await switchToNetworkFlow(driver, 'Sepolia'); + await driver.clickElement('[data-testid="account-menu-icon"]'); const accountTokenValue = await driver.waitForSelector( '.multichain-account-list-item .multichain-account-list-item__asset', diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx index 6e3f7663cdcb..8ec14fd0f726 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx @@ -23,6 +23,7 @@ import { Box, SensitiveText } from '../../component-library'; import { getCalculatedTokenAmount1dAgo } from '../../../helpers/utils/util'; import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; import { useGetFormattedTokensPerChain } from '../../../hooks/useGetFormattedTokensPerChain'; +import { TokenWithBalance } from '../assets/asset-list/asset-list'; export const AggregatedPercentageOverviewCrossChains = () => { const locale = useSelector(getIntlLocale); @@ -49,8 +50,8 @@ export const AggregatedPercentageOverviewCrossChains = () => { const getPerChainTotalFiat1dAgo = ( chainId: string, - tokenFiatBalances: string[], - tokensWithBalances: { string: string; balance: string; address: string }[], + tokenFiatBalances: (string | undefined)[], + tokensWithBalances: TokenWithBalance[], ) => { const totalPerChain1dAgoERC20 = tokensWithBalances.reduce( (total1dAgo: number, item: { address: string }, idx: number) => { @@ -76,12 +77,8 @@ export const AggregatedPercentageOverviewCrossChains = () => { item: { chainId: string; nativeFiatValue: string; - tokenFiatBalances: string[]; - tokensWithBalances: { - string: string; - balance: string; - address: string; - }[]; + tokenFiatBalances: (string | undefined)[]; + tokensWithBalances: TokenWithBalance[]; }, ) => { const perChainERC20Total = getPerChainTotalFiat1dAgo( diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index cc0d77157215..f74402dc5956 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -48,15 +48,16 @@ import { MetaMetricsContext } from '../../../contexts/metametrics'; import { isAccountConnectedToCurrentTab, getUseBlockie, - getPreferences, getShouldHideZeroBalanceTokens, getIsTokenNetworkFilterEqualCurrentNetwork, + getShowFiatInTestnets, } from '../../../selectors'; import { getMultichainIsTestnet, getMultichainNativeCurrency, getMultichainNativeCurrencyImage, getMultichainNetwork, + getMultichainShouldShowFiat, } from '../../../selectors/multichain'; import { useMultichainAccountTotalFiatBalance } from '../../../hooks/useMultichainAccountTotalFiatBalance'; import { ConnectedStatus } from '../connected-status/connected-status'; @@ -102,11 +103,19 @@ const AccountListItem = ({ const setAccountListItemMenuRef = (ref) => { setAccountListItemMenuElement(ref); }; + const isTestnet = useMultichainSelector(getMultichainIsTestnet, account); + const isMainnet = !isTestnet; + const shouldShowFiat = useMultichainSelector( + getMultichainShouldShowFiat, + account, + ); + const showFiatInTestnets = useSelector(getShowFiatInTestnets); + const showFiat = + shouldShowFiat && (isMainnet || (isTestnet && showFiatInTestnets)); const accountTotalFiatBalances = useMultichainAccountTotalFiatBalance(account); // cross chain agg balance - const { showNativeTokenAsMainBalance } = useSelector(getPreferences); const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); @@ -130,10 +139,7 @@ const AccountListItem = ({ ); let balanceToTranslate; if (isEvmNetwork) { - balanceToTranslate = - showNativeTokenAsMainBalance || isTestnet // balance in crypto - ? account.balance - : totalFiatBalance; + balanceToTranslate = isTestnet ? account.balance : totalFiatBalance; } else { balanceToTranslate = accountTotalFiatBalances.totalBalance; } @@ -331,12 +337,8 @@ const AccountListItem = ({ ethNumberOfDecimals={MAXIMUM_CURRENCY_DECIMALS} value={balanceToTranslate} type={PRIMARY} - // showFiat={showFiat} - showFiat={!isEvmNetwork} - shouldCheckShowNativeToken - isAggregatedFiatOverviewBalance={ - !showNativeTokenAsMainBalance && !isTestnet - } + showFiat={showFiat} + isAggregatedFiatOverviewBalance={!isTestnet} data-testid="first-currency-display" privacyMode={privacyMode} /> diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index b68011b91976..1bb640154b47 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -94,9 +94,8 @@ export const useAccountTotalCrossChainFiatBalance = ( const finalTotal = tokenFiatBalancesCrossChains.reduce( (accumulator, currentValue) => { - const tmpCurrentValueFiatBalances = currentValue.tokenFiatBalances.filter( - (value) => value !== undefined, - ); + const tmpCurrentValueFiatBalances: string[] = + currentValue.tokenFiatBalances.filter((value) => value !== undefined); const totalFiatBalance = sumDecimals( currentValue.nativeFiatValue, ...tmpCurrentValueFiatBalances, From 47c6e9fdefe4a7d7f75e2ee9910514b1611aa54d Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 12:17:10 +0100 Subject: [PATCH 58/73] fix: fix unit test --- .../account-list-item.test.js | 44 +------------------ 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/ui/components/multichain/account-list-item/account-list-item.test.js b/ui/components/multichain/account-list-item/account-list-item.test.js index 9422b9205481..09febefb3d83 100644 --- a/ui/components/multichain/account-list-item/account-list-item.test.js +++ b/ui/components/multichain/account-list-item/account-list-item.test.js @@ -237,7 +237,7 @@ describe('AccountListItem', () => { expect(avatarGroup).not.toBeInTheDocument(); }); - it('renders fiat for EVM account when showNativeTokenAsMainBalance is false', () => { + it('renders fiat for EVM account', () => { const { container } = render( { account: mockAccount, @@ -251,7 +251,6 @@ describe('AccountListItem', () => { }), preferences: { showFiatInTestnets: true, - showNativeTokenAsMainBalance: false, }, }, }, @@ -278,47 +277,6 @@ describe('AccountListItem', () => { expect(avatarGroup).not.toBeInTheDocument(); }); - it('renders token for EVM account when showNativeTokenAsMainBalance is true', () => { - const { container } = render( - { - account: mockAccount, - }, - { - metamask: { - ...mockNetworkState({ - chainId: CHAIN_IDS.SEPOLIA, - nickname: SEPOLIA_DISPLAY_NAME, - ticker: 'ETH', - }), - preferences: { - showFiatInTestnets: true, - showNativeTokenAsMainBalance: true, - }, - }, - }, - ); - - const firstCurrencyDisplay = container.querySelector( - '[data-testid="first-currency-display"]', - ); - const secondCurrencyDisplay = container.querySelector( - '[data-testid="second-currency-display"]', - ); - const avatarGroup = container.querySelector( - '[data-testid="avatar-group"]', - ); - - const expectedBalance = '0.006'; - - expect(firstCurrencyDisplay).toBeInTheDocument(); - expect(firstCurrencyDisplay.firstChild.textContent).toContain( - expectedBalance, - ); - expect(firstCurrencyDisplay.lastChild.textContent).toContain('ETH'); - expect(secondCurrencyDisplay.textContent).toContain(''); - expect(avatarGroup).not.toBeInTheDocument(); - }); - it('renders fiat for non-EVM account', () => { const { container } = render( { From 5d512e6182f870308da96cafeaa17b1ad943e2e2 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 13:35:37 +0100 Subject: [PATCH 59/73] fix: fix network filter format and disable network filter when on testnet --- .../asset-list-control-bar.tsx | 7 ++++- .../network-filter/network-filter.tsx | 31 ++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx index c09421279265..7722eff36870 100644 --- a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx +++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from 'react'; +import React, { useMemo, useRef, useState } from 'react'; import { useSelector } from 'react-redux'; import { getCurrentNetwork, getPreferences } from '../../../../../selectors'; import { @@ -28,6 +28,7 @@ import { ENVIRONMENT_TYPE_POPUP, } from '../../../../../../shared/constants/app'; import NetworkFilter from '../network-filter'; +import { TEST_CHAINS } from '../../../../../../shared/constants/network'; type AssetListControlBarProps = { showTokensLinks?: boolean; @@ -43,6 +44,9 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { useState(false); const allNetworksFilterShown = Object.keys(tokenNetworkFilter ?? {}).length; + const isTestNetwork = useMemo(() => { + return (TEST_CHAINS as string[]).includes(currentNetwork.chainId); + }, [currentNetwork.chainId, TEST_CHAINS]); const windowType = getEnvironmentType(); const isFullScreen = @@ -84,6 +88,7 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { className="asset-list-control-bar__button" onClick={toggleNetworkFilterPopover} size={ButtonBaseSize.Sm} + disabled={isTestNetwork} endIconName={IconName.ArrowDown} backgroundColor={ isNetworkFilterPopoverOpen diff --git a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx index b3ac6ea54417..8a7e57c2a73b 100644 --- a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx +++ b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx @@ -4,7 +4,6 @@ import { setTokenNetworkFilter } from '../../../../../store/actions'; import { getCurrentChainId, getCurrentNetwork, - getIsTestnet, getPreferences, getSelectedInternalAccount, getShouldHideZeroBalanceTokens, @@ -37,7 +36,6 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { const selectedAccount = useSelector(getSelectedInternalAccount); const currentNetwork = useSelector(getCurrentNetwork); const allNetworks = useSelector(getNetworkConfigurationsByChainId); - const isTestnet = useSelector(getIsTestnet); const { tokenNetworkFilter } = useSelector(getPreferences); const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, @@ -46,7 +44,7 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( selectedAccount, shouldHideZeroBalanceTokens, - true, + true, // true to get formattedTokensWithBalancesPerChain for the current chain ); const { totalFiatBalance: selectedAccountBalance } = useAccountTotalCrossChainFiatBalance( @@ -58,7 +56,7 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { useGetFormattedTokensPerChain( selectedAccount, shouldHideZeroBalanceTokens, - false, + false, // false to get the value for all networks ); const { totalFiatBalance: selectedAccountBalanceForAllNetworks } = useAccountTotalCrossChainFiatBalance( @@ -105,8 +103,7 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { ethNumberOfDecimals={4} hideTitle showFiat - shouldCheckShowNativeToken - isAggregatedFiatOverviewBalance={!isTestnet} + isAggregatedFiatOverviewBalance /> @@ -149,15 +146,19 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { > {t('currentNetwork')} - + + + Date: Tue, 19 Nov 2024 14:04:21 +0100 Subject: [PATCH 60/73] fix: lint --- ui/hooks/useAccountTotalCrossChainFiatBalance.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index 1bb640154b47..995e6a172bbb 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -95,7 +95,9 @@ export const useAccountTotalCrossChainFiatBalance = ( const finalTotal = tokenFiatBalancesCrossChains.reduce( (accumulator, currentValue) => { const tmpCurrentValueFiatBalances: string[] = - currentValue.tokenFiatBalances.filter((value) => value !== undefined); + currentValue.tokenFiatBalances.filter( + (value): value is string => value !== undefined, + ); const totalFiatBalance = sumDecimals( currentValue.nativeFiatValue, ...tmpCurrentValueFiatBalances, From f92add6e0541880797db908258aa9fac13ba4d4a Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 14:11:13 +0100 Subject: [PATCH 61/73] fix: use getChainIdsToPoll selector --- ui/hooks/useGetFormattedTokensPerChain.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ui/hooks/useGetFormattedTokensPerChain.ts b/ui/hooks/useGetFormattedTokensPerChain.ts index b0acaf414f77..20af88e44f6a 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.ts +++ b/ui/hooks/useGetFormattedTokensPerChain.ts @@ -2,13 +2,12 @@ import { useSelector } from 'react-redux'; import { BN } from 'bn.js'; import { Token } from '@metamask/assets-controllers'; import { - getNetworkConfigurationsByChainId, getAllTokens, getCurrentChainId, + getChainIdsToPoll, } from '../selectors'; import { hexToDecimal } from '../../shared/modules/conversion.utils'; -import { TEST_CHAINS } from '../../shared/constants/network'; import { TokenWithBalance } from '../components/multichain/asset-picker-amount/asset-picker-modal/types'; import { stringifyBalance, useTokenBalances } from './useTokenBalances'; @@ -27,13 +26,10 @@ export const useGetFormattedTokensPerChain = ( shouldHideZeroBalanceTokens: boolean, shouldGetTokensPerCurrentChain: boolean, ) => { - const allNetworks = useSelector(getNetworkConfigurationsByChainId); const currentChainId = useSelector(getCurrentChainId); // We want to filter out test chains - const allChainIDs = Object.keys(allNetworks).filter( - (singleChainId) => - !TEST_CHAINS.includes(singleChainId as (typeof TEST_CHAINS)[number]), - ); + const allChainIDs = useSelector(getChainIdsToPoll); + const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported const currentTokenBalances: { tokenBalances: TokenBalancesMapping } = useTokenBalances({ From decb2f13293a6ba69fe589c547481076f0fc17cd Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 14:44:06 +0100 Subject: [PATCH 62/73] fix: fix import --- ui/components/app/wallet-overview/coin-overview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 211b8f064235..36dfe2519fde 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -50,12 +50,12 @@ import { getTokensMarketData, getIsTestnet, getShouldShowAggregatedBalancePopover, + getIsTokenNetworkFilterEqualCurrentNetwork, ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) getDataCollectionForMarketing, getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, - getIsTokenNetworkFilterEqualCurrentNetwork, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; From 1f97c68d1fe8f4e5f2910766761464655d812b38 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 16:12:50 +0100 Subject: [PATCH 63/73] fix: fix --- ui/selectors/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index dac03d3c99cd..7e4d04eeb3de 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -598,7 +598,7 @@ export const getCrossChainTokenExchangeRates = (state) => { return Object.keys(contractMarketData).reduce((acc, topLevelKey) => { acc[topLevelKey] = Object.keys(contractMarketData[topLevelKey]).reduce( (innerAcc, innerKey) => { - innerAcc[innerKey] = contractMarketData[topLevelKey][innerKey].price; + innerAcc[innerKey] = contractMarketData[topLevelKey][innerKey]?.price; return innerAcc; }, {}, From fa55e4c89842473db6f72b18bbf009a537c98a6d Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 17:22:21 +0100 Subject: [PATCH 64/73] fix: refactor usage of getChainIdsToPoll --- .../assets/asset-list/network-filter/network-filter.tsx | 5 ++++- .../aggregated-percentage-overview-cross-chains.tsx | 4 +++- ui/components/app/wallet-overview/coin-overview.tsx | 4 +++- .../multichain/account-list-item/account-list-item.js | 8 +++++++- ui/hooks/useGetFormattedTokensPerChain.ts | 9 ++------- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx index 8a7e57c2a73b..8b9fc06b33e7 100644 --- a/ui/components/app/assets/asset-list/network-filter/network-filter.tsx +++ b/ui/components/app/assets/asset-list/network-filter/network-filter.tsx @@ -8,6 +8,7 @@ import { getSelectedInternalAccount, getShouldHideZeroBalanceTokens, getNetworkConfigurationsByChainId, + getChainIdsToPoll, } from '../../../../../selectors'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { SelectableListItem } from '../sort-control/sort-control'; @@ -40,11 +41,12 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); - + const allChainIDs = useSelector(getChainIdsToPoll); const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( selectedAccount, shouldHideZeroBalanceTokens, true, // true to get formattedTokensWithBalancesPerChain for the current chain + allChainIDs, ); const { totalFiatBalance: selectedAccountBalance } = useAccountTotalCrossChainFiatBalance( @@ -57,6 +59,7 @@ const NetworkFilter = ({ handleClose }: SortControlProps) => { selectedAccount, shouldHideZeroBalanceTokens, false, // false to get the value for all networks + allChainIDs, ); const { totalFiatBalance: selectedAccountBalanceForAllNetworks } = useAccountTotalCrossChainFiatBalance( diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx index 8ec14fd0f726..fe3698e2fc2f 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.tsx @@ -8,6 +8,7 @@ import { getShouldHideZeroBalanceTokens, getPreferences, getMarketData, + getChainIdsToPoll, } from '../../../selectors'; // TODO: Remove restricted import @@ -34,11 +35,12 @@ export const AggregatedPercentageOverviewCrossChains = () => { getShouldHideZeroBalanceTokens, ); const crossChainMarketData = useSelector(getMarketData); - + const allChainIDs = useSelector(getChainIdsToPoll); const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( selectedAccount, shouldHideZeroBalanceTokens, false, + allChainIDs, ); const { totalFiatBalance: totalFiatCrossChains, diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 36dfe2519fde..e3a9ab75e8b1 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -56,6 +56,7 @@ import { getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, + getChainIdsToPoll, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; @@ -147,11 +148,12 @@ export const CoinOverview = ({ const shouldHideZeroBalanceTokens = useSelector( getShouldHideZeroBalanceTokens, ); - + const allChainIDs = useSelector(getChainIdsToPoll); const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( account, shouldHideZeroBalanceTokens, isTokenNetworkFilterEqualCurrentNetwork, + allChainIDs, ); const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( account, diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index f74402dc5956..b73c53eea614 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -51,6 +51,7 @@ import { getShouldHideZeroBalanceTokens, getIsTokenNetworkFilterEqualCurrentNetwork, getShowFiatInTestnets, + getChainIdsToPoll, } from '../../../selectors'; import { getMultichainIsTestnet, @@ -122,10 +123,12 @@ const AccountListItem = ({ const isTokenNetworkFilterEqualCurrentNetwork = useSelector( getIsTokenNetworkFilterEqualCurrentNetwork, ); + const allChainIDs = useSelector(getChainIdsToPoll); const { formattedTokensWithBalancesPerChain } = useGetFormattedTokensPerChain( account, shouldHideZeroBalanceTokens, isTokenNetworkFilterEqualCurrentNetwork, + allChainIDs, ); const { totalFiatBalance } = useAccountTotalCrossChainFiatBalance( account, @@ -139,7 +142,10 @@ const AccountListItem = ({ ); let balanceToTranslate; if (isEvmNetwork) { - balanceToTranslate = isTestnet ? account.balance : totalFiatBalance; + balanceToTranslate = + isTestnet || !process.env.PORTFOLIO_VIEW + ? account.balance + : totalFiatBalance; } else { balanceToTranslate = accountTotalFiatBalances.totalBalance; } diff --git a/ui/hooks/useGetFormattedTokensPerChain.ts b/ui/hooks/useGetFormattedTokensPerChain.ts index 20af88e44f6a..a69f5be9e1e0 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.ts +++ b/ui/hooks/useGetFormattedTokensPerChain.ts @@ -1,11 +1,7 @@ import { useSelector } from 'react-redux'; import { BN } from 'bn.js'; import { Token } from '@metamask/assets-controllers'; -import { - getAllTokens, - getCurrentChainId, - getChainIdsToPoll, -} from '../selectors'; +import { getAllTokens, getCurrentChainId } from '../selectors'; import { hexToDecimal } from '../../shared/modules/conversion.utils'; import { TokenWithBalance } from '../components/multichain/asset-picker-amount/asset-picker-modal/types'; @@ -25,10 +21,9 @@ export const useGetFormattedTokensPerChain = ( account: { address: string }, shouldHideZeroBalanceTokens: boolean, shouldGetTokensPerCurrentChain: boolean, + allChainIDs: string[], ) => { const currentChainId = useSelector(getCurrentChainId); - // We want to filter out test chains - const allChainIDs = useSelector(getChainIdsToPoll); const importedTokens = useSelector(getAllTokens); // returns the tokens only when they are imported const currentTokenBalances: { tokenBalances: TokenBalancesMapping } = From 33bcfad1337031c29bf8f80fd4ba9d87e15c3a68 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 17:42:18 +0100 Subject: [PATCH 65/73] fix: add feature flag for agg percentage overview --- ui/components/app/wallet-overview/coin-overview.tsx | 3 ++- ui/hooks/useAccountTotalCrossChainFiatBalance.ts | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index e3a9ab75e8b1..d97f9f22b32c 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -241,7 +241,8 @@ export const CoinOverview = ({ } return ( - {isTokenNetworkFilterEqualCurrentNetwork ? ( + {isTokenNetworkFilterEqualCurrentNetwork || + !process.env.PORTFOLIO_VIEW ? ( ) : ( diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index 995e6a172bbb..b74fc5f8fd42 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -42,8 +42,6 @@ export const useAccountTotalCrossChainFiatBalance = ( getCrossChainMetaMaskCachedBalances, ); - // const loading = false; //todo check if loading is still needed - const mergedCrossChainRates: Balances = { ...crossChainContractRates, // todo add confirmation exchange rates? }; From 4cbeb577783dbeb44c6d94579e5bc04603e14597 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 18:06:02 +0100 Subject: [PATCH 66/73] fix: feature flag on account list item --- .../multichain/account-list-item/account-list-item.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/components/multichain/account-list-item/account-list-item.js b/ui/components/multichain/account-list-item/account-list-item.js index b73c53eea614..e63266080be5 100644 --- a/ui/components/multichain/account-list-item/account-list-item.js +++ b/ui/components/multichain/account-list-item/account-list-item.js @@ -344,7 +344,9 @@ const AccountListItem = ({ value={balanceToTranslate} type={PRIMARY} showFiat={showFiat} - isAggregatedFiatOverviewBalance={!isTestnet} + isAggregatedFiatOverviewBalance={ + !isTestnet && process.env.PORTFOLIO_VIEW + } data-testid="first-currency-display" privacyMode={privacyMode} /> From 04505e46832f3a920986bf1ca165721072a2b8a1 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 18:55:24 +0100 Subject: [PATCH 67/73] fix: add unit test --- .../useGetFormattedTokensPerChain.test.ts | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 ui/hooks/useGetFormattedTokensPerChain.test.ts diff --git a/ui/hooks/useGetFormattedTokensPerChain.test.ts b/ui/hooks/useGetFormattedTokensPerChain.test.ts new file mode 100644 index 000000000000..d47174fc7b97 --- /dev/null +++ b/ui/hooks/useGetFormattedTokensPerChain.test.ts @@ -0,0 +1,152 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { renderHook } from '@testing-library/react-hooks'; +import { act } from 'react-dom/test-utils'; +import { useGetFormattedTokensPerChain } from './useGetFormattedTokensPerChain'; +import { getAllTokens, getCurrentChainId } from '../selectors'; +import { stringifyBalance } from './useTokenBalances'; + +jest.mock('react-redux', () => ({ + useSelector: jest.fn((selector) => selector()), +})); + +jest.mock('../selectors', () => ({ + getCurrentChainId: jest.fn(), + getAllTokens: jest.fn(), +})); + +const mockGetAllTokens = getAllTokens as jest.Mock; +const mockGetCurrentChainId = getCurrentChainId as jest.Mock; + +const mockUseTokenBalances = jest.fn().mockReturnValue({ + tokenBalances: { + '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5': { + '0x1': { + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': '0x2f18e6', + '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0x378afc9a77b47a30', + }, + }, + }, +}); +jest.mock('./useTokenBalances', () => ({ + useTokenBalances: () => mockUseTokenBalances(), + stringifyBalance: jest.fn(), +})); + +const allTokens = { + '0x1': { + '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5': [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + aggregators: [ + 'Metamask', + 'Aave', + 'Bancor', + 'Crypto.com', + '1inch', + 'PMM', + 'Sushiswap', + 'Zerion', + 'Lifi', + 'Socket', + 'Squid', + 'Openswap', + 'UniswapLabs', + 'Coinmarketcap', + ], + decimals: 6, + symbol: 'USDC', + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + aggregators: [ + 'Metamask', + 'Aave', + 'Bancor', + 'CMC', + 'Crypto.com', + '1inch', + 'PMM', + 'Sushiswap', + 'Zerion', + 'Lifi', + 'Socket', + 'Squid', + 'Openswap', + 'UniswapLabs', + 'Coinmarketcap', + ], + decimals: 18, + symbol: 'DAI', + }, + ], + }, +}; + +describe('useGetFormattedTokensPerChain', () => { + beforeEach(() => { + mockGetAllTokens.mockReturnValue(allTokens); + mockGetCurrentChainId.mockReturnValue('0x1'); + + jest.clearAllMocks(); + }); + it('should tokensWithBalances for an array of chainIds', async () => { + (stringifyBalance as jest.Mock).mockReturnValueOnce(10.5); + (stringifyBalance as jest.Mock).mockReturnValueOnce(13); + const allChainIDs = ['0x1']; + const isTokenNetworkFilterEqualCurrentNetwork = true; + const shouldHideZeroBalanceTokens = true; + const testAccount = { + id: '7d3a1213-c465-4995-b42a-85e2ccfd2f22', + address: '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5', + options: {}, + methods: [ + 'personal_sign', + 'eth_sign', + 'eth_signTransaction', + 'eth_signTypedData_v1', + 'eth_signTypedData_v3', + 'eth_signTypedData_v4', + ], + }; + + const expectedResult = { + formattedTokensWithBalancesPerChain: [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + balance: '3086566', + decimals: 6, + string: 10.5, + symbol: 'USDC', + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + balance: '4002288959235586608', + decimals: 18, + string: 13, + symbol: 'DAI', + }, + ], + }, + ], + }; + + let result; + await act(async () => { + result = renderHook(() => + useGetFormattedTokensPerChain( + testAccount, + shouldHideZeroBalanceTokens, + isTokenNetworkFilterEqualCurrentNetwork, + allChainIDs, + ), + ); + }); + + expect((result as unknown as Record).result.current).toEqual( + expectedResult, + ); + }); +}); From 31a6b36bde2e32b15d8fc9284b1357f3f53479b5 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 19:07:50 +0100 Subject: [PATCH 68/73] fix: fix unit test --- .../aggregated-percentage-overview-cross-chains.test.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx index 06f3b9a4bec1..1a335de9c14b 100644 --- a/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx +++ b/ui/components/app/wallet-overview/aggregated-percentage-overview-cross-chains.test.tsx @@ -10,6 +10,7 @@ import { getMarketData, getNetworkConfigurationsByChainId, getAllTokens, + getChainIdsToPoll, } from '../../../selectors'; import { useAccountTotalCrossChainFiatBalance } from '../../../hooks/useAccountTotalCrossChainFiatBalance'; import { AggregatedPercentageOverviewCrossChains } from './aggregated-percentage-overview-cross-chains'; @@ -37,6 +38,7 @@ jest.mock('../../../selectors', () => ({ getMarketData: jest.fn(), getNetworkConfigurationsByChainId: jest.fn(), getAllTokens: jest.fn(), + getChainIdsToPoll: jest.fn(), })); jest.mock('../../../hooks/useAccountTotalCrossChainFiatBalance', () => ({ @@ -51,6 +53,7 @@ const mockGetShouldHideZeroBalanceTokens = getShouldHideZeroBalanceTokens as jest.Mock; const mockGetMarketData = getMarketData as jest.Mock; +const mockGetChainIdsToPoll = getChainIdsToPoll as unknown as jest.Mock; const mockGetNetworkConfigurationsByChainId = getNetworkConfigurationsByChainId as unknown as jest.Mock; const mockGetAllTokens = getAllTokens as jest.Mock; @@ -373,6 +376,7 @@ describe('AggregatedPercentageOverviewCrossChains', () => { mockGetShouldHideZeroBalanceTokens.mockReturnValue(false); mockGetMarketData.mockReturnValue(crossChainMarketDataMock); + mockGetChainIdsToPoll.mockReturnValue(['0x1']); mockGetNetworkConfigurationsByChainId.mockReturnValue( networkConfigsByChainId, ); From 48312b7d3446207636fbce4e946cf0f990effd46 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 19:45:51 +0100 Subject: [PATCH 69/73] fix: add unit test --- ...eAccountTotalCrossChainFiatBalance.test.ts | 226 ++++++++++++++++++ .../useAccountTotalCrossChainFiatBalance.ts | 12 +- .../useGetFormattedTokensPerChain.test.ts | 2 +- 3 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts new file mode 100644 index 000000000000..9fe819d92171 --- /dev/null +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.test.ts @@ -0,0 +1,226 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { renderHook } from '@testing-library/react-hooks'; +import { act } from 'react-dom/test-utils'; +import { + getCurrentCurrency, + getNetworkConfigurationsByChainId, + getCrossChainTokenExchangeRates, + getCrossChainMetaMaskCachedBalances, +} from '../selectors'; +import { getCurrencyRates } from '../ducks/metamask/metamask'; +import { + FormattedTokensWithBalances, + useAccountTotalCrossChainFiatBalance, +} from './useAccountTotalCrossChainFiatBalance'; + +jest.mock('react-redux', () => ({ + useSelector: jest.fn((selector) => selector()), +})); + +jest.mock('../selectors', () => ({ + getCurrentCurrency: jest.fn(), + getNetworkConfigurationsByChainId: jest.fn(), + getCrossChainTokenExchangeRates: jest.fn(), + getCrossChainMetaMaskCachedBalances: jest.fn(), +})); +jest.mock('../ducks/metamask/metamask', () => ({ + getCurrencyRates: jest.fn(), +})); + +const mockGetCurrencyRates = getCurrencyRates as jest.Mock; +const mockGetCurrentCurrency = getCurrentCurrency as jest.Mock; +const mockGetNetworkConfigurationsByChainId = + getNetworkConfigurationsByChainId as unknown as jest.Mock; +const mockGetCrossChainTokenExchangeRates = + getCrossChainTokenExchangeRates as jest.Mock; +const mockGetCrossChainMetaMaskCachedBalances = + getCrossChainMetaMaskCachedBalances as jest.Mock; + +const mockUseTokenBalances = jest.fn().mockReturnValue({ + tokenBalances: { + '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5': { + '0x1': { + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': '0x2f18e6', + '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0x378afc9a77b47a30', + }, + }, + }, +}); +jest.mock('./useTokenBalances', () => ({ + useTokenBalances: () => mockUseTokenBalances(), + stringifyBalance: jest.fn(), +})); + +const mockCurrencyRates = { + ETH: { + conversionDate: 1732040829.246, + conversionRate: 3124.56, + usdConversionRate: 3124.56, + }, + LineaETH: { + conversionDate: 1732040829.246, + conversionRate: 3124.56, + usdConversionRate: 3124.56, + }, +}; + +const mockNetworkConfigs = { + '0x1': { + blockExplorerUrls: ['https://etherscan.io'], + chainId: '0x1', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Ethereum Mainnet', + nativeCurrency: 'ETH', + rpcEndpoints: [ + { + networkClientId: 'mainnet', + type: 'infura', + url: 'https://mainnet.infura.io/v3/{infuraProjectId}', + }, + ], + }, + '0xe708': { + blockExplorerUrls: ['https://lineascan.build'], + chainId: '0xe708', + defaultBlockExplorerUrlIndex: 0, + defaultRpcEndpointIndex: 0, + name: 'Linea', + nativeCurrency: 'ETH', + rpcEndpoints: [ + { + networkClientId: 'linea-mainnet', + type: 'infura', + url: 'https://linea-mainnet.infura.io/v3/{infuraProjectId}', + }, + ], + }, +}; + +const mockCrossChainTokenExchangeRates = { + '0x1': { + '0x0000000000000000000000000000000000000000': 1.0000131552270237, + '0x4d224452801ACEd8B2F0aebE155379bb5D594381': 0.0003643652288147761, + '0x6982508145454Ce325dDbE47a25d4ec3d2311933': 6.62249784302e-9, + '0x6B175474E89094C44Da98b954EedeAC495271d0F': 0.00031961862176734744, + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 0.00031993824038911484, + '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84': 0.9994154684043188, + }, + '0xe708': { + '0x0000000000000000000000000000000000000000': 0.9999084951480334, + }, +}; + +const mockCachedBalances = { + '0x1': { + '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5': '0x4e2adedda15fd6', + }, + '0xe708': { + '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5': '0x4e2adedda15fd6', + }, +}; + +describe('useAccountTotalCrossChainFiatBalance', () => { + beforeEach(() => { + mockGetCurrencyRates.mockReturnValue(mockCurrencyRates); + mockGetCurrentCurrency.mockReturnValue('usd'); + mockGetNetworkConfigurationsByChainId.mockReturnValue(mockNetworkConfigs); + mockGetCrossChainTokenExchangeRates.mockReturnValue( + mockCrossChainTokenExchangeRates, + ); + mockGetCrossChainMetaMaskCachedBalances.mockReturnValue(mockCachedBalances); + + jest.clearAllMocks(); + }); + it('should return totalFiatBalance successfully for eth and linea', async () => { + const testAccount = { + id: '7d3a1213-c465-4995-b42a-85e2ccfd2f22', + address: '0xac7985f2e57609bdd7ad3003e4be868d83e4b6d5', + options: {}, + methods: [ + 'personal_sign', + 'eth_sign', + 'eth_signTransaction', + 'eth_signTypedData_v1', + 'eth_signTypedData_v3', + 'eth_signTypedData_v4', + ], + }; + const testFormattedTokensWithBalances = [ + { + chainId: '0x1', + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + decimals: 6, + balance: '3086566', + string: '3.08656', + image: '', + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', + decimals: 18, + balance: '4002288959235586608', + string: '4.00228', + image: '', + }, + ], + }, + { + chainId: '0xe708', + tokensWithBalances: [], + }, + ]; + + const expectedResult = { + tokenFiatBalancesCrossChains: [ + { + chainId: '0x1', + nativeFiatValue: '68.75', + tokenFiatBalances: ['3.09', '4'], + tokensWithBalances: [ + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + balance: '3086566', + decimals: 6, + image: '', + string: '3.08656', + symbol: 'USDC', + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + balance: '4002288959235586608', + decimals: 18, + image: '', + string: '4.00228', + symbol: 'DAI', + }, + ], + }, + { + chainId: '0xe708', + nativeFiatValue: '68.75', + tokenFiatBalances: [], + tokensWithBalances: [], + }, + ], + totalFiatBalance: '144.59', + }; + + let result; + await act(async () => { + result = renderHook(() => + useAccountTotalCrossChainFiatBalance( + testAccount, + testFormattedTokensWithBalances as FormattedTokensWithBalances[], + ), + ); + }); + + expect((result as unknown as Record).result.current).toEqual( + expectedResult, + ); + }); +}); diff --git a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts index b74fc5f8fd42..d63328e4fbcf 100644 --- a/ui/hooks/useAccountTotalCrossChainFiatBalance.ts +++ b/ui/hooks/useAccountTotalCrossChainFiatBalance.ts @@ -22,12 +22,14 @@ export type Balances = { [id: string]: AddressBalances; }; +export type FormattedTokensWithBalances = { + chainId: string; + tokensWithBalances: TokenWithBalance[]; +}; + export const useAccountTotalCrossChainFiatBalance = ( account: { address: string }, - formattedTokensWithBalancesPerChain: { - chainId: string; - tokensWithBalances: TokenWithBalance[]; - }[], + formattedTokensWithBalancesPerChain: FormattedTokensWithBalances[], ) => { const allNetworks = useSelector(getNetworkConfigurationsByChainId); const currencyRates = useSelector(getCurrencyRates); @@ -37,11 +39,9 @@ export const useAccountTotalCrossChainFiatBalance = ( getCrossChainTokenExchangeRates, shallowEqual, ); - const crossChainCachedBalances: Balances = useSelector( getCrossChainMetaMaskCachedBalances, ); - const mergedCrossChainRates: Balances = { ...crossChainContractRates, // todo add confirmation exchange rates? }; diff --git a/ui/hooks/useGetFormattedTokensPerChain.test.ts b/ui/hooks/useGetFormattedTokensPerChain.test.ts index d47174fc7b97..973a16b0e648 100644 --- a/ui/hooks/useGetFormattedTokensPerChain.test.ts +++ b/ui/hooks/useGetFormattedTokensPerChain.test.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { renderHook } from '@testing-library/react-hooks'; import { act } from 'react-dom/test-utils'; -import { useGetFormattedTokensPerChain } from './useGetFormattedTokensPerChain'; import { getAllTokens, getCurrentChainId } from '../selectors'; +import { useGetFormattedTokensPerChain } from './useGetFormattedTokensPerChain'; import { stringifyBalance } from './useTokenBalances'; jest.mock('react-redux', () => ({ From 69c9d5b864179185aa90123f635f376c48e7261c Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 20:23:15 +0100 Subject: [PATCH 70/73] fix: update popover text --- app/_locales/en/messages.json | 4 ++ .../app/wallet-overview/coin-overview.tsx | 46 +++++++++++++------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 610ddba3a4dd..01ab19b7dcf9 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1343,6 +1343,10 @@ "creatorAddress": { "message": "Creator address" }, + "crossChainAggregatedBalancePopover": { + "message": "This reflects the value of all tokens you own on all networks. If you prefer seeing this value in ETH or other currencies, go to $1.", + "description": "$1 represents the settings page" + }, "crossChainSwapsLink": { "message": "Swap across networks with MetaMask Portfolio" }, diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index d97f9f22b32c..af4b31f80ca8 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -363,21 +363,37 @@ export const CoinOverview = ({ - {t('aggregatedBalancePopover', [ - - {t('settings')} - , - ])} + {process.env.PORTFOLIO_VIEW + ? t('crossChainAggregatedBalancePopover', [ + + {t('settings')} + , + ]) + : t('aggregatedBalancePopover', [ + + {t('settings')} + , + ])} From 69ed10a72af20c479095c64c043145878851137c Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 22:04:22 +0100 Subject: [PATCH 71/73] fix: fix import --- ui/components/app/wallet-overview/coin-overview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index af4b31f80ca8..b06f0c06b374 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -51,12 +51,12 @@ import { getIsTestnet, getShouldShowAggregatedBalancePopover, getIsTokenNetworkFilterEqualCurrentNetwork, + getChainIdsToPoll, ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) getDataCollectionForMarketing, getMetaMetricsId, getParticipateInMetaMetrics, SwapsEthToken, - getChainIdsToPoll, ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Spinner from '../../ui/spinner'; From 0c058aad8eff3b63d7aece4787a6080224d15907 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Tue, 19 Nov 2024 23:42:05 +0100 Subject: [PATCH 72/73] fix: rm privacy snapshot updates --- privacy-snapshot.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/privacy-snapshot.json b/privacy-snapshot.json index 9de6ab69b4bd..817d1e102bff 100644 --- a/privacy-snapshot.json +++ b/privacy-snapshot.json @@ -29,8 +29,6 @@ "github.com", "goerli.infura.io", "lattice.gridplus.io", - "linea-mainnet.infura.io", - "linea-sepolia.infura.io", "localhost:8000", "localhost:8545", "mainnet.infura.io", @@ -54,7 +52,6 @@ "security-alerts.api.cx.metamask.io", "security-alerts.dev-api.cx.metamask.io", "sentry.io", - "sepolia.infura.io", "snaps.metamask.io", "sourcify.dev", "start.metamask.io", From d380413baac31a28eb8fac0c472a9275ab775986 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Wed, 20 Nov 2024 00:42:46 +0100 Subject: [PATCH 73/73] fix: add mock for e2e and update privacy snapshot --- privacy-snapshot.json | 3 ++- .../tests/settings/account-token-list.spec.js | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/privacy-snapshot.json b/privacy-snapshot.json index 817d1e102bff..f5cf068b8728 100644 --- a/privacy-snapshot.json +++ b/privacy-snapshot.json @@ -52,12 +52,13 @@ "security-alerts.api.cx.metamask.io", "security-alerts.dev-api.cx.metamask.io", "sentry.io", + "sepolia.infura.io", "snaps.metamask.io", "sourcify.dev", "start.metamask.io", "static.cx.metamask.io", - "support.metamask.io", "support.metamask-institutional.io", + "support.metamask.io", "swap.api.cx.metamask.io", "test.metamask-phishing.io", "token.api.cx.metamask.io", diff --git a/test/e2e/tests/settings/account-token-list.spec.js b/test/e2e/tests/settings/account-token-list.spec.js index 29c7db3e91ef..ddd905501f50 100644 --- a/test/e2e/tests/settings/account-token-list.spec.js +++ b/test/e2e/tests/settings/account-token-list.spec.js @@ -9,8 +9,34 @@ const { switchToNetworkFlow, } = require('../../page-objects/flows/network.flow'); +const { mockServerJsonRpc } = require('../ppom/mocks/mock-server-json-rpc'); const FixtureBuilder = require('../../fixture-builder'); +const infuraSepoliaUrl = + 'https://sepolia.infura.io/v3/00000000000000000000000000000000'; + +async function mockInfura(mockServer) { + await mockServerJsonRpc(mockServer, [ + ['eth_blockNumber'], + ['eth_getBlockByNumber'], + ]); + await mockServer + .forPost(infuraSepoliaUrl) + .withJsonBodyIncluding({ method: 'eth_getBalance' }) + .thenCallback(() => ({ + statusCode: 200, + json: { + jsonrpc: '2.0', + id: '6857940763865360', + result: '0x15af1d78b58c40000', + }, + })); +} + +async function mockInfuraResponses(mockServer) { + await mockInfura(mockServer); +} + describe('Settings', function () { it('Should match the value of token list item and account list item for eth conversion', async function () { await withFixtures( @@ -52,6 +78,7 @@ describe('Settings', function () { .build(), ganacheOptions: defaultGanacheOptions, title: this.test.fullTitle(), + testSpecificMock: mockInfuraResponses, }, async ({ driver }) => { await unlockWallet(driver);