diff --git a/jest.config.js b/jest.config.js index 88805a1..b456054 100644 --- a/jest.config.js +++ b/jest.config.js @@ -41,10 +41,10 @@ module.exports = { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 90.09, - functions: 84.21, - lines: 95.32, - statements: 95.32, + branches: 94.44, + functions: 85, + lines: 96.87, + statements: 96.87, }, }, diff --git a/package.json b/package.json index 1eba820..5ce51c5 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test:watch": "jest --watch" }, "dependencies": { - "@metamask/utils": "^3.2.0", + "@metamask/utils": "^5.0.0", "fast-safe-stringify": "^2.0.6" }, "devDependencies": { @@ -63,7 +63,7 @@ "prettier-plugin-packagejson": "^2.2.18", "ts-jest": "^28.0.7", "typedoc": "^0.23.19", - "typescript": "~4.7.4" + "typescript": "~4.9.5" }, "packageManager": "yarn@3.2.4", "engines": { diff --git a/src/__fixtures__/errors.ts b/src/__fixtures__/errors.ts index 47a4043..25472d2 100644 --- a/src/__fixtures__/errors.ts +++ b/src/__fixtures__/errors.ts @@ -5,7 +5,7 @@ export const dummyMessage = 'baz'; export const invalidError0 = 0; export const invalidError1 = ['foo', 'bar', 3]; -export const invalidError2 = { code: 34 }; +export const invalidError2 = { code: 'foo' }; export const invalidError3 = { code: 4001 }; export const invalidError4 = { code: 4001, @@ -15,7 +15,7 @@ export const invalidError4 = { export const invalidError5 = null; export const invalidError6 = undefined; export const invalidError7 = { - code: 34, + code: 'foo', message: dummyMessage, data: Object.assign({}, dummyData), }; diff --git a/src/classes.ts b/src/classes.ts index 9a3b2f9..1654ad2 100644 --- a/src/classes.ts +++ b/src/classes.ts @@ -1,12 +1,7 @@ import safeStringify from 'fast-safe-stringify'; -import { Json } from '@metamask/utils'; +import { Json, JsonRpcError } from '@metamask/utils'; -export type SerializedEthereumRpcError = { - code: number; - message: string; - data?: Json; - stack?: string; -}; +export { JsonRpcError }; /** * Error subclass implementing JSON RPC 2.0 errors and Ethereum RPC errors @@ -40,8 +35,8 @@ export class EthereumRpcError extends Error { * * @returns A plain object with all public class properties. */ - serialize(): SerializedEthereumRpcError { - const serialized: SerializedEthereumRpcError = { + serialize(): JsonRpcError { + const serialized: JsonRpcError = { code: this.code, message: this.message, }; diff --git a/src/utils.test.ts b/src/utils.test.ts index 3007598..b73801d 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -13,9 +13,10 @@ import { validError3, validError4, dummyMessage, + dummyData, } from './__fixtures__'; import { getMessageFromCode, serializeError } from './utils'; -import { errorCodes } from '.'; +import { errorCodes, ethErrors } from '.'; const rpcCodes = errorCodes.rpc; @@ -25,7 +26,7 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.internal, message: getMessageFromCode(rpcCodes.internal), - data: { originalError: invalidError0 }, + data: { cause: invalidError0 }, }); }); @@ -34,7 +35,7 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.internal, message: getMessageFromCode(rpcCodes.internal), - data: { originalError: invalidError5 }, + data: { cause: invalidError5 }, }); }); @@ -43,7 +44,7 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.internal, message: getMessageFromCode(rpcCodes.internal), - data: { originalError: invalidError6 }, + data: { cause: null }, }); }); @@ -52,7 +53,7 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.internal, message: getMessageFromCode(rpcCodes.internal), - data: { originalError: invalidError1 }, + data: { cause: invalidError1 }, }); }); @@ -61,25 +62,35 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.internal, message: getMessageFromCode(rpcCodes.internal), - data: { originalError: invalidError2 }, + data: { cause: invalidError2 }, }); }); it('handles invalid error: valid code, undefined message', () => { const result = serializeError(invalidError3); expect(result).toStrictEqual({ - code: 4001, - message: getMessageFromCode(4001), - data: { originalError: Object.assign({}, invalidError3) }, + code: errorCodes.rpc.internal, + message: getMessageFromCode(errorCodes.rpc.internal), + data: { + cause: { + code: 4001, + }, + }, }); }); it('handles invalid error: non-string message with data', () => { const result = serializeError(invalidError4); expect(result).toStrictEqual({ - code: 4001, - message: getMessageFromCode(4001), - data: { originalError: Object.assign({}, invalidError4) }, + code: rpcCodes.internal, + message: getMessageFromCode(rpcCodes.internal), + data: { + cause: { + code: invalidError4.code, + message: invalidError4.message, + data: Object.assign({}, dummyData), + }, + }, }); }); @@ -87,8 +98,14 @@ describe('serializeError', () => { const result = serializeError(invalidError7); expect(result).toStrictEqual({ code: rpcCodes.internal, - message: dummyMessage, - data: { originalError: Object.assign({}, invalidError7) }, + message: getMessageFromCode(rpcCodes.internal), + data: { + cause: { + code: invalidError7.code, + message: invalidError7.message, + data: Object.assign({}, dummyData), + }, + }, }); }); @@ -99,7 +116,7 @@ describe('serializeError', () => { expect(result).toStrictEqual({ code: rpcCodes.methodNotFound, message: 'foo', - data: { originalError: Object.assign({}, invalidError2) }, + data: { cause: Object.assign({}, invalidError2) }, }); }); @@ -145,10 +162,8 @@ describe('serializeError', () => { }); }); - it('handles valid error: message, data, and stack', () => { - const result = serializeError( - Object.assign({}, validError1, { stack: 'foo' }), - ); + it('handles valid error: message and data', () => { + const result = serializeError(Object.assign({}, validError1)); expect(result).toStrictEqual({ code: 4001, message: validError1.message, @@ -157,7 +172,7 @@ describe('serializeError', () => { }); it('handles including stack: no stack present', () => { - const result = serializeError(validError1, { shouldIncludeStack: true }); + const result = serializeError(validError1); expect(result).toStrictEqual({ code: 4001, message: validError1.message, @@ -168,7 +183,6 @@ describe('serializeError', () => { it('handles including stack: string stack present', () => { const result = serializeError( Object.assign({}, validError1, { stack: 'foo' }), - { shouldIncludeStack: true }, ); expect(result).toStrictEqual({ code: 4001, @@ -178,12 +192,10 @@ describe('serializeError', () => { }); }); - it('handles including stack: non-string stack present', () => { + it('handles removing stack', () => { const result = serializeError( - Object.assign({}, validError1, { stack: 2 }), - { - shouldIncludeStack: true, - }, + Object.assign({}, validError1, { stack: 'foo' }), + { shouldIncludeStack: false }, ); expect(result).toStrictEqual({ code: 4001, @@ -191,4 +203,110 @@ describe('serializeError', () => { data: Object.assign({}, validError1.data), }); }); + + it('handles regular Error()', () => { + const error = new Error('foo'); + const result = serializeError(error); + expect(result).toStrictEqual({ + code: errorCodes.rpc.internal, + message: getMessageFromCode(errorCodes.rpc.internal), + data: { + cause: { + message: error.message, + stack: error.stack, + }, + }, + }); + + expect(JSON.parse(JSON.stringify(result))).toStrictEqual({ + code: errorCodes.rpc.internal, + message: getMessageFromCode(errorCodes.rpc.internal), + data: { + cause: { + message: error.message, + stack: error.stack, + }, + }, + }); + }); + + it('handles EthereumRpcError', () => { + const error = ethErrors.rpc.invalidParams(); + const result = serializeError(error); + expect(result).toStrictEqual({ + code: error.code, + message: error.message, + stack: error.stack, + }); + + expect(JSON.parse(JSON.stringify(result))).toStrictEqual({ + code: error.code, + message: error.message, + stack: error.stack, + }); + }); + + it('handles class that has serialize function', () => { + class MockClass { + serialize() { + return { code: 1, message: 'foo' }; + } + } + const error = new MockClass(); + const result = serializeError(error); + expect(result).toStrictEqual({ + code: 1, + message: 'foo', + }); + + expect(JSON.parse(JSON.stringify(result))).toStrictEqual({ + code: 1, + message: 'foo', + }); + }); + + it('removes non JSON-serializable props on cause', () => { + const error = new Error('foo'); + // @ts-expect-error Intentionally using wrong type + error.message = () => undefined; + const result = serializeError(error); + expect(result).toStrictEqual({ + code: errorCodes.rpc.internal, + message: getMessageFromCode(errorCodes.rpc.internal), + data: { + cause: { + stack: error.stack, + }, + }, + }); + }); + + it('throws if fallback is invalid', () => { + expect(() => + // @ts-expect-error Intentionally using wrong type + serializeError(new Error(), { fallbackError: new Error() }), + ).toThrow( + 'Must provide fallback error with integer number code and string message.', + ); + }); + + it('handles arrays passed as error', () => { + const error = ['foo', Symbol('bar'), { baz: 'qux', symbol: Symbol('') }]; + const result = serializeError(error); + expect(result).toStrictEqual({ + code: rpcCodes.internal, + message: getMessageFromCode(rpcCodes.internal), + data: { + cause: ['foo', null, { baz: 'qux' }], + }, + }); + + expect(JSON.parse(JSON.stringify(result))).toStrictEqual({ + code: rpcCodes.internal, + message: getMessageFromCode(rpcCodes.internal), + data: { + cause: ['foo', null, { baz: 'qux' }], + }, + }); + }); }); diff --git a/src/utils.ts b/src/utils.ts index 6a1dd71..1c27119 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,11 +1,18 @@ -import { hasProperty, isPlainObject, Json } from '@metamask/utils'; +import { + hasProperty, + isValidJson, + isObject, + isJsonRpcError, + Json, + JsonRpcError, + RuntimeObject, +} from '@metamask/utils'; import { errorCodes, errorValues } from './error-constants'; -import { EthereumRpcError, SerializedEthereumRpcError } from './classes'; const FALLBACK_ERROR_CODE = errorCodes.rpc.internal; const FALLBACK_MESSAGE = 'Unspecified error message. This is a bug, please report it.'; -const FALLBACK_ERROR: SerializedEthereumRpcError = { +const FALLBACK_ERROR: JsonRpcError = { code: FALLBACK_ERROR_CODE, message: getMessageFromCode(FALLBACK_ERROR_CODE), }; @@ -25,10 +32,10 @@ type ErrorValueKey = keyof typeof errorValues; * has no corresponding message. */ export function getMessageFromCode( - code: number, + code: unknown, fallbackMessage: string = FALLBACK_MESSAGE, ): string { - if (Number.isInteger(code)) { + if (isValidCode(code)) { const codeString = code.toString(); if (hasProperty(errorValues, codeString)) { @@ -44,103 +51,77 @@ export function getMessageFromCode( /** * Returns whether the given code is valid. - * A code is only valid if it has a message. + * A code is valid if it is an integer. * * @param code - The error code. * @returns Whether the given code is valid. */ -export function isValidCode(code: number): boolean { - if (!Number.isInteger(code)) { - return false; - } - - const codeString = code.toString(); - if (errorValues[codeString as ErrorValueKey]) { - return true; - } - - if (isJsonRpcServerError(code)) { - return true; - } - - return false; +export function isValidCode(code: unknown): code is number { + return Number.isInteger(code); } /** * Serializes the given error to an Ethereum JSON RPC-compatible error object. - * Merely copies the given error's values if it is already compatible. * If the given error is not fully compatible, it will be preserved on the - * returned object's data.originalError property. + * returned object's data.cause property. * * @param error - The error to serialize. * @param options - Options bag. * @param options.fallbackError - The error to return if the given error is - * not compatible. + * not compatible. Should be a JSON serializable value. * @param options.shouldIncludeStack - Whether to include the error's stack * on the returned object. * @returns The serialized error. */ export function serializeError( error: unknown, - { fallbackError = FALLBACK_ERROR, shouldIncludeStack = false } = {}, -): SerializedEthereumRpcError { - if ( - !fallbackError || - !Number.isInteger(fallbackError.code) || - typeof fallbackError.message !== 'string' - ) { + { fallbackError = FALLBACK_ERROR, shouldIncludeStack = true } = {}, +): JsonRpcError { + if (!isJsonRpcError(fallbackError)) { throw new Error( 'Must provide fallback error with integer number code and string message.', ); } - if (error instanceof EthereumRpcError) { - return error.serialize(); + const serialized = buildError(error, fallbackError); + + if (!shouldIncludeStack) { + delete serialized.stack; } - const serialized: Partial = {}; + return serialized; +} +/** + * Construct a JSON-serializable object given an error and a JSON serializable `fallbackError` + * + * @param error - The error in question. + * @param fallbackError - A JSON serializable fallback error. + * @returns A JSON serializable error object. + */ +function buildError(error: unknown, fallbackError: JsonRpcError): JsonRpcError { + // If an error specifies a `serialize` function, we call it and return the result. if ( error && - isPlainObject(error) && - hasProperty(error, 'code') && - isValidCode((error as SerializedEthereumRpcError).code) + typeof error === 'object' && + 'serialize' in error && + typeof error.serialize === 'function' ) { - const _error = error as Partial; - serialized.code = _error.code as number; - - if (_error.message && typeof _error.message === 'string') { - serialized.message = _error.message; - - if (hasProperty(_error, 'data')) { - serialized.data = _error.data ?? null; - } - } else { - serialized.message = getMessageFromCode( - (serialized as SerializedEthereumRpcError).code, - ); - - // TODO: Verify that the original error is serializable. - serialized.data = { originalError: assignOriginalError(error) } as Json; - } - } else { - serialized.code = fallbackError.code; - - const message = (error as any)?.message; - - serialized.message = - message && typeof message === 'string' ? message : fallbackError.message; + return error.serialize(); + } - // TODO: Verify that the original error is serializable. - serialized.data = { originalError: assignOriginalError(error) } as Json; + if (isJsonRpcError(error)) { + return error; } - const stack = (error as any)?.stack; + // If the error does not match the JsonRpcError type, use the fallback error, but try to include the original error as `cause`. + const cause = serializeCause(error); + const fallbackWithCause = { + ...fallbackError, + data: { cause }, + }; - if (shouldIncludeStack && error && stack && typeof stack === 'string') { - serialized.stack = stack; - } - return serialized as SerializedEthereumRpcError; + return fallbackWithCause; } /** @@ -154,15 +135,48 @@ function isJsonRpcServerError(code: number): boolean { } /** - * Create a copy of the given value if it's an object, and not an array. + * Serializes an unknown error to be used as the `cause` in a fallback error. * - * @param error - The value to copy. - * @returns The copied value, or the original value if it's not an object. + * @param error - The unknown error. + * @returns A JSON-serializable object containing as much information about the original error as possible. */ -function assignOriginalError(error: unknown): unknown { - if (error && typeof error === 'object' && !Array.isArray(error)) { - return Object.assign({}, error); +function serializeCause(error: unknown): Json { + if (Array.isArray(error)) { + return error.map((entry) => { + if (isValidJson(entry)) { + return entry; + } else if (isObject(entry)) { + return serializeObject(entry); + } + return null; + }); + } else if (isObject(error)) { + return serializeObject(error); } - return error; + if (isValidJson(error)) { + return error; + } + + return null; +} + +/** + * Extracts all JSON-serializable properties from an object. + * + * @param object - The object in question. + * @returns An object containing all the JSON-serializable properties. + */ +function serializeObject(object: RuntimeObject): Json { + return Object.getOwnPropertyNames(object).reduce>( + (acc, key) => { + const value = object[key]; + if (isValidJson(value)) { + acc[key] = value; + } + + return acc; + }, + {}, + ); } diff --git a/yarn.lock b/yarn.lock index 99257e6..a81a952 100644 --- a/yarn.lock +++ b/yarn.lock @@ -397,6 +397,33 @@ __metadata: languageName: node linkType: hard +"@chainsafe/as-sha256@npm:^0.3.1": + version: 0.3.1 + resolution: "@chainsafe/as-sha256@npm:0.3.1" + checksum: 58ea733be1657b0e31dbf48b0dba862da0833df34a81c1460c7352f04ce90874f70003cbf34d0afb9e5e53a33ee2d63a261a8b12462be85b2ba0a6f7f13d6150 + languageName: node + linkType: hard + +"@chainsafe/persistent-merkle-tree@npm:^0.4.2": + version: 0.4.2 + resolution: "@chainsafe/persistent-merkle-tree@npm:0.4.2" + dependencies: + "@chainsafe/as-sha256": ^0.3.1 + checksum: f9cfcb2132a243992709715dbd28186ab48c7c0c696f29d30857693cca5526bf753974a505ef68ffd5623bbdbcaa10f9083f4dd40bf99eb6408e451cc26a1a9e + languageName: node + linkType: hard + +"@chainsafe/ssz@npm:0.9.4": + version: 0.9.4 + resolution: "@chainsafe/ssz@npm:0.9.4" + dependencies: + "@chainsafe/as-sha256": ^0.3.1 + "@chainsafe/persistent-merkle-tree": ^0.4.2 + case: ^1.6.3 + checksum: c6eaedeae9e5618b3c666ff4507a27647f665a8dcf17d5ca86da4ed4788c5a93868f256d0005467d184fdf35ec03f323517ec2e55ec42492d769540a2ec396bc + languageName: node + linkType: hard + "@es-joy/jsdoccomment@npm:~0.33.4": version: 0.33.4 resolution: "@es-joy/jsdoccomment@npm:0.33.4" @@ -425,6 +452,310 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/common@npm:^3.1.1": + version: 3.1.1 + resolution: "@ethereumjs/common@npm:3.1.1" + dependencies: + "@ethereumjs/util": ^8.0.5 + crc-32: ^1.2.0 + checksum: 58602dee9fbcf691dca111b4fd7fd5770f5e86d68012ce48fba396c7038afdca4fca273a9cf39f88cf6ea7b256603a4bd214e94e9d01361efbcd060460b78952 + languageName: node + linkType: hard + +"@ethereumjs/rlp@npm:^4.0.1": + version: 4.0.1 + resolution: "@ethereumjs/rlp@npm:4.0.1" + bin: + rlp: bin/rlp + checksum: 30db19c78faa2b6ff27275ab767646929207bb207f903f09eb3e4c273ce2738b45f3c82169ddacd67468b4f063d8d96035f2bf36f02b6b7e4d928eefe2e3ecbc + languageName: node + linkType: hard + +"@ethereumjs/tx@npm:^4.1.1": + version: 4.1.1 + resolution: "@ethereumjs/tx@npm:4.1.1" + dependencies: + "@chainsafe/ssz": 0.9.4 + "@ethereumjs/common": ^3.1.1 + "@ethereumjs/rlp": ^4.0.1 + "@ethereumjs/util": ^8.0.5 + "@ethersproject/providers": ^5.7.2 + ethereum-cryptography: ^1.1.2 + peerDependencies: + c-kzg: ^1.0.8 + peerDependenciesMeta: + c-kzg: + optional: true + checksum: 98897e79adf03ee90ed98c6a543e15e0b4e127bc5bc381d70cdcc76b111574205b94869c29d925ea9e30a98e5ef8b0f5597914359deb9db552017b2e78ef17a8 + languageName: node + linkType: hard + +"@ethereumjs/util@npm:^8.0.5": + version: 8.0.5 + resolution: "@ethereumjs/util@npm:8.0.5" + dependencies: + "@chainsafe/ssz": 0.9.4 + "@ethereumjs/rlp": ^4.0.1 + ethereum-cryptography: ^1.1.2 + checksum: 318386785295b4584289b1aa576d2621392b3a918d127890db62d3f74184f3377694dd9e951e19bfb9ab80e8dc9e38e180236cac2651dead26097d10963731f9 + languageName: node + linkType: hard + +"@ethersproject/abstract-provider@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/abstract-provider@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/networks": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/web": ^5.7.0 + checksum: 74cf4696245cf03bb7cc5b6cbf7b4b89dd9a79a1c4688126d214153a938126d4972d42c93182198653ce1de35f2a2cad68be40337d4774b3698a39b28f0228a8 + languageName: node + linkType: hard + +"@ethersproject/abstract-signer@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/abstract-signer@npm:5.7.0" + dependencies: + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + checksum: a823dac9cfb761e009851050ebebd5b229d1b1cc4a75b125c2da130ff37e8218208f7f9d1386f77407705b889b23d4a230ad67185f8872f083143e0073cbfbe3 + languageName: node + linkType: hard + +"@ethersproject/address@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/address@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + checksum: 64ea5ebea9cc0e845c413e6cb1e54e157dd9fc0dffb98e239d3a3efc8177f2ff798cd4e3206cf3660ee8faeb7bef1a47dc0ebef0d7b132c32e61e550c7d4c843 + languageName: node + linkType: hard + +"@ethersproject/base64@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/base64@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + checksum: 7dd5d734d623582f08f665434f53685041a3d3b334a0e96c0c8afa8bbcaab934d50e5b6b980e826a8fde8d353e0b18f11e61faf17468177274b8e7c69cd9742b + languageName: node + linkType: hard + +"@ethersproject/basex@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/basex@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + checksum: 326087b7e1f3787b5fe6cd1cf2b4b5abfafbc355a45e88e22e5e9d6c845b613ffc5301d629b28d5c4d5e2bfe9ec424e6782c804956dff79be05f0098cb5817de + languageName: node + linkType: hard + +"@ethersproject/bignumber@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/bignumber@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + bn.js: ^5.2.1 + checksum: 8c9a134b76f3feb4ec26a5a27379efb4e156b8fb2de0678a67788a91c7f4e30abe9d948638458e4b20f2e42380da0adacc7c9389d05fce070692edc6ae9b4904 + languageName: node + linkType: hard + +"@ethersproject/bytes@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/bytes@npm:5.7.0" + dependencies: + "@ethersproject/logger": ^5.7.0 + checksum: 66ad365ceaab5da1b23b72225c71dce472cf37737af5118181fa8ab7447d696bea15ca22e3a0e8836fdd8cfac161afe321a7c67d0dde96f9f645ddd759676621 + languageName: node + linkType: hard + +"@ethersproject/constants@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/constants@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + checksum: 6d4b1355747cce837b3e76ec3bde70e4732736f23b04f196f706ebfa5d4d9c2be50904a390d4d40ce77803b98d03d16a9b6898418e04ba63491933ce08c4ba8a + languageName: node + linkType: hard + +"@ethersproject/hash@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/hash@npm:5.7.0" + dependencies: + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/base64": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 6e9fa8d14eb08171cd32f17f98cc108ec2aeca74a427655f0d689c550fee0b22a83b3b400fad7fb3f41cf14d4111f87f170aa7905bcbcd1173a55f21b06262ef + languageName: node + linkType: hard + +"@ethersproject/keccak256@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/keccak256@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + js-sha3: 0.8.0 + checksum: ff70950d82203aab29ccda2553422cbac2e7a0c15c986bd20a69b13606ed8bb6e4fdd7b67b8d3b27d4f841e8222cbaccd33ed34be29f866fec7308f96ed244c6 + languageName: node + linkType: hard + +"@ethersproject/logger@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/logger@npm:5.7.0" + checksum: 075ab2f605f1fd0813f2e39c3308f77b44a67732b36e712d9bc085f22a84aac4da4f71b39bee50fe78da3e1c812673fadc41180c9970fe5e486e91ea17befe0d + languageName: node + linkType: hard + +"@ethersproject/networks@npm:^5.7.0": + version: 5.7.1 + resolution: "@ethersproject/networks@npm:5.7.1" + dependencies: + "@ethersproject/logger": ^5.7.0 + checksum: 0339f312304c17d9a0adce550edb825d4d2c8c9468c1634c44172c67a9ed256f594da62c4cda5c3837a0f28b7fabc03aca9b492f68ff1fdad337ee861b27bd5d + languageName: node + linkType: hard + +"@ethersproject/properties@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/properties@npm:5.7.0" + dependencies: + "@ethersproject/logger": ^5.7.0 + checksum: 6ab0ccf0c3aadc9221e0cdc5306ce6cd0df7f89f77d77bccdd1277182c9ead0202cd7521329ba3acde130820bf8af299e17cf567d0d497c736ee918207bbf59f + languageName: node + linkType: hard + +"@ethersproject/providers@npm:^5.7.2": + version: 5.7.2 + resolution: "@ethersproject/providers@npm:5.7.2" + dependencies: + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/base64": ^5.7.0 + "@ethersproject/basex": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/networks": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/random": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + "@ethersproject/sha2": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/web": ^5.7.0 + bech32: 1.1.4 + ws: 7.4.6 + checksum: 1754c731a5ca6782ae9677f4a9cd8b6246c4ef21a966c9a01b133750f3c578431ec43ec254e699969c4a0f87e84463ded50f96b415600aabd37d2056aee58c19 + languageName: node + linkType: hard + +"@ethersproject/random@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/random@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: 017829c91cff6c76470852855108115b0b52c611b6be817ed1948d56ba42d6677803ec2012aa5ae298a7660024156a64c11fcf544e235e239ab3f89f0fff7345 + languageName: node + linkType: hard + +"@ethersproject/rlp@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/rlp@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: bce165b0f7e68e4d091c9d3cf47b247cac33252df77a095ca4281d32d5eeaaa3695d9bc06b2b057c5015353a68df89f13a4a54a72e888e4beeabbe56b15dda6e + languageName: node + linkType: hard + +"@ethersproject/sha2@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/sha2@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + hash.js: 1.1.7 + checksum: 09321057c022effbff4cc2d9b9558228690b5dd916329d75c4b1ffe32ba3d24b480a367a7cc92d0f0c0b1c896814d03351ae4630e2f1f7160be2bcfbde435dbc + languageName: node + linkType: hard + +"@ethersproject/signing-key@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/signing-key@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + bn.js: ^5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + checksum: 8f8de09b0aac709683bbb49339bc0a4cd2f95598f3546436c65d6f3c3a847ffa98e06d35e9ed2b17d8030bd2f02db9b7bd2e11c5cf8a71aad4537487ab4cf03a + languageName: node + linkType: hard + +"@ethersproject/strings@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/strings@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: 5ff78693ae3fdf3cf23e1f6dc047a61e44c8197d2408c42719fef8cb7b7b3613a4eec88ac0ed1f9f5558c74fe0de7ae3195a29ca91a239c74b9f444d8e8b50df + languageName: node + linkType: hard + +"@ethersproject/transactions@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/transactions@npm:5.7.0" + dependencies: + "@ethersproject/address": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + "@ethersproject/signing-key": ^5.7.0 + checksum: a31b71996d2b283f68486241bff0d3ea3f1ba0e8f1322a8fffc239ccc4f4a7eb2ea9994b8fd2f093283fd75f87bae68171e01b6265261f821369aca319884a79 + languageName: node + linkType: hard + +"@ethersproject/web@npm:^5.7.0": + version: 5.7.1 + resolution: "@ethersproject/web@npm:5.7.1" + dependencies: + "@ethersproject/base64": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 7028c47103f82fd2e2c197ce0eecfacaa9180ffeec7de7845b1f4f9b19d84081b7a48227aaddde05a4aaa526af574a9a0ce01cc0fc75e3e371f84b38b5b16b2b + languageName: node + linkType: hard + "@gar/promisify@npm:^1.1.3": version: 1.1.3 resolution: "@gar/promisify@npm:1.1.3" @@ -894,7 +1225,7 @@ __metadata: "@metamask/eslint-config-jest": ^10.0.0 "@metamask/eslint-config-nodejs": ^10.0.0 "@metamask/eslint-config-typescript": ^10.0.0 - "@metamask/utils": ^3.2.0 + "@metamask/utils": ^5.0.0 "@types/jest": ^28.1.6 "@typescript-eslint/eslint-plugin": ^5.33.1 "@typescript-eslint/parser": ^5.33.1 @@ -913,19 +1244,34 @@ __metadata: prettier-plugin-packagejson: ^2.2.18 ts-jest: ^28.0.7 typedoc: ^0.23.19 - typescript: ~4.7.4 + typescript: ~4.9.5 languageName: unknown linkType: soft -"@metamask/utils@npm:^3.2.0": - version: 3.2.0 - resolution: "@metamask/utils@npm:3.2.0" +"@metamask/utils@npm:^5.0.0": + version: 5.0.0 + resolution: "@metamask/utils@npm:5.0.0" dependencies: + "@ethereumjs/tx": ^4.1.1 "@types/debug": ^4.1.7 debug: ^4.3.4 - fast-deep-equal: ^3.1.3 - superstruct: ^0.16.5 - checksum: 99adcbd273c69075628913259f8c3fb843291898eba813f4f5fe0bfc060ae5955e2c69e70e15b04156793f8d84edd077d1fac3f8c3927e067d0f311eef9d4469 + semver: ^7.3.8 + superstruct: ^1.0.3 + checksum: 34e39fc0bf28db5fe92676753de3291b05a517f8c81dbe332a4b6002739a58450a89fb2bddd85922a4f420affb1674604e6ad4627cdf052459e5371361ef7dd2 + languageName: node + linkType: hard + +"@noble/hashes@npm:1.2.0, @noble/hashes@npm:~1.2.0": + version: 1.2.0 + resolution: "@noble/hashes@npm:1.2.0" + checksum: 8ca080ce557b8f40fb2f78d3aedffd95825a415ac8e13d7ffe3643f8626a8c2d99a3e5975b555027ac24316d8b3c02a35b8358567c0c23af681e6573602aa434 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:~1.7.0": + version: 1.7.1 + resolution: "@noble/secp256k1@npm:1.7.1" + checksum: d2301f1f7690368d8409a3152450458f27e54df47e3f917292de3de82c298770890c2de7c967d237eff9c95b70af485389a9695f73eb05a43e2bd562d18b18cb languageName: node linkType: hard @@ -1004,6 +1350,34 @@ __metadata: languageName: node linkType: hard +"@scure/base@npm:~1.1.0": + version: 1.1.1 + resolution: "@scure/base@npm:1.1.1" + checksum: b4fc810b492693e7e8d0107313ac74c3646970c198bbe26d7332820886fa4f09441991023ec9aa3a2a51246b74409ab5ebae2e8ef148bbc253da79ac49130309 + languageName: node + linkType: hard + +"@scure/bip32@npm:1.1.5": + version: 1.1.5 + resolution: "@scure/bip32@npm:1.1.5" + dependencies: + "@noble/hashes": ~1.2.0 + "@noble/secp256k1": ~1.7.0 + "@scure/base": ~1.1.0 + checksum: b08494ab0d2b1efee7226d1b5100db5157ebea22a78bb87126982a76a186cb3048413e8be0ba2622d00d048a20acbba527af730de86c132a77de616eb9907a3b + languageName: node + linkType: hard + +"@scure/bip39@npm:1.1.1": + version: 1.1.1 + resolution: "@scure/bip39@npm:1.1.1" + dependencies: + "@noble/hashes": ~1.2.0 + "@scure/base": ~1.1.0 + checksum: fbb594c50696fa9c14e891d872f382e50a3f919b6c96c55ef2fb10c7102c546dafb8f099a62bd114c12a00525b595dcf7381846f383f0ddcedeaa6e210747d2f + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.24.1": version: 0.24.51 resolution: "@sinclair/typebox@npm:0.24.51" @@ -1675,6 +2049,27 @@ __metadata: languageName: node linkType: hard +"bech32@npm:1.1.4": + version: 1.1.4 + resolution: "bech32@npm:1.1.4" + checksum: 0e98db619191548390d6f09ff68b0253ba7ae6a55db93dfdbb070ba234c1fd3308c0606fbcc95fad50437227b10011e2698b89f0181f6e7f845c499bd14d0f4b + languageName: node + linkType: hard + +"bn.js@npm:^4.11.9": + version: 4.12.0 + resolution: "bn.js@npm:4.12.0" + checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 + languageName: node + linkType: hard + +"bn.js@npm:^5.2.1": + version: 5.2.1 + resolution: "bn.js@npm:5.2.1" + checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -1703,6 +2098,13 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 8a05c9f3c4b46572dec6ef71012b1946db6cae8c7bb60ccd4b7dd5a84655db49fe043ecc6272e7ef1f69dc53d6730b9e2a3a03a8310509a3d797a618cbee52be + languageName: node + linkType: hard + "browserslist@npm:^4.21.3": version: 4.21.4 resolution: "browserslist@npm:4.21.4" @@ -1806,6 +2208,13 @@ __metadata: languageName: node linkType: hard +"case@npm:^1.6.3": + version: 1.6.3 + resolution: "case@npm:1.6.3" + checksum: febe73278f910b0d28aab7efd6f51c235f9aa9e296148edb56dfb83fd58faa88308c30ce9a0122b6e53e0362c44f4407105bd5ef89c46860fc2b184e540fd68d + languageName: node + linkType: hard + "caseless@npm:~0.12.0": version: 0.12.0 resolution: "caseless@npm:0.12.0" @@ -2025,6 +2434,15 @@ __metadata: languageName: node linkType: hard +"crc-32@npm:^1.2.0": + version: 1.2.2 + resolution: "crc-32@npm:1.2.2" + bin: + crc32: bin/crc32.njs + checksum: ad2d0ad0cbd465b75dcaeeff0600f8195b686816ab5f3ba4c6e052a07f728c3e70df2e3ca9fd3d4484dc4ba70586e161ca5a2334ec8bf5a41bf022a6103ff243 + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -2199,6 +2617,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:6.5.4": + version: 6.5.4 + resolution: "elliptic@npm:6.5.4" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: d56d21fd04e97869f7ffcc92e18903b9f67f2d4637a23c860492fbbff5a3155fd9ca0184ce0c865dd6eb2487d234ce9551335c021c376cd2d3b7cb749c7d10f4 + languageName: node + linkType: hard + "emittery@npm:^0.10.2": version: 0.10.2 resolution: "emittery@npm:0.10.2" @@ -2628,6 +3061,18 @@ __metadata: languageName: node linkType: hard +"ethereum-cryptography@npm:^1.1.2": + version: 1.2.0 + resolution: "ethereum-cryptography@npm:1.2.0" + dependencies: + "@noble/hashes": 1.2.0 + "@noble/secp256k1": 1.7.1 + "@scure/bip32": 1.1.5 + "@scure/bip39": 1.1.1 + checksum: 97e8e8253cb9f5a9271bd0201c37609c451c890eb85883b9c564f14743c3d7c673287406c93bf5604307593ee298ad9a03983388b85c11ca61461b9fc1a4f2c7 + languageName: node + linkType: hard + "execa@npm:^5.0.0, execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -3167,6 +3612,27 @@ __metadata: languageName: node linkType: hard +"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: ^2.0.3 + minimalistic-assert: ^1.0.1 + checksum: e350096e659c62422b85fa508e4b3669017311aa4c49b74f19f8e1bc7f3a54a584fdfd45326d4964d6011f2b2d882e38bea775a96046f2a61b7779a979629d8f + languageName: node + linkType: hard + +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: ^1.0.3 + minimalistic-assert: ^1.0.0 + minimalistic-crypto-utils: ^1.0.1 + checksum: bd30b6a68d7f22d63f10e1888aee497d7c2c5c0bb469e66bbdac99f143904d1dfe95f8131f95b3e86c86dd239963c9d972fcbe147e7cffa00e55d18585c43fe0 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -3298,7 +3764,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -4047,6 +4513,13 @@ __metadata: languageName: node linkType: hard +"js-sha3@npm:0.8.0": + version: 0.8.0 + resolution: "js-sha3@npm:0.8.0" + checksum: 75df77c1fc266973f06cce8309ce010e9e9f07ec35ab12022ed29b7f0d9c8757f5a73e1b35aa24840dced0dea7059085aa143d817aea9e188e2a80d569d9adce + languageName: node + linkType: hard + "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -4372,6 +4845,20 @@ __metadata: languageName: node linkType: hard +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7 + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 6e8a0422b30039406efd4c440829ea8f988845db02a3299f372fceba56ffa94994a9c0f2fd70c17f9969eedfbd72f34b5070ead9656a34d3f71c0bd72583a0ed + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -5554,10 +6041,10 @@ __metadata: languageName: node linkType: hard -"superstruct@npm:^0.16.5": - version: 0.16.7 - resolution: "superstruct@npm:0.16.7" - checksum: c8c855ff6945da8a41048c6d236de7b1af5d4d9c31742b3ee54d65647c31597488620281f65e095d5efc9e2fbdaad529b8c8f2506c12569d428467c835a21477 +"superstruct@npm:^1.0.3": + version: 1.0.3 + resolution: "superstruct@npm:1.0.3" + checksum: 761790bb111e6e21ddd608299c252f3be35df543263a7ebbc004e840d01fcf8046794c274bcb351bdf3eae4600f79d317d085cdbb19ca05803a4361840cc9bb1 languageName: node linkType: hard @@ -5805,23 +6292,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~4.7.4": - version: 4.7.4 - resolution: "typescript@npm:4.7.4" +"typescript@npm:~4.9.5": + version: 4.9.5 + resolution: "typescript@npm:4.9.5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 5750181b1cd7e6482c4195825547e70f944114fb47e58e4aa7553e62f11b3f3173766aef9c281783edfd881f7b8299cf35e3ca8caebe73d8464528c907a164df + checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db languageName: node linkType: hard -"typescript@patch:typescript@~4.7.4#~builtin": - version: 4.7.4 - resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=701156" +"typescript@patch:typescript@~4.9.5#~builtin": + version: 4.9.5 + resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=701156" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 9096d8f6c16cb80ef3bf96fcbbd055bf1c4a43bd14f3b7be45a9fbe7ada46ec977f604d5feed3263b4f2aa7d4c7477ce5f9cd87de0d6feedec69a983f3a4f93e + checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20 languageName: node linkType: hard @@ -6007,6 +6494,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:7.4.6": + version: 7.4.6 + resolution: "ws@npm:7.4.6" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 3a990b32ed08c72070d5e8913e14dfcd831919205be52a3ff0b4cdd998c8d554f167c9df3841605cde8b11d607768cacab3e823c58c96a5c08c987e093eb767a + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8"