@metamask-previews/eth-json-rpc-middleware 21.0.0-preview-64d897d9 → 21.0.0-preview-fe4c2215

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +0 -3
  2. package/dist/block-cache.cjs +32 -41
  3. package/dist/block-cache.cjs.map +1 -1
  4. package/dist/block-cache.d.cts +3 -12
  5. package/dist/block-cache.d.cts.map +1 -1
  6. package/dist/block-cache.d.mts +3 -12
  7. package/dist/block-cache.d.mts.map +1 -1
  8. package/dist/block-cache.mjs +32 -41
  9. package/dist/block-cache.mjs.map +1 -1
  10. package/dist/block-ref-rewrite.cjs +8 -12
  11. package/dist/block-ref-rewrite.cjs.map +1 -1
  12. package/dist/block-ref-rewrite.d.cts +3 -3
  13. package/dist/block-ref-rewrite.d.cts.map +1 -1
  14. package/dist/block-ref-rewrite.d.mts +3 -3
  15. package/dist/block-ref-rewrite.d.mts.map +1 -1
  16. package/dist/block-ref-rewrite.mjs +8 -12
  17. package/dist/block-ref-rewrite.mjs.map +1 -1
  18. package/dist/block-ref.cjs +10 -17
  19. package/dist/block-ref.cjs.map +1 -1
  20. package/dist/block-ref.d.cts +3 -12
  21. package/dist/block-ref.d.cts.map +1 -1
  22. package/dist/block-ref.d.mts +3 -12
  23. package/dist/block-ref.d.mts.map +1 -1
  24. package/dist/block-ref.mjs +10 -17
  25. package/dist/block-ref.mjs.map +1 -1
  26. package/dist/block-tracker-inspector.cjs +25 -28
  27. package/dist/block-tracker-inspector.cjs.map +1 -1
  28. package/dist/block-tracker-inspector.d.cts +3 -3
  29. package/dist/block-tracker-inspector.d.cts.map +1 -1
  30. package/dist/block-tracker-inspector.d.mts +3 -3
  31. package/dist/block-tracker-inspector.d.mts.map +1 -1
  32. package/dist/block-tracker-inspector.mjs +25 -28
  33. package/dist/block-tracker-inspector.mjs.map +1 -1
  34. package/dist/fetch.cjs +12 -8
  35. package/dist/fetch.cjs.map +1 -1
  36. package/dist/fetch.d.cts +3 -5
  37. package/dist/fetch.d.cts.map +1 -1
  38. package/dist/fetch.d.mts +3 -5
  39. package/dist/fetch.d.mts.map +1 -1
  40. package/dist/fetch.mjs +12 -8
  41. package/dist/fetch.mjs.map +1 -1
  42. package/dist/inflight-cache.cjs +45 -61
  43. package/dist/inflight-cache.cjs.map +1 -1
  44. package/dist/inflight-cache.d.cts +3 -12
  45. package/dist/inflight-cache.d.cts.map +1 -1
  46. package/dist/inflight-cache.d.mts +3 -12
  47. package/dist/inflight-cache.d.mts.map +1 -1
  48. package/dist/inflight-cache.mjs +45 -61
  49. package/dist/inflight-cache.mjs.map +1 -1
  50. package/dist/methods/wallet-request-execution-permissions.cjs +9 -20
  51. package/dist/methods/wallet-request-execution-permissions.cjs.map +1 -1
  52. package/dist/methods/wallet-request-execution-permissions.d.cts +3 -14
  53. package/dist/methods/wallet-request-execution-permissions.d.cts.map +1 -1
  54. package/dist/methods/wallet-request-execution-permissions.d.mts +3 -14
  55. package/dist/methods/wallet-request-execution-permissions.d.mts.map +1 -1
  56. package/dist/methods/wallet-request-execution-permissions.mjs +7 -18
  57. package/dist/methods/wallet-request-execution-permissions.mjs.map +1 -1
  58. package/dist/methods/wallet-revoke-execution-permission.cjs +11 -23
  59. package/dist/methods/wallet-revoke-execution-permission.cjs.map +1 -1
  60. package/dist/methods/wallet-revoke-execution-permission.d.cts +5 -19
  61. package/dist/methods/wallet-revoke-execution-permission.d.cts.map +1 -1
  62. package/dist/methods/wallet-revoke-execution-permission.d.mts +5 -19
  63. package/dist/methods/wallet-revoke-execution-permission.d.mts.map +1 -1
  64. package/dist/methods/wallet-revoke-execution-permission.mjs +8 -20
  65. package/dist/methods/wallet-revoke-execution-permission.mjs.map +1 -1
  66. package/dist/providerAsMiddleware.cjs +1 -18
  67. package/dist/providerAsMiddleware.cjs.map +1 -1
  68. package/dist/providerAsMiddleware.d.cts +3 -18
  69. package/dist/providerAsMiddleware.d.cts.map +1 -1
  70. package/dist/providerAsMiddleware.d.mts +3 -18
  71. package/dist/providerAsMiddleware.d.mts.map +1 -1
  72. package/dist/providerAsMiddleware.mjs +0 -16
  73. package/dist/providerAsMiddleware.mjs.map +1 -1
  74. package/dist/retryOnEmpty.cjs +11 -8
  75. package/dist/retryOnEmpty.cjs.map +1 -1
  76. package/dist/retryOnEmpty.d.cts +3 -3
  77. package/dist/retryOnEmpty.d.cts.map +1 -1
  78. package/dist/retryOnEmpty.d.mts +3 -3
  79. package/dist/retryOnEmpty.d.mts.map +1 -1
  80. package/dist/retryOnEmpty.mjs +11 -8
  81. package/dist/retryOnEmpty.mjs.map +1 -1
  82. package/dist/types.cjs.map +1 -1
  83. package/dist/types.d.cts +5 -0
  84. package/dist/types.d.cts.map +1 -1
  85. package/dist/types.d.mts +5 -0
  86. package/dist/types.d.mts.map +1 -1
  87. package/dist/types.mjs.map +1 -1
  88. package/dist/utils/error.cjs +0 -7
  89. package/dist/utils/error.cjs.map +1 -1
  90. package/dist/utils/error.d.cts +0 -7
  91. package/dist/utils/error.d.cts.map +1 -1
  92. package/dist/utils/error.d.mts +0 -7
  93. package/dist/utils/error.d.mts.map +1 -1
  94. package/dist/utils/error.mjs +0 -7
  95. package/dist/utils/error.mjs.map +1 -1
  96. package/dist/utils/normalize.cjs +2 -7
  97. package/dist/utils/normalize.cjs.map +1 -1
  98. package/dist/utils/normalize.d.cts.map +1 -1
  99. package/dist/utils/normalize.d.mts.map +1 -1
  100. package/dist/utils/normalize.mjs +2 -7
  101. package/dist/utils/normalize.mjs.map +1 -1
  102. package/dist/utils/validation.cjs +2 -34
  103. package/dist/utils/validation.cjs.map +1 -1
  104. package/dist/utils/validation.d.cts +3 -29
  105. package/dist/utils/validation.d.cts.map +1 -1
  106. package/dist/utils/validation.d.mts +3 -29
  107. package/dist/utils/validation.d.mts.map +1 -1
  108. package/dist/utils/validation.mjs +2 -34
  109. package/dist/utils/validation.mjs.map +1 -1
  110. package/dist/wallet.cjs +92 -199
  111. package/dist/wallet.cjs.map +1 -1
  112. package/dist/wallet.d.cts +13 -40
  113. package/dist/wallet.d.cts.map +1 -1
  114. package/dist/wallet.d.mts +13 -40
  115. package/dist/wallet.d.mts.map +1 -1
  116. package/dist/wallet.mjs +93 -200
  117. package/dist/wallet.mjs.map +1 -1
  118. package/package.json +1 -4
@@ -1,4 +1,5 @@
1
- import { klona } from "klona";
1
+ import { createAsyncMiddleware } from "@metamask/json-rpc-engine";
2
+ import { klona } from "klona/full";
2
3
  import { projectLogger, createModuleLogger } from "./logging-utils.mjs";
3
4
  import { blockTagParamIndex } from "./utils/cache.mjs";
4
5
  import { isExecutionRevertedError } from "./utils/error.mjs";
@@ -28,15 +29,15 @@ export function createRetryOnEmptyMiddleware({ provider, blockTracker, } = {}) {
28
29
  if (!blockTracker) {
29
30
  throw Error('RetryOnEmptyMiddleware - mandatory "blockTracker" option is missing.');
30
31
  }
31
- return async ({ request, next }) => {
32
- const blockRefIndex = blockTagParamIndex(request.method);
32
+ return createAsyncMiddleware(async (req, res, next) => {
33
+ const blockRefIndex = blockTagParamIndex(req.method);
33
34
  // skip if method does not include blockRef
34
35
  if (blockRefIndex === undefined) {
35
36
  return next();
36
37
  }
37
38
  // skip if not exact block references
38
- let blockRef = Array.isArray(request.params) && request.params[blockRefIndex]
39
- ? request.params[blockRefIndex]
39
+ let blockRef = Array.isArray(req.params) && req.params[blockRefIndex]
40
+ ? req.params[blockRefIndex]
40
41
  : undefined;
41
42
  // omitted blockRef implies "latest"
42
43
  if (blockRef === undefined) {
@@ -61,7 +62,7 @@ export function createRetryOnEmptyMiddleware({ provider, blockTracker, } = {}) {
61
62
  }
62
63
  log('Requested block number %o is not higher than latest block number %o, trying request until non-empty response is received', blockRefNumber, latestBlockNumber);
63
64
  // create child request with specific block-ref
64
- const childRequest = klona(request);
65
+ const childRequest = klona(req);
65
66
  // attempt child request until non-empty response is received
66
67
  const childResult = await retry(10, async () => {
67
68
  log('Performing request %o', childRequest);
@@ -75,8 +76,10 @@ export function createRetryOnEmptyMiddleware({ provider, blockTracker, } = {}) {
75
76
  return attemptResult;
76
77
  });
77
78
  log('Copying result %o', childResult);
78
- return childResult;
79
- };
79
+ // copy child result onto original response
80
+ res.result = childResult;
81
+ return undefined;
82
+ });
80
83
  }
81
84
  /**
82
85
  * Retries an asynchronous function up to a maximum number of times.
@@ -1 +1 @@
1
- {"version":3,"file":"retryOnEmpty.mjs","sourceRoot":"","sources":["../src/retryOnEmpty.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine/v2';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\nimport { klona } from 'klona';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type { Block } from './types';\nimport { blockTagParamIndex } from './utils/cache';\nimport { isExecutionRevertedError } from './utils/error';\nimport { timeout } from './utils/timeout';\n\n//\n// RetryOnEmptyMiddleware will retry any request with an empty response that has\n// a numbered block reference at or lower than the blockTracker's latest block.\n// Its useful for dealing with load-balanced ethereum JSON RPC\n// nodes that are not always in sync with each other.\n//\n\nconst log = createModuleLogger(projectLogger, 'retry-on-empty');\n// empty values used to determine if a request should be retried\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [null, '\\u003cnil\\u003e'];\n\n/**\n * Creates a middleware that retries requests with empty responses.\n *\n * @param options - The options for the middleware.\n * @param options.provider - The provider to use.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createRetryOnEmptyMiddleware({\n provider,\n blockTracker,\n}: {\n provider?: InternalProvider;\n blockTracker?: PollingBlockTracker;\n} = {}): JsonRpcMiddleware<JsonRpcRequest, Json> {\n if (!provider) {\n throw Error(\n 'RetryOnEmptyMiddleware - mandatory \"provider\" option is missing.',\n );\n }\n\n if (!blockTracker) {\n throw Error(\n 'RetryOnEmptyMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return async ({ request, next }) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(\n request.method,\n );\n // skip if method does not include blockRef\n if (blockRefIndex === undefined) {\n return next();\n }\n // skip if not exact block references\n let blockRef: string | undefined =\n Array.isArray(request.params) && request.params[blockRefIndex]\n ? (request.params[blockRefIndex] as string)\n : undefined;\n // omitted blockRef implies \"latest\"\n if (blockRef === undefined) {\n blockRef = 'latest';\n }\n\n // skip if non-number block reference\n if (['latest', 'pending'].includes(blockRef)) {\n return next();\n }\n // skip if block refernce is not a valid number\n const blockRefNumber: number = Number.parseInt(blockRef.slice(2), 16);\n if (Number.isNaN(blockRefNumber)) {\n return next();\n }\n // lookup latest block\n const latestBlockNumberHex: string = await blockTracker.getLatestBlock();\n const latestBlockNumber: number = Number.parseInt(\n latestBlockNumberHex.slice(2),\n 16,\n );\n // skip if request block number is higher than current\n if (blockRefNumber > latestBlockNumber) {\n log(\n 'Requested block number %o is higher than latest block number %o, falling through to original request',\n blockRefNumber,\n latestBlockNumber,\n );\n return next();\n }\n\n log(\n 'Requested block number %o is not higher than latest block number %o, trying request until non-empty response is received',\n blockRefNumber,\n latestBlockNumber,\n );\n\n // create child request with specific block-ref\n const childRequest = klona(request);\n // attempt child request until non-empty response is received\n const childResult = await retry(10, async () => {\n log('Performing request %o', childRequest);\n const attemptResult = await provider.request<JsonRpcParams, Block>(\n childRequest,\n );\n log('Result is %o', attemptResult);\n // verify result\n const allEmptyValues: unknown[] = emptyValues;\n if (allEmptyValues.includes(attemptResult)) {\n throw new Error(\n `RetryOnEmptyMiddleware - empty result \"${JSON.stringify(\n attemptResult,\n )}\" for request \"${JSON.stringify(childRequest)}\"`,\n );\n }\n return attemptResult;\n });\n log('Copying result %o', childResult);\n return childResult;\n };\n}\n\n/**\n * Retries an asynchronous function up to a maximum number of times.\n *\n * @param maxRetries - The maximum number of retries.\n * @param asyncFn - The asynchronous function to retry.\n * @returns The result of the asynchronous function.\n */\nasync function retry<Result>(\n maxRetries: number,\n asyncFn: () => Promise<Result>,\n): Promise<Result> {\n for (let index = 0; index < maxRetries; index++) {\n try {\n return await asyncFn();\n } catch (err: unknown) {\n if (isExecutionRevertedError(err)) {\n throw err as unknown;\n }\n log('(call %i) Request failed, waiting 1s to retry again...', index + 1);\n await timeout(1000);\n }\n }\n log('Retries exhausted');\n throw new Error('RetryOnEmptyMiddleware - retries exhausted');\n}\n"]}
1
+ {"version":3,"file":"retryOnEmpty.mjs","sourceRoot":"","sources":["../src/retryOnEmpty.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PollingBlockTracker } from '@metamask/eth-block-tracker';\nimport type { InternalProvider } from '@metamask/eth-json-rpc-provider';\nimport type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type { Json, JsonRpcParams } from '@metamask/utils';\nimport { klona } from 'klona/full';\n\nimport { projectLogger, createModuleLogger } from './logging-utils';\nimport type { Block } from './types';\nimport { blockTagParamIndex } from './utils/cache';\nimport { isExecutionRevertedError } from './utils/error';\nimport { timeout } from './utils/timeout';\n\n//\n// RetryOnEmptyMiddleware will retry any request with an empty response that has\n// a numbered block reference at or lower than the blockTracker's latest block.\n// Its useful for dealing with load-balanced ethereum JSON RPC\n// nodes that are not always in sync with each other.\n//\n\nconst log = createModuleLogger(projectLogger, 'retry-on-empty');\n// empty values used to determine if a request should be retried\n// `<nil>` comes from https://github.com/ethereum/go-ethereum/issues/16925\nconst emptyValues = [null, '\\u003cnil\\u003e'];\n\n/**\n * Creates a middleware that retries requests with empty responses.\n *\n * @param options - The options for the middleware.\n * @param options.provider - The provider to use.\n * @param options.blockTracker - The block tracker to use.\n * @returns The middleware.\n */\nexport function createRetryOnEmptyMiddleware({\n provider,\n blockTracker,\n}: {\n provider?: InternalProvider;\n blockTracker?: PollingBlockTracker;\n} = {}): JsonRpcMiddleware<JsonRpcParams, Json> {\n if (!provider) {\n throw Error(\n 'RetryOnEmptyMiddleware - mandatory \"provider\" option is missing.',\n );\n }\n\n if (!blockTracker) {\n throw Error(\n 'RetryOnEmptyMiddleware - mandatory \"blockTracker\" option is missing.',\n );\n }\n\n return createAsyncMiddleware(async (req, res, next) => {\n const blockRefIndex: number | undefined = blockTagParamIndex(req.method);\n // skip if method does not include blockRef\n if (blockRefIndex === undefined) {\n return next();\n }\n // skip if not exact block references\n let blockRef: string | undefined =\n Array.isArray(req.params) && req.params[blockRefIndex]\n ? (req.params[blockRefIndex] as string)\n : undefined;\n // omitted blockRef implies \"latest\"\n if (blockRef === undefined) {\n blockRef = 'latest';\n }\n\n // skip if non-number block reference\n if (['latest', 'pending'].includes(blockRef)) {\n return next();\n }\n // skip if block refernce is not a valid number\n const blockRefNumber: number = Number.parseInt(blockRef.slice(2), 16);\n if (Number.isNaN(blockRefNumber)) {\n return next();\n }\n // lookup latest block\n const latestBlockNumberHex: string = await blockTracker.getLatestBlock();\n const latestBlockNumber: number = Number.parseInt(\n latestBlockNumberHex.slice(2),\n 16,\n );\n // skip if request block number is higher than current\n if (blockRefNumber > latestBlockNumber) {\n log(\n 'Requested block number %o is higher than latest block number %o, falling through to original request',\n blockRefNumber,\n latestBlockNumber,\n );\n return next();\n }\n\n log(\n 'Requested block number %o is not higher than latest block number %o, trying request until non-empty response is received',\n blockRefNumber,\n latestBlockNumber,\n );\n\n // create child request with specific block-ref\n const childRequest = klona(req);\n // attempt child request until non-empty response is received\n const childResult = await retry(10, async () => {\n log('Performing request %o', childRequest);\n const attemptResult = await provider.request<JsonRpcParams, Block>(\n childRequest,\n );\n log('Result is %o', attemptResult);\n // verify result\n const allEmptyValues: unknown[] = emptyValues;\n if (allEmptyValues.includes(attemptResult)) {\n throw new Error(\n `RetryOnEmptyMiddleware - empty result \"${JSON.stringify(\n attemptResult,\n )}\" for request \"${JSON.stringify(childRequest)}\"`,\n );\n }\n return attemptResult;\n });\n log('Copying result %o', childResult);\n // copy child result onto original response\n res.result = childResult;\n return undefined;\n });\n}\n\n/**\n * Retries an asynchronous function up to a maximum number of times.\n *\n * @param maxRetries - The maximum number of retries.\n * @param asyncFn - The asynchronous function to retry.\n * @returns The result of the asynchronous function.\n */\nasync function retry<Result>(\n maxRetries: number,\n asyncFn: () => Promise<Result>,\n): Promise<Result> {\n for (let index = 0; index < maxRetries; index++) {\n try {\n return await asyncFn();\n } catch (err: unknown) {\n if (isExecutionRevertedError(err)) {\n throw err as unknown;\n }\n log('(call %i) Request failed, waiting 1s to retry again...', index + 1);\n await timeout(1000);\n }\n }\n log('Retries exhausted');\n throw new Error('RetryOnEmptyMiddleware - retries exhausted');\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nexport type BlockData = string | string[];\n\nexport type Block = Record<string, BlockData>;\n\nexport type BlockCache = Record<string, Block>;\n\nexport type Cache = Record<number, BlockCache>;\n\n/**\n * A copy of the `AbstractRpcService` type in metamask/network-controller`, but\n * keeping only the `request` method.\n *\n * We cannot get `AbstractRpcService` directly from\n * `@metamask/network-controller` because relying on this package would create a\n * circular dependency.\n *\n * This type should be accurate as of `@metamask/network-controller` 24.x and\n * `@metamask/utils` 11.x.\n */\nexport type AbstractRpcServiceLike = {\n request: <Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: RequestInit,\n ) => Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nexport type JsonRpcRequestToCache<Params extends JsonRpcParams> =\n JsonRpcRequest<Params> & {\n skipCache?: boolean;\n };\n\nexport type JsonRpcCacheMiddleware<\n Params extends JsonRpcParams,\n Result extends Json,\n> =\n JsonRpcMiddleware<Params, Result> extends (\n req: JsonRpcRequest<Params>,\n ...args: infer X\n ) => infer Y\n ? (req: JsonRpcRequestToCache<Params>, ...args: X) => Y\n : never;\n\nexport type BlockData = string | string[];\n\nexport type Block = Record<string, BlockData>;\n\nexport type BlockCache = Record<string, Block>;\n\nexport type Cache = Record<number, BlockCache>;\n\n/**\n * A copy of the `AbstractRpcService` type in metamask/network-controller`, but\n * keeping only the `request` method.\n *\n * We cannot get `AbstractRpcService` directly from\n * `@metamask/network-controller` because relying on this package would create a\n * circular dependency.\n *\n * This type should be accurate as of `@metamask/network-controller` 24.x and\n * `@metamask/utils` 11.x.\n */\nexport type AbstractRpcServiceLike = {\n request: <Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: RequestInit,\n ) => Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
package/dist/types.d.cts CHANGED
@@ -1,4 +1,9 @@
1
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
1
2
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ export type JsonRpcRequestToCache<Params extends JsonRpcParams> = JsonRpcRequest<Params> & {
4
+ skipCache?: boolean;
5
+ };
6
+ export type JsonRpcCacheMiddleware<Params extends JsonRpcParams, Result extends Json> = JsonRpcMiddleware<Params, Result> extends (req: JsonRpcRequest<Params>, ...args: infer X) => infer Y ? (req: JsonRpcRequestToCache<Params>, ...args: X) => Y : never;
2
7
  export type BlockData = string | string[];
3
8
  export type Block = Record<string, BlockData>;
4
9
  export type BlockCache = Record<string, Block>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACzD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,WAAW,KACvB,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC9C,CAAC"}
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AACnE,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,MAAM,MAAM,qBAAqB,CAAC,MAAM,SAAS,aAAa,IAC5D,cAAc,CAAC,MAAM,CAAC,GAAG;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ,MAAM,MAAM,sBAAsB,CAChC,MAAM,SAAS,aAAa,EAC5B,MAAM,SAAS,IAAI,IAEnB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CACxC,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,EAC3B,GAAG,IAAI,EAAE,MAAM,CAAC,KACb,MAAM,CAAC,GACR,CAAC,GAAG,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,GACrD,KAAK,CAAC;AAEZ,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACzD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,WAAW,KACvB,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC9C,CAAC"}
package/dist/types.d.mts CHANGED
@@ -1,4 +1,9 @@
1
+ import type { JsonRpcMiddleware } from "@metamask/json-rpc-engine";
1
2
  import type { Json, JsonRpcParams, JsonRpcRequest, JsonRpcResponse } from "@metamask/utils";
3
+ export type JsonRpcRequestToCache<Params extends JsonRpcParams> = JsonRpcRequest<Params> & {
4
+ skipCache?: boolean;
5
+ };
6
+ export type JsonRpcCacheMiddleware<Params extends JsonRpcParams, Result extends Json> = JsonRpcMiddleware<Params, Result> extends (req: JsonRpcRequest<Params>, ...args: infer X) => infer Y ? (req: JsonRpcRequestToCache<Params>, ...args: X) => Y : never;
2
7
  export type BlockData = string | string[];
3
8
  export type Block = Record<string, BlockData>;
4
9
  export type BlockCache = Record<string, Block>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACzD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,WAAW,KACvB,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC9C,CAAC"}
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kCAAkC;AACnE,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,cAAc,EACd,eAAe,EAChB,wBAAwB;AAEzB,MAAM,MAAM,qBAAqB,CAAC,MAAM,SAAS,aAAa,IAC5D,cAAc,CAAC,MAAM,CAAC,GAAG;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ,MAAM,MAAM,sBAAsB,CAChC,MAAM,SAAS,aAAa,EAC5B,MAAM,SAAS,IAAI,IAEnB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CACxC,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,EAC3B,GAAG,IAAI,EAAE,MAAM,CAAC,KACb,MAAM,CAAC,GACR,CAAC,GAAG,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,GACrD,KAAK,CAAC;AAEZ,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,CAAC,MAAM,SAAS,aAAa,EAAE,MAAM,SAAS,IAAI,EACzD,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,EACtC,YAAY,CAAC,EAAE,WAAW,KACvB,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC9C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nexport type BlockData = string | string[];\n\nexport type Block = Record<string, BlockData>;\n\nexport type BlockCache = Record<string, Block>;\n\nexport type Cache = Record<number, BlockCache>;\n\n/**\n * A copy of the `AbstractRpcService` type in metamask/network-controller`, but\n * keeping only the `request` method.\n *\n * We cannot get `AbstractRpcService` directly from\n * `@metamask/network-controller` because relying on this package would create a\n * circular dependency.\n *\n * This type should be accurate as of `@metamask/network-controller` 24.x and\n * `@metamask/utils` 11.x.\n */\nexport type AbstractRpcServiceLike = {\n request: <Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: RequestInit,\n ) => Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n Json,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n} from '@metamask/utils';\n\nexport type JsonRpcRequestToCache<Params extends JsonRpcParams> =\n JsonRpcRequest<Params> & {\n skipCache?: boolean;\n };\n\nexport type JsonRpcCacheMiddleware<\n Params extends JsonRpcParams,\n Result extends Json,\n> =\n JsonRpcMiddleware<Params, Result> extends (\n req: JsonRpcRequest<Params>,\n ...args: infer X\n ) => infer Y\n ? (req: JsonRpcRequestToCache<Params>, ...args: X) => Y\n : never;\n\nexport type BlockData = string | string[];\n\nexport type Block = Record<string, BlockData>;\n\nexport type BlockCache = Record<string, Block>;\n\nexport type Cache = Record<number, BlockCache>;\n\n/**\n * A copy of the `AbstractRpcService` type in metamask/network-controller`, but\n * keeping only the `request` method.\n *\n * We cannot get `AbstractRpcService` directly from\n * `@metamask/network-controller` because relying on this package would create a\n * circular dependency.\n *\n * This type should be accurate as of `@metamask/network-controller` 24.x and\n * `@metamask/utils` 11.x.\n */\nexport type AbstractRpcServiceLike = {\n request: <Params extends JsonRpcParams, Result extends Json>(\n jsonRpcRequest: JsonRpcRequest<Params>,\n fetchOptions?: RequestInit,\n ) => Promise<JsonRpcResponse<Result | null>>;\n};\n"]}
@@ -3,13 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isExecutionRevertedError = void 0;
4
4
  const rpc_errors_1 = require("@metamask/rpc-errors");
5
5
  const utils_1 = require("@metamask/utils");
6
- /**
7
- * Checks if a value is a JSON-RPC error that indicates an execution reverted error.
8
- *
9
- * @param error - The value to check.
10
- * @returns True if the value is a JSON-RPC error that indicates an execution reverted
11
- * error, false otherwise.
12
- */
13
6
  function isExecutionRevertedError(error) {
14
7
  return ((0, utils_1.isJsonRpcError)(error) &&
15
8
  error.code === rpc_errors_1.errorCodes.rpc.invalidInput &&
@@ -1 +1 @@
1
- {"version":3,"file":"error.cjs","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAClD,2CAAiD;AAGjD;;;;;;GAMG;AACH,SAAgB,wBAAwB,CACtC,KAAc;IAEd,OAAO,CACL,IAAA,sBAAc,EAAC,KAAK,CAAC;QACrB,KAAK,CAAC,IAAI,KAAK,uBAAU,CAAC,GAAG,CAAC,YAAY;QAC1C,KAAK,CAAC,OAAO,KAAK,oBAAoB,CACvC,CAAC;AACJ,CAAC;AARD,4DAQC","sourcesContent":["import { errorCodes } from '@metamask/rpc-errors';\nimport { isJsonRpcError } from '@metamask/utils';\nimport type { JsonRpcError } from '@metamask/utils';\n\n/**\n * Checks if a value is a JSON-RPC error that indicates an execution reverted error.\n *\n * @param error - The value to check.\n * @returns True if the value is a JSON-RPC error that indicates an execution reverted\n * error, false otherwise.\n */\nexport function isExecutionRevertedError(\n error: unknown,\n): error is JsonRpcError {\n return (\n isJsonRpcError(error) &&\n error.code === errorCodes.rpc.invalidInput &&\n error.message === 'execution reverted'\n );\n}\n"]}
1
+ {"version":3,"file":"error.cjs","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAClD,2CAAiD;AAGjD,SAAgB,wBAAwB,CACtC,KAAc;IAEd,OAAO,CACL,IAAA,sBAAc,EAAC,KAAK,CAAC;QACrB,KAAK,CAAC,IAAI,KAAK,uBAAU,CAAC,GAAG,CAAC,YAAY;QAC1C,KAAK,CAAC,OAAO,KAAK,oBAAoB,CACvC,CAAC;AACJ,CAAC;AARD,4DAQC","sourcesContent":["import { errorCodes } from '@metamask/rpc-errors';\nimport { isJsonRpcError } from '@metamask/utils';\nimport type { JsonRpcError } from '@metamask/utils';\n\nexport function isExecutionRevertedError(\n error: unknown,\n): error is JsonRpcError {\n return (\n isJsonRpcError(error) &&\n error.code === errorCodes.rpc.invalidInput &&\n error.message === 'execution reverted'\n );\n}\n"]}
@@ -1,10 +1,3 @@
1
1
  import type { JsonRpcError } from "@metamask/utils";
2
- /**
3
- * Checks if a value is a JSON-RPC error that indicates an execution reverted error.
4
- *
5
- * @param error - The value to check.
6
- * @returns True if the value is a JSON-RPC error that indicates an execution reverted
7
- * error, false otherwise.
8
- */
9
2
  export declare function isExecutionRevertedError(error: unknown): error is JsonRpcError;
10
3
  //# sourceMappingURL=error.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.cts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB;AAEpD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,YAAY,CAMvB"}
1
+ {"version":3,"file":"error.d.cts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB;AAEpD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,YAAY,CAMvB"}
@@ -1,10 +1,3 @@
1
1
  import type { JsonRpcError } from "@metamask/utils";
2
- /**
3
- * Checks if a value is a JSON-RPC error that indicates an execution reverted error.
4
- *
5
- * @param error - The value to check.
6
- * @returns True if the value is a JSON-RPC error that indicates an execution reverted
7
- * error, false otherwise.
8
- */
9
2
  export declare function isExecutionRevertedError(error: unknown): error is JsonRpcError;
10
3
  //# sourceMappingURL=error.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.mts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB;AAEpD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,YAAY,CAMvB"}
1
+ {"version":3,"file":"error.d.mts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,wBAAwB;AAEpD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,YAAY,CAMvB"}
@@ -1,12 +1,5 @@
1
1
  import { errorCodes } from "@metamask/rpc-errors";
2
2
  import { isJsonRpcError } from "@metamask/utils";
3
- /**
4
- * Checks if a value is a JSON-RPC error that indicates an execution reverted error.
5
- *
6
- * @param error - The value to check.
7
- * @returns True if the value is a JSON-RPC error that indicates an execution reverted
8
- * error, false otherwise.
9
- */
10
3
  export function isExecutionRevertedError(error) {
11
4
  return (isJsonRpcError(error) &&
12
5
  error.code === errorCodes.rpc.invalidInput &&
@@ -1 +1 @@
1
- {"version":3,"file":"error.mjs","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,6BAA6B;AAClD,OAAO,EAAE,cAAc,EAAE,wBAAwB;AAGjD;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAc;IAEd,OAAO,CACL,cAAc,CAAC,KAAK,CAAC;QACrB,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,CAAC,YAAY;QAC1C,KAAK,CAAC,OAAO,KAAK,oBAAoB,CACvC,CAAC;AACJ,CAAC","sourcesContent":["import { errorCodes } from '@metamask/rpc-errors';\nimport { isJsonRpcError } from '@metamask/utils';\nimport type { JsonRpcError } from '@metamask/utils';\n\n/**\n * Checks if a value is a JSON-RPC error that indicates an execution reverted error.\n *\n * @param error - The value to check.\n * @returns True if the value is a JSON-RPC error that indicates an execution reverted\n * error, false otherwise.\n */\nexport function isExecutionRevertedError(\n error: unknown,\n): error is JsonRpcError {\n return (\n isJsonRpcError(error) &&\n error.code === errorCodes.rpc.invalidInput &&\n error.message === 'execution reverted'\n );\n}\n"]}
1
+ {"version":3,"file":"error.mjs","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,6BAA6B;AAClD,OAAO,EAAE,cAAc,EAAE,wBAAwB;AAGjD,MAAM,UAAU,wBAAwB,CACtC,KAAc;IAEd,OAAO,CACL,cAAc,CAAC,KAAK,CAAC;QACrB,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,CAAC,YAAY;QAC1C,KAAK,CAAC,OAAO,KAAK,oBAAoB,CACvC,CAAC;AACJ,CAAC","sourcesContent":["import { errorCodes } from '@metamask/rpc-errors';\nimport { isJsonRpcError } from '@metamask/utils';\nimport type { JsonRpcError } from '@metamask/utils';\n\nexport function isExecutionRevertedError(\n error: unknown,\n): error is JsonRpcError {\n return (\n isJsonRpcError(error) &&\n error.code === errorCodes.rpc.invalidInput &&\n error.message === 'execution reverted'\n );\n}\n"]}
@@ -20,13 +20,8 @@ function normalizeTypedMessage(messageData) {
20
20
  if (!verifyingContract) {
21
21
  return messageData;
22
22
  }
23
- return JSON.stringify({
24
- ...data,
25
- domain: {
26
- ...data.domain,
27
- verifyingContract: normalizeContractAddress(verifyingContract),
28
- },
29
- });
23
+ data.domain.verifyingContract = normalizeContractAddress(verifyingContract);
24
+ return JSON.stringify(data);
30
25
  }
31
26
  exports.normalizeTypedMessage = normalizeTypedMessage;
32
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.cjs","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":";;;AAaA;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,WAAmB;IACvD,IAAI,IAAI,CAAC;IACT,IAAI;QACF,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;KACvC;IAAC,MAAM;QACN,yDAAyD;QACzD,OAAO,WAAW,CAAC;KACpB;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO,WAAW,CAAC;KACpB;IAED,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,GAAG,IAAI;QACP,MAAM,EAAE;YACN,GAAG,IAAI,CAAC,MAAM;YACd,iBAAiB,EAAE,wBAAwB,CAAC,iBAAiB,CAAC;SAC/D;KACF,CAAC,CAAC;AACL,CAAC;AAtBD,sDAsBC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwC,CAAC;AACjE,CAAC;AAND,8CAMC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAY;IAC5C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { Hex } from '@metamask/utils';\n\ntype EIP712Domain = {\n verifyingContract: Hex;\n};\n\ntype SignTypedMessageDataV3V4 = {\n types: Record<string, unknown>;\n domain: EIP712Domain;\n primaryType: string;\n message: unknown;\n};\n\n/**\n * Normalizes the messageData for the eth_signTypedData\n *\n * @param messageData - The messageData to normalize.\n * @returns The normalized messageData.\n */\nexport function normalizeTypedMessage(messageData: string) {\n let data;\n try {\n data = parseTypedMessage(messageData);\n } catch {\n // Ignore normalization errors and pass the message as is\n return messageData;\n }\n\n const { verifyingContract } = data.domain ?? {};\n\n if (!verifyingContract) {\n return messageData;\n }\n\n return JSON.stringify({\n ...data,\n domain: {\n ...data.domain,\n verifyingContract: normalizeContractAddress(verifyingContract),\n },\n });\n}\n\n/**\n * Parses the messageData to obtain the data object for EIP712 normalization\n *\n * @param data - The messageData to parse.\n * @returns The data object for EIP712 normalization.\n */\nexport function parseTypedMessage(data: string) {\n if (typeof data !== 'string') {\n return data;\n }\n\n return JSON.parse(data) as unknown as SignTypedMessageDataV3V4;\n}\n\n/**\n * Normalizes the address to standard hexadecimal format\n *\n * @param address - The address to normalize.\n * @returns The normalized address.\n */\nfunction normalizeContractAddress(address: Hex): Hex {\n if (address.startsWith('0X')) {\n return `0x${address.slice(2)}`;\n }\n return address;\n}\n"]}
1
+ {"version":3,"file":"normalize.cjs","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":";;;AAaA;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,WAAmB;IACvD,IAAI,IAAI,CAAC;IACT,IAAI;QACF,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;KACvC;IAAC,MAAM;QACN,yDAAyD;QACzD,OAAO,WAAW,CAAC;KACpB;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO,WAAW,CAAC;KACpB;IAED,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAE5E,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAlBD,sDAkBC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwC,CAAC;AACjE,CAAC;AAND,8CAMC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAY;IAC5C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { Hex } from '@metamask/utils';\n\ntype EIP712Domain = {\n verifyingContract: Hex;\n};\n\ntype SignTypedMessageDataV3V4 = {\n types: Record<string, unknown>;\n domain: EIP712Domain;\n primaryType: string;\n message: unknown;\n};\n\n/**\n * Normalizes the messageData for the eth_signTypedData\n *\n * @param messageData - The messageData to normalize.\n * @returns The normalized messageData.\n */\nexport function normalizeTypedMessage(messageData: string) {\n let data;\n try {\n data = parseTypedMessage(messageData);\n } catch {\n // Ignore normalization errors and pass the message as is\n return messageData;\n }\n\n const { verifyingContract } = data.domain ?? {};\n\n if (!verifyingContract) {\n return messageData;\n }\n\n data.domain.verifyingContract = normalizeContractAddress(verifyingContract);\n\n return JSON.stringify(data);\n}\n\n/**\n * Parses the messageData to obtain the data object for EIP712 normalization\n *\n * @param data - The messageData to parse.\n * @returns The data object for EIP712 normalization.\n */\nexport function parseTypedMessage(data: string) {\n if (typeof data !== 'string') {\n return data;\n }\n\n return JSON.parse(data) as unknown as SignTypedMessageDataV3V4;\n}\n\n/**\n * Normalizes the address to standard hexadecimal format\n *\n * @param address - The address to normalize.\n * @returns The normalized address.\n */\nfunction normalizeContractAddress(address: Hex): Hex {\n if (address.startsWith('0X')) {\n return `0x${address.slice(2)}`;\n }\n return address;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.cts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,UAsBxD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,4BAM7C"}
1
+ {"version":3,"file":"normalize.d.cts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,UAkBxD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,4BAM7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.mts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,UAsBxD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,4BAM7C"}
1
+ {"version":3,"file":"normalize.d.mts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,UAkBxD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,4BAM7C"}
@@ -17,13 +17,8 @@ export function normalizeTypedMessage(messageData) {
17
17
  if (!verifyingContract) {
18
18
  return messageData;
19
19
  }
20
- return JSON.stringify({
21
- ...data,
22
- domain: {
23
- ...data.domain,
24
- verifyingContract: normalizeContractAddress(verifyingContract),
25
- },
26
- });
20
+ data.domain.verifyingContract = normalizeContractAddress(verifyingContract);
21
+ return JSON.stringify(data);
27
22
  }
28
23
  /**
29
24
  * Parses the messageData to obtain the data object for EIP712 normalization
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.mjs","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAaA;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,IAAI,CAAC;IACT,IAAI;QACF,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;KACvC;IAAC,MAAM;QACN,yDAAyD;QACzD,OAAO,WAAW,CAAC;KACpB;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO,WAAW,CAAC;KACpB;IAED,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,GAAG,IAAI;QACP,MAAM,EAAE;YACN,GAAG,IAAI,CAAC,MAAM;YACd,iBAAiB,EAAE,wBAAwB,CAAC,iBAAiB,CAAC;SAC/D;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAY;IAC5C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { Hex } from '@metamask/utils';\n\ntype EIP712Domain = {\n verifyingContract: Hex;\n};\n\ntype SignTypedMessageDataV3V4 = {\n types: Record<string, unknown>;\n domain: EIP712Domain;\n primaryType: string;\n message: unknown;\n};\n\n/**\n * Normalizes the messageData for the eth_signTypedData\n *\n * @param messageData - The messageData to normalize.\n * @returns The normalized messageData.\n */\nexport function normalizeTypedMessage(messageData: string) {\n let data;\n try {\n data = parseTypedMessage(messageData);\n } catch {\n // Ignore normalization errors and pass the message as is\n return messageData;\n }\n\n const { verifyingContract } = data.domain ?? {};\n\n if (!verifyingContract) {\n return messageData;\n }\n\n return JSON.stringify({\n ...data,\n domain: {\n ...data.domain,\n verifyingContract: normalizeContractAddress(verifyingContract),\n },\n });\n}\n\n/**\n * Parses the messageData to obtain the data object for EIP712 normalization\n *\n * @param data - The messageData to parse.\n * @returns The data object for EIP712 normalization.\n */\nexport function parseTypedMessage(data: string) {\n if (typeof data !== 'string') {\n return data;\n }\n\n return JSON.parse(data) as unknown as SignTypedMessageDataV3V4;\n}\n\n/**\n * Normalizes the address to standard hexadecimal format\n *\n * @param address - The address to normalize.\n * @returns The normalized address.\n */\nfunction normalizeContractAddress(address: Hex): Hex {\n if (address.startsWith('0X')) {\n return `0x${address.slice(2)}`;\n }\n return address;\n}\n"]}
1
+ {"version":3,"file":"normalize.mjs","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAaA;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,IAAI,CAAC;IACT,IAAI;QACF,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;KACvC;IAAC,MAAM;QACN,yDAAyD;QACzD,OAAO,WAAW,CAAC;KACpB;IAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO,WAAW,CAAC;KACpB;IAED,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;IAE5E,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAY;IAC5C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type { Hex } from '@metamask/utils';\n\ntype EIP712Domain = {\n verifyingContract: Hex;\n};\n\ntype SignTypedMessageDataV3V4 = {\n types: Record<string, unknown>;\n domain: EIP712Domain;\n primaryType: string;\n message: unknown;\n};\n\n/**\n * Normalizes the messageData for the eth_signTypedData\n *\n * @param messageData - The messageData to normalize.\n * @returns The normalized messageData.\n */\nexport function normalizeTypedMessage(messageData: string) {\n let data;\n try {\n data = parseTypedMessage(messageData);\n } catch {\n // Ignore normalization errors and pass the message as is\n return messageData;\n }\n\n const { verifyingContract } = data.domain ?? {};\n\n if (!verifyingContract) {\n return messageData;\n }\n\n data.domain.verifyingContract = normalizeContractAddress(verifyingContract);\n\n return JSON.stringify(data);\n}\n\n/**\n * Parses the messageData to obtain the data object for EIP712 normalization\n *\n * @param data - The messageData to parse.\n * @returns The data object for EIP712 normalization.\n */\nexport function parseTypedMessage(data: string) {\n if (typeof data !== 'string') {\n return data;\n }\n\n return JSON.parse(data) as unknown as SignTypedMessageDataV3V4;\n}\n\n/**\n * Normalizes the address to standard hexadecimal format\n *\n * @param address - The address to normalize.\n * @returns The normalized address.\n */\nfunction normalizeContractAddress(address: Hex): Hex {\n if (address.startsWith('0X')) {\n return `0x${address.slice(2)}`;\n }\n return address;\n}\n"]}
@@ -3,24 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resemblesAddress = exports.validateParams = exports.validateAndNormalizeKeyholder = void 0;
4
4
  const rpc_errors_1 = require("@metamask/rpc-errors");
5
5
  const superstruct_1 = require("@metamask/superstruct");
6
- /**
7
- * Validates and normalizes a keyholder address for transaction- and
8
- * signature-related operations.
9
- *
10
- * @param address - The Ethereum address to validate and normalize.
11
- * @param context - The context of the request.
12
- * @param options - The options for the validation.
13
- * @param options.getAccounts - The function to get the accounts for the origin.
14
- * @returns The normalized address, if valid. Otherwise, throws
15
- * an error
16
- */
17
- async function validateAndNormalizeKeyholder(address, context, { getAccounts }) {
6
+ async function validateAndNormalizeKeyholder(address, req, { getAccounts }) {
18
7
  if (typeof address === 'string' &&
19
8
  address.length > 0 &&
20
9
  resemblesAddress(address)) {
21
10
  // Ensure that an "unauthorized" error is thrown if the requester
22
11
  // does not have the `eth_accounts` permission.
23
- const accounts = await getAccounts(context.assertGet('origin'));
12
+ const accounts = await getAccounts(req);
24
13
  const normalizedAccounts = accounts.map((_address) => _address.toLowerCase());
25
14
  const normalizedAddress = address.toLowerCase();
26
15
  if (normalizedAccounts.includes(normalizedAddress)) {
@@ -33,14 +22,6 @@ async function validateAndNormalizeKeyholder(address, context, { getAccounts })
33
22
  });
34
23
  }
35
24
  exports.validateAndNormalizeKeyholder = validateAndNormalizeKeyholder;
36
- /**
37
- * Validates the parameters of a request against a Superstruct schema.
38
- * Throws a JSON-RPC error if the parameters are invalid.
39
- *
40
- * @param value - The value to validate.
41
- * @param struct - The Superstruct schema to validate against.
42
- * @throws An error if the parameters are invalid.
43
- */
44
25
  function validateParams(value, struct) {
45
26
  const [error] = (0, superstruct_1.validate)(value, struct);
46
27
  if (error) {
@@ -48,24 +29,11 @@ function validateParams(value, struct) {
48
29
  }
49
30
  }
50
31
  exports.validateParams = validateParams;
51
- /**
52
- * Checks if a string resembles an Ethereum address.
53
- *
54
- * @param str - The string to check.
55
- * @returns True if the string resembles an Ethereum address, false otherwise.
56
- */
57
32
  function resemblesAddress(str) {
58
33
  // hex prefix 2 + 20 bytes
59
34
  return str.length === 2 + 20 * 2;
60
35
  }
61
36
  exports.resemblesAddress = resemblesAddress;
62
- /**
63
- * Formats a Superstruct validation error into a human-readable string.
64
- *
65
- * @param error - The Superstruct validation error.
66
- * @param message - The base error message to prepend to the formatted details.
67
- * @returns The formatted error.
68
- */
69
37
  function formatValidationError(error, message) {
70
38
  return `${message}\n\n${error
71
39
  .failures()
@@ -1 +1 @@
1
- {"version":3,"file":"validation.cjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":";;;AAAA,qDAAiE;AAEjE,uDAAiD;AAKjD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,6BAA6B,CACjD,OAAY,EACZ,OAAgC,EAChC,EAAE,WAAW,EAA0D;IAEvE,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,gBAAgB,CAAC,OAAO,CAAC,EACzB;QACA,iEAAiE;QACjE,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhE,MAAM,kBAAkB,GAAa,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC7D,QAAQ,CAAC,WAAW,EAAE,CACvB,CAAC;QAEF,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAS,CAAC;QAEvD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAClD,OAAO,iBAAiB,CAAC;SAC1B;QAED,MAAM,2BAAc,CAAC,YAAY,EAAE,CAAC;KACrC;IAED,MAAM,sBAAS,CAAC,aAAa,CAAC;QAC5B,OAAO,EAAE,uDAAuD;KACjE,CAAC,CAAC;AACL,CAAC;AA9BD,sEA8BC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,KAA2B,EAC3B,MAA0B;IAE1B,MAAM,CAAC,KAAK,CAAC,GAAG,IAAA,sBAAQ,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE;QACT,MAAM,sBAAS,CAAC,aAAa,CAC3B,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC/C,CAAC;KACH;AACH,CAAC;AAXD,wCAWC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,0BAA0B;IAC1B,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAHD,4CAGC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,KAAkB,EAAE,OAAe;IAChE,OAAO,GAAG,OAAO,OAAO,KAAK;SAC1B,QAAQ,EAAE;SACV,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CACxE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Struct, StructError } from '@metamask/superstruct';\nimport { validate } from '@metamask/superstruct';\nimport type { Hex } from '@metamask/utils';\n\nimport type { WalletMiddlewareContext } from '../wallet';\n\n/**\n * Validates and normalizes a keyholder address for transaction- and\n * signature-related operations.\n *\n * @param address - The Ethereum address to validate and normalize.\n * @param context - The context of the request.\n * @param options - The options for the validation.\n * @param options.getAccounts - The function to get the accounts for the origin.\n * @returns The normalized address, if valid. Otherwise, throws\n * an error\n */\nexport async function validateAndNormalizeKeyholder(\n address: Hex,\n context: WalletMiddlewareContext,\n { getAccounts }: { getAccounts: (origin: string) => Promise<string[]> },\n): Promise<Hex> {\n if (\n typeof address === 'string' &&\n address.length > 0 &&\n resemblesAddress(address)\n ) {\n // Ensure that an \"unauthorized\" error is thrown if the requester\n // does not have the `eth_accounts` permission.\n const accounts = await getAccounts(context.assertGet('origin'));\n\n const normalizedAccounts: string[] = accounts.map((_address) =>\n _address.toLowerCase(),\n );\n\n const normalizedAddress = address.toLowerCase() as Hex;\n\n if (normalizedAccounts.includes(normalizedAddress)) {\n return normalizedAddress;\n }\n\n throw providerErrors.unauthorized();\n }\n\n throw rpcErrors.invalidParams({\n message: `Invalid parameters: must provide an Ethereum address.`,\n });\n}\n\n/**\n * Validates the parameters of a request against a Superstruct schema.\n * Throws a JSON-RPC error if the parameters are invalid.\n *\n * @param value - The value to validate.\n * @param struct - The Superstruct schema to validate against.\n * @throws An error if the parameters are invalid.\n */\nexport function validateParams<ParamsType>(\n value: unknown | ParamsType,\n struct: Struct<ParamsType>,\n): asserts value is ParamsType {\n const [error] = validate(value, struct);\n\n if (error) {\n throw rpcErrors.invalidParams(\n formatValidationError(error, `Invalid params`),\n );\n }\n}\n\n/**\n * Checks if a string resembles an Ethereum address.\n *\n * @param str - The string to check.\n * @returns True if the string resembles an Ethereum address, false otherwise.\n */\nexport function resemblesAddress(str: string): boolean {\n // hex prefix 2 + 20 bytes\n return str.length === 2 + 20 * 2;\n}\n\n/**\n * Formats a Superstruct validation error into a human-readable string.\n *\n * @param error - The Superstruct validation error.\n * @param message - The base error message to prepend to the formatted details.\n * @returns The formatted error.\n */\nfunction formatValidationError(error: StructError, message: string): string {\n return `${message}\\n\\n${error\n .failures()\n .map(\n (f) => `${f.path.join(' > ')}${f.path.length ? ' - ' : ''}${f.message}`,\n )\n .join('\\n')}`;\n}\n"]}
1
+ {"version":3,"file":"validation.cjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":";;;AAAA,qDAAiE;AAEjE,uDAAiD;AAG1C,KAAK,UAAU,6BAA6B,CACjD,OAAY,EACZ,GAAmB,EACnB,EAAE,WAAW,EAA+D;IAE5E,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,gBAAgB,CAAC,OAAO,CAAC,EACzB;QACA,iEAAiE;QACjE,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAExC,MAAM,kBAAkB,GAAa,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC7D,QAAQ,CAAC,WAAW,EAAE,CACvB,CAAC;QAEF,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAS,CAAC;QAEvD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAClD,OAAO,iBAAiB,CAAC;SAC1B;QAED,MAAM,2BAAc,CAAC,YAAY,EAAE,CAAC;KACrC;IAED,MAAM,sBAAS,CAAC,aAAa,CAAC;QAC5B,OAAO,EAAE,uDAAuD;KACjE,CAAC,CAAC;AACL,CAAC;AA9BD,sEA8BC;AAED,SAAgB,cAAc,CAC5B,KAA2B,EAC3B,MAA0B;IAE1B,MAAM,CAAC,KAAK,CAAC,GAAG,IAAA,sBAAQ,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE;QACT,MAAM,sBAAS,CAAC,aAAa,CAC3B,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC/C,CAAC;KACH;AACH,CAAC;AAXD,wCAWC;AAED,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,0BAA0B;IAC1B,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAHD,4CAGC;AAED,SAAS,qBAAqB,CAAC,KAAkB,EAAE,OAAe;IAChE,OAAO,GAAG,OAAO,OAAO,KAAK;SAC1B,QAAQ,EAAE;SACV,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CACxE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Struct, StructError } from '@metamask/superstruct';\nimport { validate } from '@metamask/superstruct';\nimport type { Hex, JsonRpcRequest } from '@metamask/utils';\n\nexport async function validateAndNormalizeKeyholder(\n address: Hex,\n req: JsonRpcRequest,\n { getAccounts }: { getAccounts: (req: JsonRpcRequest) => Promise<string[]> },\n): Promise<Hex> {\n if (\n typeof address === 'string' &&\n address.length > 0 &&\n resemblesAddress(address)\n ) {\n // Ensure that an \"unauthorized\" error is thrown if the requester\n // does not have the `eth_accounts` permission.\n const accounts = await getAccounts(req);\n\n const normalizedAccounts: string[] = accounts.map((_address) =>\n _address.toLowerCase(),\n );\n\n const normalizedAddress = address.toLowerCase() as Hex;\n\n if (normalizedAccounts.includes(normalizedAddress)) {\n return normalizedAddress;\n }\n\n throw providerErrors.unauthorized();\n }\n\n throw rpcErrors.invalidParams({\n message: `Invalid parameters: must provide an Ethereum address.`,\n });\n}\n\nexport function validateParams<ParamsType>(\n value: unknown | ParamsType,\n struct: Struct<ParamsType>,\n): asserts value is ParamsType {\n const [error] = validate(value, struct);\n\n if (error) {\n throw rpcErrors.invalidParams(\n formatValidationError(error, `Invalid params`),\n );\n }\n}\n\nexport function resemblesAddress(str: string): boolean {\n // hex prefix 2 + 20 bytes\n return str.length === 2 + 20 * 2;\n}\n\nfunction formatValidationError(error: StructError, message: string): string {\n return `${message}\\n\\n${error\n .failures()\n .map(\n (f) => `${f.path.join(' > ')}${f.path.length ? ' - ' : ''}${f.message}`,\n )\n .join('\\n')}`;\n}\n"]}
@@ -1,34 +1,8 @@
1
1
  import type { Struct } from "@metamask/superstruct";
2
- import type { Hex } from "@metamask/utils";
3
- import type { WalletMiddlewareContext } from "../wallet.cjs";
4
- /**
5
- * Validates and normalizes a keyholder address for transaction- and
6
- * signature-related operations.
7
- *
8
- * @param address - The Ethereum address to validate and normalize.
9
- * @param context - The context of the request.
10
- * @param options - The options for the validation.
11
- * @param options.getAccounts - The function to get the accounts for the origin.
12
- * @returns The normalized address, if valid. Otherwise, throws
13
- * an error
14
- */
15
- export declare function validateAndNormalizeKeyholder(address: Hex, context: WalletMiddlewareContext, { getAccounts }: {
16
- getAccounts: (origin: string) => Promise<string[]>;
2
+ import type { Hex, JsonRpcRequest } from "@metamask/utils";
3
+ export declare function validateAndNormalizeKeyholder(address: Hex, req: JsonRpcRequest, { getAccounts }: {
4
+ getAccounts: (req: JsonRpcRequest) => Promise<string[]>;
17
5
  }): Promise<Hex>;
18
- /**
19
- * Validates the parameters of a request against a Superstruct schema.
20
- * Throws a JSON-RPC error if the parameters are invalid.
21
- *
22
- * @param value - The value to validate.
23
- * @param struct - The Superstruct schema to validate against.
24
- * @throws An error if the parameters are invalid.
25
- */
26
6
  export declare function validateParams<ParamsType>(value: unknown | ParamsType, struct: Struct<ParamsType>): asserts value is ParamsType;
27
- /**
28
- * Checks if a string resembles an Ethereum address.
29
- *
30
- * @param str - The string to check.
31
- * @returns True if the string resembles an Ethereum address, false otherwise.
32
- */
33
7
  export declare function resemblesAddress(str: string): boolean;
34
8
  //# sourceMappingURL=validation.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.cts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAe,8BAA8B;AAEjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,sBAAkB;AAEzD;;;;;;;;;;GAUG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,uBAAuB,EAChC,EAAE,WAAW,EAAE,EAAE;IAAE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GACtE,OAAO,CAAC,GAAG,CAAC,CA0Bd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EACvC,KAAK,EAAE,OAAO,GAAG,UAAU,EAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GACzB,OAAO,CAAC,KAAK,IAAI,UAAU,CAQ7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD"}
1
+ {"version":3,"file":"validation.d.cts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAe,8BAA8B;AAEjE,OAAO,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,wBAAwB;AAE3D,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,cAAc,EACnB,EAAE,WAAW,EAAE,EAAE;IAAE,WAAW,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAC3E,OAAO,CAAC,GAAG,CAAC,CA0Bd;AAED,wBAAgB,cAAc,CAAC,UAAU,EACvC,KAAK,EAAE,OAAO,GAAG,UAAU,EAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GACzB,OAAO,CAAC,KAAK,IAAI,UAAU,CAQ7B;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD"}
@@ -1,34 +1,8 @@
1
1
  import type { Struct } from "@metamask/superstruct";
2
- import type { Hex } from "@metamask/utils";
3
- import type { WalletMiddlewareContext } from "../wallet.mjs";
4
- /**
5
- * Validates and normalizes a keyholder address for transaction- and
6
- * signature-related operations.
7
- *
8
- * @param address - The Ethereum address to validate and normalize.
9
- * @param context - The context of the request.
10
- * @param options - The options for the validation.
11
- * @param options.getAccounts - The function to get the accounts for the origin.
12
- * @returns The normalized address, if valid. Otherwise, throws
13
- * an error
14
- */
15
- export declare function validateAndNormalizeKeyholder(address: Hex, context: WalletMiddlewareContext, { getAccounts }: {
16
- getAccounts: (origin: string) => Promise<string[]>;
2
+ import type { Hex, JsonRpcRequest } from "@metamask/utils";
3
+ export declare function validateAndNormalizeKeyholder(address: Hex, req: JsonRpcRequest, { getAccounts }: {
4
+ getAccounts: (req: JsonRpcRequest) => Promise<string[]>;
17
5
  }): Promise<Hex>;
18
- /**
19
- * Validates the parameters of a request against a Superstruct schema.
20
- * Throws a JSON-RPC error if the parameters are invalid.
21
- *
22
- * @param value - The value to validate.
23
- * @param struct - The Superstruct schema to validate against.
24
- * @throws An error if the parameters are invalid.
25
- */
26
6
  export declare function validateParams<ParamsType>(value: unknown | ParamsType, struct: Struct<ParamsType>): asserts value is ParamsType;
27
- /**
28
- * Checks if a string resembles an Ethereum address.
29
- *
30
- * @param str - The string to check.
31
- * @returns True if the string resembles an Ethereum address, false otherwise.
32
- */
33
7
  export declare function resemblesAddress(str: string): boolean;
34
8
  //# sourceMappingURL=validation.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.mts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAe,8BAA8B;AAEjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,sBAAkB;AAEzD;;;;;;;;;;GAUG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,uBAAuB,EAChC,EAAE,WAAW,EAAE,EAAE;IAAE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GACtE,OAAO,CAAC,GAAG,CAAC,CA0Bd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EACvC,KAAK,EAAE,OAAO,GAAG,UAAU,EAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GACzB,OAAO,CAAC,KAAK,IAAI,UAAU,CAQ7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD"}
1
+ {"version":3,"file":"validation.d.mts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAe,8BAA8B;AAEjE,OAAO,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,wBAAwB;AAE3D,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,cAAc,EACnB,EAAE,WAAW,EAAE,EAAE;IAAE,WAAW,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAC3E,OAAO,CAAC,GAAG,CAAC,CA0Bd;AAED,wBAAgB,cAAc,CAAC,UAAU,EACvC,KAAK,EAAE,OAAO,GAAG,UAAU,EAC3B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GACzB,OAAO,CAAC,KAAK,IAAI,UAAU,CAQ7B;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD"}
@@ -1,23 +1,12 @@
1
1
  import { providerErrors, rpcErrors } from "@metamask/rpc-errors";
2
2
  import { validate } from "@metamask/superstruct";
3
- /**
4
- * Validates and normalizes a keyholder address for transaction- and
5
- * signature-related operations.
6
- *
7
- * @param address - The Ethereum address to validate and normalize.
8
- * @param context - The context of the request.
9
- * @param options - The options for the validation.
10
- * @param options.getAccounts - The function to get the accounts for the origin.
11
- * @returns The normalized address, if valid. Otherwise, throws
12
- * an error
13
- */
14
- export async function validateAndNormalizeKeyholder(address, context, { getAccounts }) {
3
+ export async function validateAndNormalizeKeyholder(address, req, { getAccounts }) {
15
4
  if (typeof address === 'string' &&
16
5
  address.length > 0 &&
17
6
  resemblesAddress(address)) {
18
7
  // Ensure that an "unauthorized" error is thrown if the requester
19
8
  // does not have the `eth_accounts` permission.
20
- const accounts = await getAccounts(context.assertGet('origin'));
9
+ const accounts = await getAccounts(req);
21
10
  const normalizedAccounts = accounts.map((_address) => _address.toLowerCase());
22
11
  const normalizedAddress = address.toLowerCase();
23
12
  if (normalizedAccounts.includes(normalizedAddress)) {
@@ -29,37 +18,16 @@ export async function validateAndNormalizeKeyholder(address, context, { getAccou
29
18
  message: `Invalid parameters: must provide an Ethereum address.`,
30
19
  });
31
20
  }
32
- /**
33
- * Validates the parameters of a request against a Superstruct schema.
34
- * Throws a JSON-RPC error if the parameters are invalid.
35
- *
36
- * @param value - The value to validate.
37
- * @param struct - The Superstruct schema to validate against.
38
- * @throws An error if the parameters are invalid.
39
- */
40
21
  export function validateParams(value, struct) {
41
22
  const [error] = validate(value, struct);
42
23
  if (error) {
43
24
  throw rpcErrors.invalidParams(formatValidationError(error, `Invalid params`));
44
25
  }
45
26
  }
46
- /**
47
- * Checks if a string resembles an Ethereum address.
48
- *
49
- * @param str - The string to check.
50
- * @returns True if the string resembles an Ethereum address, false otherwise.
51
- */
52
27
  export function resemblesAddress(str) {
53
28
  // hex prefix 2 + 20 bytes
54
29
  return str.length === 2 + 20 * 2;
55
30
  }
56
- /**
57
- * Formats a Superstruct validation error into a human-readable string.
58
- *
59
- * @param error - The Superstruct validation error.
60
- * @param message - The base error message to prepend to the formatted details.
61
- * @returns The formatted error.
62
- */
63
31
  function formatValidationError(error, message) {
64
32
  return `${message}\n\n${error
65
33
  .failures()
@@ -1 +1 @@
1
- {"version":3,"file":"validation.mjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,6BAA6B;AAEjE,OAAO,EAAE,QAAQ,EAAE,8BAA8B;AAKjD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAY,EACZ,OAAgC,EAChC,EAAE,WAAW,EAA0D;IAEvE,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,gBAAgB,CAAC,OAAO,CAAC,EACzB;QACA,iEAAiE;QACjE,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhE,MAAM,kBAAkB,GAAa,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC7D,QAAQ,CAAC,WAAW,EAAE,CACvB,CAAC;QAEF,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAS,CAAC;QAEvD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAClD,OAAO,iBAAiB,CAAC;SAC1B;QAED,MAAM,cAAc,CAAC,YAAY,EAAE,CAAC;KACrC;IAED,MAAM,SAAS,CAAC,aAAa,CAAC;QAC5B,OAAO,EAAE,uDAAuD;KACjE,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,KAA2B,EAC3B,MAA0B;IAE1B,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE;QACT,MAAM,SAAS,CAAC,aAAa,CAC3B,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC/C,CAAC;KACH;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,0BAA0B;IAC1B,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,KAAkB,EAAE,OAAe;IAChE,OAAO,GAAG,OAAO,OAAO,KAAK;SAC1B,QAAQ,EAAE;SACV,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CACxE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Struct, StructError } from '@metamask/superstruct';\nimport { validate } from '@metamask/superstruct';\nimport type { Hex } from '@metamask/utils';\n\nimport type { WalletMiddlewareContext } from '../wallet';\n\n/**\n * Validates and normalizes a keyholder address for transaction- and\n * signature-related operations.\n *\n * @param address - The Ethereum address to validate and normalize.\n * @param context - The context of the request.\n * @param options - The options for the validation.\n * @param options.getAccounts - The function to get the accounts for the origin.\n * @returns The normalized address, if valid. Otherwise, throws\n * an error\n */\nexport async function validateAndNormalizeKeyholder(\n address: Hex,\n context: WalletMiddlewareContext,\n { getAccounts }: { getAccounts: (origin: string) => Promise<string[]> },\n): Promise<Hex> {\n if (\n typeof address === 'string' &&\n address.length > 0 &&\n resemblesAddress(address)\n ) {\n // Ensure that an \"unauthorized\" error is thrown if the requester\n // does not have the `eth_accounts` permission.\n const accounts = await getAccounts(context.assertGet('origin'));\n\n const normalizedAccounts: string[] = accounts.map((_address) =>\n _address.toLowerCase(),\n );\n\n const normalizedAddress = address.toLowerCase() as Hex;\n\n if (normalizedAccounts.includes(normalizedAddress)) {\n return normalizedAddress;\n }\n\n throw providerErrors.unauthorized();\n }\n\n throw rpcErrors.invalidParams({\n message: `Invalid parameters: must provide an Ethereum address.`,\n });\n}\n\n/**\n * Validates the parameters of a request against a Superstruct schema.\n * Throws a JSON-RPC error if the parameters are invalid.\n *\n * @param value - The value to validate.\n * @param struct - The Superstruct schema to validate against.\n * @throws An error if the parameters are invalid.\n */\nexport function validateParams<ParamsType>(\n value: unknown | ParamsType,\n struct: Struct<ParamsType>,\n): asserts value is ParamsType {\n const [error] = validate(value, struct);\n\n if (error) {\n throw rpcErrors.invalidParams(\n formatValidationError(error, `Invalid params`),\n );\n }\n}\n\n/**\n * Checks if a string resembles an Ethereum address.\n *\n * @param str - The string to check.\n * @returns True if the string resembles an Ethereum address, false otherwise.\n */\nexport function resemblesAddress(str: string): boolean {\n // hex prefix 2 + 20 bytes\n return str.length === 2 + 20 * 2;\n}\n\n/**\n * Formats a Superstruct validation error into a human-readable string.\n *\n * @param error - The Superstruct validation error.\n * @param message - The base error message to prepend to the formatted details.\n * @returns The formatted error.\n */\nfunction formatValidationError(error: StructError, message: string): string {\n return `${message}\\n\\n${error\n .failures()\n .map(\n (f) => `${f.path.join(' > ')}${f.path.length ? ' - ' : ''}${f.message}`,\n )\n .join('\\n')}`;\n}\n"]}
1
+ {"version":3,"file":"validation.mjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,6BAA6B;AAEjE,OAAO,EAAE,QAAQ,EAAE,8BAA8B;AAGjD,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAY,EACZ,GAAmB,EACnB,EAAE,WAAW,EAA+D;IAE5E,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,gBAAgB,CAAC,OAAO,CAAC,EACzB;QACA,iEAAiE;QACjE,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAExC,MAAM,kBAAkB,GAAa,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC7D,QAAQ,CAAC,WAAW,EAAE,CACvB,CAAC;QAEF,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAS,CAAC;QAEvD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAClD,OAAO,iBAAiB,CAAC;SAC1B;QAED,MAAM,cAAc,CAAC,YAAY,EAAE,CAAC;KACrC;IAED,MAAM,SAAS,CAAC,aAAa,CAAC;QAC5B,OAAO,EAAE,uDAAuD;KACjE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAA2B,EAC3B,MAA0B;IAE1B,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE;QACT,MAAM,SAAS,CAAC,aAAa,CAC3B,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAC/C,CAAC;KACH;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,0BAA0B;IAC1B,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAkB,EAAE,OAAe;IAChE,OAAO,GAAG,OAAO,OAAO,KAAK;SAC1B,QAAQ,EAAE;SACV,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CACxE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Struct, StructError } from '@metamask/superstruct';\nimport { validate } from '@metamask/superstruct';\nimport type { Hex, JsonRpcRequest } from '@metamask/utils';\n\nexport async function validateAndNormalizeKeyholder(\n address: Hex,\n req: JsonRpcRequest,\n { getAccounts }: { getAccounts: (req: JsonRpcRequest) => Promise<string[]> },\n): Promise<Hex> {\n if (\n typeof address === 'string' &&\n address.length > 0 &&\n resemblesAddress(address)\n ) {\n // Ensure that an \"unauthorized\" error is thrown if the requester\n // does not have the `eth_accounts` permission.\n const accounts = await getAccounts(req);\n\n const normalizedAccounts: string[] = accounts.map((_address) =>\n _address.toLowerCase(),\n );\n\n const normalizedAddress = address.toLowerCase() as Hex;\n\n if (normalizedAccounts.includes(normalizedAddress)) {\n return normalizedAddress;\n }\n\n throw providerErrors.unauthorized();\n }\n\n throw rpcErrors.invalidParams({\n message: `Invalid parameters: must provide an Ethereum address.`,\n });\n}\n\nexport function validateParams<ParamsType>(\n value: unknown | ParamsType,\n struct: Struct<ParamsType>,\n): asserts value is ParamsType {\n const [error] = validate(value, struct);\n\n if (error) {\n throw rpcErrors.invalidParams(\n formatValidationError(error, `Invalid params`),\n );\n }\n}\n\nexport function resemblesAddress(str: string): boolean {\n // hex prefix 2 + 20 bytes\n return str.length === 2 + 20 * 2;\n}\n\nfunction formatValidationError(error: StructError, message: string): string {\n return `${message}\\n\\n${error\n .failures()\n .map(\n (f) => `${f.path.join(' > ')}${f.path.length ? ' - ' : ''}${f.message}`,\n )\n .join('\\n')}`;\n}\n"]}