@metamask/snaps-rpc-methods 11.12.0 → 11.13.1

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 (124) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/dist/endowments/caveats/requestTime.cjs +1 -2
  3. package/dist/endowments/caveats/requestTime.cjs.map +1 -1
  4. package/dist/endowments/caveats/requestTime.mjs +1 -2
  5. package/dist/endowments/caveats/requestTime.mjs.map +1 -1
  6. package/dist/endowments/rpc.cjs.map +1 -1
  7. package/dist/endowments/rpc.d.cts.map +1 -1
  8. package/dist/endowments/rpc.d.mts.map +1 -1
  9. package/dist/endowments/rpc.mjs.map +1 -1
  10. package/dist/permitted/getState.cjs.map +1 -1
  11. package/dist/permitted/getState.d.cts +1 -1
  12. package/dist/permitted/getState.d.cts.map +1 -1
  13. package/dist/permitted/getState.d.mts +1 -1
  14. package/dist/permitted/getState.d.mts.map +1 -1
  15. package/dist/permitted/getState.mjs.map +1 -1
  16. package/dist/permitted/handlers.cjs +2 -0
  17. package/dist/permitted/handlers.cjs.map +1 -1
  18. package/dist/permitted/handlers.d.cts +2 -1
  19. package/dist/permitted/handlers.d.cts.map +1 -1
  20. package/dist/permitted/handlers.d.mts +2 -1
  21. package/dist/permitted/handlers.d.mts.map +1 -1
  22. package/dist/permitted/handlers.mjs +2 -0
  23. package/dist/permitted/handlers.mjs.map +1 -1
  24. package/dist/permitted/index.cjs.map +1 -1
  25. package/dist/permitted/index.d.cts +2 -1
  26. package/dist/permitted/index.d.cts.map +1 -1
  27. package/dist/permitted/index.d.mts +2 -1
  28. package/dist/permitted/index.d.mts.map +1 -1
  29. package/dist/permitted/index.mjs.map +1 -1
  30. package/dist/permitted/invokeKeyring.cjs.map +1 -1
  31. package/dist/permitted/invokeKeyring.d.cts.map +1 -1
  32. package/dist/permitted/invokeKeyring.d.mts.map +1 -1
  33. package/dist/permitted/invokeKeyring.mjs.map +1 -1
  34. package/dist/permitted/listEntropySources.cjs +53 -0
  35. package/dist/permitted/listEntropySources.cjs.map +1 -0
  36. package/dist/permitted/listEntropySources.d.cts +25 -0
  37. package/dist/permitted/listEntropySources.d.cts.map +1 -0
  38. package/dist/permitted/listEntropySources.d.mts +25 -0
  39. package/dist/permitted/listEntropySources.d.mts.map +1 -0
  40. package/dist/permitted/listEntropySources.mjs +50 -0
  41. package/dist/permitted/listEntropySources.mjs.map +1 -0
  42. package/dist/permitted/middleware.cjs +1 -1
  43. package/dist/permitted/middleware.cjs.map +1 -1
  44. package/dist/permitted/middleware.mjs +1 -1
  45. package/dist/permitted/middleware.mjs.map +1 -1
  46. package/dist/permitted/resolveInterface.cjs.map +1 -1
  47. package/dist/permitted/resolveInterface.d.cts +1 -1
  48. package/dist/permitted/resolveInterface.d.cts.map +1 -1
  49. package/dist/permitted/resolveInterface.d.mts +1 -1
  50. package/dist/permitted/resolveInterface.d.mts.map +1 -1
  51. package/dist/permitted/resolveInterface.mjs.map +1 -1
  52. package/dist/permitted/scheduleBackgroundEvent.cjs.map +1 -1
  53. package/dist/permitted/scheduleBackgroundEvent.d.cts +1 -2
  54. package/dist/permitted/scheduleBackgroundEvent.d.cts.map +1 -1
  55. package/dist/permitted/scheduleBackgroundEvent.d.mts +1 -2
  56. package/dist/permitted/scheduleBackgroundEvent.d.mts.map +1 -1
  57. package/dist/permitted/scheduleBackgroundEvent.mjs.map +1 -1
  58. package/dist/permitted/setState.cjs +1 -3
  59. package/dist/permitted/setState.cjs.map +1 -1
  60. package/dist/permitted/setState.d.cts +1 -1
  61. package/dist/permitted/setState.d.cts.map +1 -1
  62. package/dist/permitted/setState.d.mts +1 -1
  63. package/dist/permitted/setState.d.mts.map +1 -1
  64. package/dist/permitted/setState.mjs +1 -3
  65. package/dist/permitted/setState.mjs.map +1 -1
  66. package/dist/restricted/caveats/index.cjs +3 -3
  67. package/dist/restricted/caveats/index.cjs.map +1 -1
  68. package/dist/restricted/caveats/index.mjs +3 -3
  69. package/dist/restricted/caveats/index.mjs.map +1 -1
  70. package/dist/restricted/caveats/permittedCoinTypes.cjs +7 -0
  71. package/dist/restricted/caveats/permittedCoinTypes.cjs.map +1 -1
  72. package/dist/restricted/caveats/permittedCoinTypes.d.cts.map +1 -1
  73. package/dist/restricted/caveats/permittedCoinTypes.d.mts.map +1 -1
  74. package/dist/restricted/caveats/permittedCoinTypes.mjs +7 -0
  75. package/dist/restricted/caveats/permittedCoinTypes.mjs.map +1 -1
  76. package/dist/restricted/getBip32Entropy.cjs +2 -1
  77. package/dist/restricted/getBip32Entropy.cjs.map +1 -1
  78. package/dist/restricted/getBip32Entropy.d.cts +7 -2
  79. package/dist/restricted/getBip32Entropy.d.cts.map +1 -1
  80. package/dist/restricted/getBip32Entropy.d.mts +7 -2
  81. package/dist/restricted/getBip32Entropy.d.mts.map +1 -1
  82. package/dist/restricted/getBip32Entropy.mjs +3 -2
  83. package/dist/restricted/getBip32Entropy.mjs.map +1 -1
  84. package/dist/restricted/getBip32PublicKey.cjs +3 -1
  85. package/dist/restricted/getBip32PublicKey.cjs.map +1 -1
  86. package/dist/restricted/getBip32PublicKey.d.cts +9 -2
  87. package/dist/restricted/getBip32PublicKey.d.cts.map +1 -1
  88. package/dist/restricted/getBip32PublicKey.d.mts +9 -2
  89. package/dist/restricted/getBip32PublicKey.d.mts.map +1 -1
  90. package/dist/restricted/getBip32PublicKey.mjs +5 -3
  91. package/dist/restricted/getBip32PublicKey.mjs.map +1 -1
  92. package/dist/restricted/getBip44Entropy.cjs +3 -1
  93. package/dist/restricted/getBip44Entropy.cjs.map +1 -1
  94. package/dist/restricted/getBip44Entropy.d.cts +7 -2
  95. package/dist/restricted/getBip44Entropy.d.cts.map +1 -1
  96. package/dist/restricted/getBip44Entropy.d.mts +7 -2
  97. package/dist/restricted/getBip44Entropy.d.mts.map +1 -1
  98. package/dist/restricted/getBip44Entropy.mjs +3 -1
  99. package/dist/restricted/getBip44Entropy.mjs.map +1 -1
  100. package/dist/restricted/getEntropy.cjs +2 -1
  101. package/dist/restricted/getEntropy.cjs.map +1 -1
  102. package/dist/restricted/getEntropy.d.cts +9 -2
  103. package/dist/restricted/getEntropy.d.cts.map +1 -1
  104. package/dist/restricted/getEntropy.d.mts +9 -2
  105. package/dist/restricted/getEntropy.d.mts.map +1 -1
  106. package/dist/restricted/getEntropy.mjs +3 -2
  107. package/dist/restricted/getEntropy.mjs.map +1 -1
  108. package/dist/restricted/index.d.cts +2 -2
  109. package/dist/restricted/index.d.mts +2 -2
  110. package/dist/restricted/notify.cjs.map +1 -1
  111. package/dist/restricted/notify.d.cts +4 -14
  112. package/dist/restricted/notify.d.cts.map +1 -1
  113. package/dist/restricted/notify.d.mts +4 -14
  114. package/dist/restricted/notify.d.mts.map +1 -1
  115. package/dist/restricted/notify.mjs.map +1 -1
  116. package/dist/utils.cjs +29 -1
  117. package/dist/utils.cjs.map +1 -1
  118. package/dist/utils.d.cts +9 -0
  119. package/dist/utils.d.cts.map +1 -1
  120. package/dist/utils.d.mts +9 -0
  121. package/dist/utils.d.mts.map +1 -1
  122. package/dist/utils.mjs +27 -0
  123. package/dist/utils.mjs.map +1 -1
  124. package/package.json +8 -22
@@ -1 +1 @@
1
- {"version":3,"file":"setState.cjs","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { PermittedHandlerExport } from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { SetStateParams, SetStateResult } from '@metamask/snaps-sdk';\nimport type { JsonObject } from '@metamask/snaps-sdk/jsx';\nimport { type InferMatching } from '@metamask/snaps-utils';\nimport {\n boolean,\n create,\n object as objectStruct,\n optional,\n StructError,\n} from '@metamask/superstruct';\nimport type { PendingJsonRpcResponse, JsonRpcRequest } from '@metamask/utils';\nimport {\n getJsonSize,\n hasProperty,\n isObject,\n assert,\n JsonStruct,\n type Json,\n} from '@metamask/utils';\n\nimport {\n manageStateBuilder,\n STORAGE_SIZE_LIMIT,\n} from '../restricted/manageState';\nimport type { MethodHooksObject } from '../utils';\nimport { FORBIDDEN_KEYS, StateKeyStruct } from '../utils';\n\nconst hookNames: MethodHooksObject<SetStateHooks> = {\n hasPermission: true,\n getSnapState: true,\n getUnlockPromise: true,\n updateSnapState: true,\n};\n\n/**\n * `snap_setState` sets the state of the Snap.\n */\nexport const setStateHandler: PermittedHandlerExport<\n SetStateHooks,\n SetStateParameters,\n SetStateResult\n> = {\n methodNames: ['snap_setState'],\n implementation: setStateImplementation,\n hookNames,\n};\n\nexport type SetStateHooks = {\n /**\n * Check if the requesting origin has a given permission.\n *\n * @param permissionName - The name of the permission to check.\n * @returns Whether the origin has the permission.\n */\n hasPermission: (permissionName: string) => boolean;\n\n /**\n * Get the state of the requesting Snap.\n *\n * @param encrypted - Whether the state is encrypted.\n * @returns The current state of the Snap.\n */\n getSnapState: (encrypted: boolean) => Promise<Record<string, Json>>;\n\n /**\n * Wait for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Update the state of the requesting Snap.\n *\n * @param newState - The new state of the Snap.\n * @param encrypted - Whether the state should be encrypted.\n */\n updateSnapState: (\n newState: Record<string, Json>,\n encrypted: boolean,\n ) => Promise<void>;\n};\n\nconst SetStateParametersStruct = objectStruct({\n key: optional(StateKeyStruct),\n value: JsonStruct,\n encrypted: optional(boolean()),\n});\n\nexport type SetStateParameters = InferMatching<\n typeof SetStateParametersStruct,\n SetStateParams\n>;\n\n/**\n * The `snap_setState` method implementation.\n *\n * @param request - The JSON-RPC request object.\n * @param response - The JSON-RPC response object.\n * @param _next - The `json-rpc-engine` \"next\" callback. Not used by this\n * function.\n * @param end - The `json-rpc-engine` \"end\" callback.\n * @param hooks - The RPC method hooks.\n * @param hooks.hasPermission - Check whether a given origin has a given\n * permission.\n * @param hooks.getSnapState - Get the state of the requesting Snap.\n * @param hooks.getUnlockPromise - Wait for the extension to be unlocked.\n * @param hooks.updateSnapState - Update the state of the requesting Snap.\n * @returns Nothing.\n */\nasync function setStateImplementation(\n request: JsonRpcRequest<SetStateParameters>,\n response: PendingJsonRpcResponse<SetStateResult>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n {\n hasPermission,\n getSnapState,\n getUnlockPromise,\n updateSnapState,\n }: SetStateHooks,\n): Promise<void> {\n const { params } = request;\n\n if (!hasPermission(manageStateBuilder.targetName)) {\n return end(providerErrors.unauthorized());\n }\n\n try {\n const validatedParams = getValidatedParams(params);\n const { key, value, encrypted = true } = validatedParams;\n\n if (key === undefined && !isObject(value)) {\n return end(\n rpcErrors.invalidParams(\n 'Invalid params: Value must be an object if key is not provided.',\n ),\n );\n }\n\n if (encrypted) {\n await getUnlockPromise(true);\n }\n\n const newState = await getNewState(key, value, encrypted, getSnapState);\n\n const size = getJsonSize(newState);\n if (size > STORAGE_SIZE_LIMIT) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: The new state must not exceed ${\n STORAGE_SIZE_LIMIT / 1_000_000\n } MB in size.`,\n });\n }\n\n await updateSnapState(newState, encrypted);\n response.result = null;\n } catch (error) {\n return end(error);\n }\n\n return end();\n}\n\n/**\n * Validate the parameters of the `snap_setState` method.\n *\n * @param params - The parameters to validate.\n * @returns The validated parameters.\n */\nfunction getValidatedParams(params?: unknown) {\n try {\n return create(params, SetStateParametersStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n\n/**\n * Get the new state of the Snap.\n *\n * If the key is `undefined`, the value is expected to be an object. In this\n * case, the value is returned as the new state.\n *\n * If the key is not `undefined`, the value is set in the state at the key. If\n * the key does not exist, it is created (and any missing intermediate keys are\n * created as well).\n *\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @param encrypted - Whether the state is encrypted.\n * @param getSnapState - The `getSnapState` hook.\n * @returns The new state of the Snap.\n */\nasync function getNewState(\n key: string | undefined,\n value: Json,\n encrypted: boolean,\n getSnapState: SetStateHooks['getSnapState'],\n) {\n if (key === undefined) {\n assert(isObject(value));\n return value;\n }\n\n const state = await getSnapState(encrypted);\n return set(state, key, value);\n}\n\n/**\n * Set the value of a key in an object. The key may contain Lodash-style path\n * syntax, e.g., `a.b.c` (with the exception of array syntax). If the key does\n * not exist, it is created (and any missing intermediate keys are created as\n * well).\n *\n * This is a simplified version of Lodash's `set` function, but Lodash doesn't\n * seem to be maintained anymore, so we're using our own implementation.\n *\n * @param object - The object to get the key from.\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @returns The new object with the key set to the value.\n */\nexport function set(\n // eslint-disable-next-line @typescript-eslint/default-param-last\n object: Record<string, Json> | null,\n key: string,\n value: Json,\n): JsonObject {\n const keys = key.split('.');\n const requiredObject = object ?? {};\n let currentObject: Record<string, Json> = requiredObject;\n\n for (let i = 0; i < keys.length; i++) {\n const currentKey = keys[i];\n if (FORBIDDEN_KEYS.includes(currentKey)) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Key contains forbidden characters.',\n );\n }\n\n if (i === keys.length - 1) {\n currentObject[currentKey] = value;\n return requiredObject;\n }\n\n if (\n !hasProperty(currentObject, currentKey) ||\n currentObject[currentKey] === null\n ) {\n currentObject[currentKey] = {};\n } else if (!isObject(currentObject[currentKey])) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Cannot overwrite non-object value.',\n );\n }\n\n currentObject = currentObject[currentKey] as Record<string, Json>;\n }\n\n // This should never be reached.\n /* istanbul ignore next */\n throw new Error('Unexpected error while setting the state.');\n}\n"]}
1
+ {"version":3,"file":"setState.cjs","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { PermittedHandlerExport } from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { SetStateParams, SetStateResult } from '@metamask/snaps-sdk';\nimport type { JsonObject } from '@metamask/snaps-sdk/jsx';\nimport { type InferMatching } from '@metamask/snaps-utils';\nimport {\n boolean,\n create,\n object as objectStruct,\n optional,\n StructError,\n} from '@metamask/superstruct';\nimport type {\n PendingJsonRpcResponse,\n Json,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n getJsonSize,\n hasProperty,\n isObject,\n assert,\n JsonStruct,\n} from '@metamask/utils';\n\nimport {\n manageStateBuilder,\n STORAGE_SIZE_LIMIT,\n} from '../restricted/manageState';\nimport type { MethodHooksObject } from '../utils';\nimport { FORBIDDEN_KEYS, StateKeyStruct } from '../utils';\n\nconst hookNames: MethodHooksObject<SetStateHooks> = {\n hasPermission: true,\n getSnapState: true,\n getUnlockPromise: true,\n updateSnapState: true,\n};\n\n/**\n * `snap_setState` sets the state of the Snap.\n */\nexport const setStateHandler: PermittedHandlerExport<\n SetStateHooks,\n SetStateParameters,\n SetStateResult\n> = {\n methodNames: ['snap_setState'],\n implementation: setStateImplementation,\n hookNames,\n};\n\nexport type SetStateHooks = {\n /**\n * Check if the requesting origin has a given permission.\n *\n * @param permissionName - The name of the permission to check.\n * @returns Whether the origin has the permission.\n */\n hasPermission: (permissionName: string) => boolean;\n\n /**\n * Get the state of the requesting Snap.\n *\n * @param encrypted - Whether the state is encrypted.\n * @returns The current state of the Snap.\n */\n getSnapState: (encrypted: boolean) => Promise<Record<string, Json>>;\n\n /**\n * Wait for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Update the state of the requesting Snap.\n *\n * @param newState - The new state of the Snap.\n * @param encrypted - Whether the state should be encrypted.\n */\n updateSnapState: (\n newState: Record<string, Json>,\n encrypted: boolean,\n ) => Promise<void>;\n};\n\nconst SetStateParametersStruct = objectStruct({\n key: optional(StateKeyStruct),\n value: JsonStruct,\n encrypted: optional(boolean()),\n});\n\nexport type SetStateParameters = InferMatching<\n typeof SetStateParametersStruct,\n SetStateParams\n>;\n\n/**\n * The `snap_setState` method implementation.\n *\n * @param request - The JSON-RPC request object.\n * @param response - The JSON-RPC response object.\n * @param _next - The `json-rpc-engine` \"next\" callback. Not used by this\n * function.\n * @param end - The `json-rpc-engine` \"end\" callback.\n * @param hooks - The RPC method hooks.\n * @param hooks.hasPermission - Check whether a given origin has a given\n * permission.\n * @param hooks.getSnapState - Get the state of the requesting Snap.\n * @param hooks.getUnlockPromise - Wait for the extension to be unlocked.\n * @param hooks.updateSnapState - Update the state of the requesting Snap.\n * @returns Nothing.\n */\nasync function setStateImplementation(\n request: JsonRpcRequest<SetStateParameters>,\n response: PendingJsonRpcResponse<SetStateResult>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n {\n hasPermission,\n getSnapState,\n getUnlockPromise,\n updateSnapState,\n }: SetStateHooks,\n): Promise<void> {\n const { params } = request;\n\n if (!hasPermission(manageStateBuilder.targetName)) {\n return end(providerErrors.unauthorized());\n }\n\n try {\n const validatedParams = getValidatedParams(params);\n const { key, value, encrypted = true } = validatedParams;\n\n if (key === undefined && !isObject(value)) {\n return end(\n rpcErrors.invalidParams(\n 'Invalid params: Value must be an object if key is not provided.',\n ),\n );\n }\n\n if (encrypted) {\n await getUnlockPromise(true);\n }\n\n const newState = await getNewState(key, value, encrypted, getSnapState);\n\n const size = getJsonSize(newState);\n if (size > STORAGE_SIZE_LIMIT) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: The new state must not exceed ${\n STORAGE_SIZE_LIMIT / 1_000_000\n } MB in size.`,\n });\n }\n\n await updateSnapState(newState, encrypted);\n response.result = null;\n } catch (error) {\n return end(error);\n }\n\n return end();\n}\n\n/**\n * Validate the parameters of the `snap_setState` method.\n *\n * @param params - The parameters to validate.\n * @returns The validated parameters.\n */\nfunction getValidatedParams(params?: unknown) {\n try {\n return create(params, SetStateParametersStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n\n/**\n * Get the new state of the Snap.\n *\n * If the key is `undefined`, the value is expected to be an object. In this\n * case, the value is returned as the new state.\n *\n * If the key is not `undefined`, the value is set in the state at the key. If\n * the key does not exist, it is created (and any missing intermediate keys are\n * created as well).\n *\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @param encrypted - Whether the state is encrypted.\n * @param getSnapState - The `getSnapState` hook.\n * @returns The new state of the Snap.\n */\nasync function getNewState(\n key: string | undefined,\n value: Json,\n encrypted: boolean,\n getSnapState: SetStateHooks['getSnapState'],\n) {\n if (key === undefined) {\n assert(isObject(value));\n return value;\n }\n\n const state = await getSnapState(encrypted);\n return set(state, key, value);\n}\n\n/**\n * Set the value of a key in an object. The key may contain Lodash-style path\n * syntax, e.g., `a.b.c` (with the exception of array syntax). If the key does\n * not exist, it is created (and any missing intermediate keys are created as\n * well).\n *\n * This is a simplified version of Lodash's `set` function, but Lodash doesn't\n * seem to be maintained anymore, so we're using our own implementation.\n *\n * @param object - The object to get the key from.\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @returns The new object with the key set to the value.\n */\nexport function set(\n object: Record<string, Json> | null,\n key: string,\n value: Json,\n): JsonObject {\n const keys = key.split('.');\n const requiredObject = object ?? {};\n let currentObject: Record<string, Json> = requiredObject;\n\n for (let i = 0; i < keys.length; i++) {\n const currentKey = keys[i];\n if (FORBIDDEN_KEYS.includes(currentKey)) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Key contains forbidden characters.',\n );\n }\n\n if (i === keys.length - 1) {\n currentObject[currentKey] = value;\n return requiredObject;\n }\n\n if (\n !hasProperty(currentObject, currentKey) ||\n currentObject[currentKey] === null\n ) {\n currentObject[currentKey] = {};\n } else if (!isObject(currentObject[currentKey])) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Cannot overwrite non-object value.',\n );\n }\n\n currentObject = currentObject[currentKey] as Record<string, Json>;\n }\n\n // This should never be reached.\n /* istanbul ignore next */\n throw new Error('Unexpected error while setting the state.');\n}\n"]}
@@ -2,7 +2,7 @@ import type { PermittedHandlerExport } from "@metamask/permission-controller";
2
2
  import type { SetStateParams, SetStateResult } from "@metamask/snaps-sdk";
3
3
  import type { JsonObject } from "@metamask/snaps-sdk/jsx";
4
4
  import { type InferMatching } from "@metamask/snaps-utils";
5
- import { type Json } from "@metamask/utils";
5
+ import type { Json } from "@metamask/utils";
6
6
  /**
7
7
  * `snap_setState` sets the state of the Snap.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"setState.d.cts","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,wCAAwC;AAE9E,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,4BAA4B;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,8BAA8B;AAS3D,OAAO,EAML,KAAK,IAAI,EACV,wBAAwB;AAgBzB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAClD,aAAa,EACb,kBAAkB,EAClB,cAAc,CAKf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,aAAa,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEpE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9B,SAAS,EAAE,OAAO,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;EAI5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,OAAO,wBAAwB,EAC/B,cAAc,CACf,CAAC;AA4HF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CAEjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,EACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,GACV,UAAU,CAmCZ"}
1
+ {"version":3,"file":"setState.d.cts","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,wCAAwC;AAE9E,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,4BAA4B;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,8BAA8B;AAQ3D,OAAO,KAAK,EAEV,IAAI,EAEL,wBAAwB;AAuBzB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAClD,aAAa,EACb,kBAAkB,EAClB,cAAc,CAKf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,aAAa,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEpE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9B,SAAS,EAAE,OAAO,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;EAI5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,OAAO,wBAAwB,EAC/B,cAAc,CACf,CAAC;AA4HF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,EACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,GACV,UAAU,CAmCZ"}
@@ -2,7 +2,7 @@ import type { PermittedHandlerExport } from "@metamask/permission-controller";
2
2
  import type { SetStateParams, SetStateResult } from "@metamask/snaps-sdk";
3
3
  import type { JsonObject } from "@metamask/snaps-sdk/jsx";
4
4
  import { type InferMatching } from "@metamask/snaps-utils";
5
- import { type Json } from "@metamask/utils";
5
+ import type { Json } from "@metamask/utils";
6
6
  /**
7
7
  * `snap_setState` sets the state of the Snap.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"setState.d.mts","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,wCAAwC;AAE9E,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,4BAA4B;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,8BAA8B;AAS3D,OAAO,EAML,KAAK,IAAI,EACV,wBAAwB;AAgBzB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAClD,aAAa,EACb,kBAAkB,EAClB,cAAc,CAKf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,aAAa,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEpE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9B,SAAS,EAAE,OAAO,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;EAI5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,OAAO,wBAAwB,EAC/B,cAAc,CACf,CAAC;AA4HF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CAEjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,EACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,GACV,UAAU,CAmCZ"}
1
+ {"version":3,"file":"setState.d.mts","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,wCAAwC;AAE9E,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,4BAA4B;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,8BAA8B;AAQ3D,OAAO,KAAK,EAEV,IAAI,EAEL,wBAAwB;AAuBzB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAClD,aAAa,EACb,kBAAkB,EAClB,cAAc,CAKf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,aAAa,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEpE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC9B,SAAS,EAAE,OAAO,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;EAI5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,OAAO,wBAAwB,EAC/B,cAAc,CACf,CAAC;AA4HF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,EACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,GACV,UAAU,CAmCZ"}
@@ -125,9 +125,7 @@ async function getNewState(key, value, encrypted, getSnapState) {
125
125
  * @param value - The value to set the key to.
126
126
  * @returns The new object with the key set to the value.
127
127
  */
128
- export function set(
129
- // eslint-disable-next-line @typescript-eslint/default-param-last
130
- object, key, value) {
128
+ export function set(object, key, value) {
131
129
  const keys = key.split('.');
132
130
  const requiredObject = object ?? {};
133
131
  let currentObject = requiredObject;
@@ -1 +1 @@
1
- {"version":3,"file":"setState.mjs","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { PermittedHandlerExport } from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { SetStateParams, SetStateResult } from '@metamask/snaps-sdk';\nimport type { JsonObject } from '@metamask/snaps-sdk/jsx';\nimport { type InferMatching } from '@metamask/snaps-utils';\nimport {\n boolean,\n create,\n object as objectStruct,\n optional,\n StructError,\n} from '@metamask/superstruct';\nimport type { PendingJsonRpcResponse, JsonRpcRequest } from '@metamask/utils';\nimport {\n getJsonSize,\n hasProperty,\n isObject,\n assert,\n JsonStruct,\n type Json,\n} from '@metamask/utils';\n\nimport {\n manageStateBuilder,\n STORAGE_SIZE_LIMIT,\n} from '../restricted/manageState';\nimport type { MethodHooksObject } from '../utils';\nimport { FORBIDDEN_KEYS, StateKeyStruct } from '../utils';\n\nconst hookNames: MethodHooksObject<SetStateHooks> = {\n hasPermission: true,\n getSnapState: true,\n getUnlockPromise: true,\n updateSnapState: true,\n};\n\n/**\n * `snap_setState` sets the state of the Snap.\n */\nexport const setStateHandler: PermittedHandlerExport<\n SetStateHooks,\n SetStateParameters,\n SetStateResult\n> = {\n methodNames: ['snap_setState'],\n implementation: setStateImplementation,\n hookNames,\n};\n\nexport type SetStateHooks = {\n /**\n * Check if the requesting origin has a given permission.\n *\n * @param permissionName - The name of the permission to check.\n * @returns Whether the origin has the permission.\n */\n hasPermission: (permissionName: string) => boolean;\n\n /**\n * Get the state of the requesting Snap.\n *\n * @param encrypted - Whether the state is encrypted.\n * @returns The current state of the Snap.\n */\n getSnapState: (encrypted: boolean) => Promise<Record<string, Json>>;\n\n /**\n * Wait for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Update the state of the requesting Snap.\n *\n * @param newState - The new state of the Snap.\n * @param encrypted - Whether the state should be encrypted.\n */\n updateSnapState: (\n newState: Record<string, Json>,\n encrypted: boolean,\n ) => Promise<void>;\n};\n\nconst SetStateParametersStruct = objectStruct({\n key: optional(StateKeyStruct),\n value: JsonStruct,\n encrypted: optional(boolean()),\n});\n\nexport type SetStateParameters = InferMatching<\n typeof SetStateParametersStruct,\n SetStateParams\n>;\n\n/**\n * The `snap_setState` method implementation.\n *\n * @param request - The JSON-RPC request object.\n * @param response - The JSON-RPC response object.\n * @param _next - The `json-rpc-engine` \"next\" callback. Not used by this\n * function.\n * @param end - The `json-rpc-engine` \"end\" callback.\n * @param hooks - The RPC method hooks.\n * @param hooks.hasPermission - Check whether a given origin has a given\n * permission.\n * @param hooks.getSnapState - Get the state of the requesting Snap.\n * @param hooks.getUnlockPromise - Wait for the extension to be unlocked.\n * @param hooks.updateSnapState - Update the state of the requesting Snap.\n * @returns Nothing.\n */\nasync function setStateImplementation(\n request: JsonRpcRequest<SetStateParameters>,\n response: PendingJsonRpcResponse<SetStateResult>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n {\n hasPermission,\n getSnapState,\n getUnlockPromise,\n updateSnapState,\n }: SetStateHooks,\n): Promise<void> {\n const { params } = request;\n\n if (!hasPermission(manageStateBuilder.targetName)) {\n return end(providerErrors.unauthorized());\n }\n\n try {\n const validatedParams = getValidatedParams(params);\n const { key, value, encrypted = true } = validatedParams;\n\n if (key === undefined && !isObject(value)) {\n return end(\n rpcErrors.invalidParams(\n 'Invalid params: Value must be an object if key is not provided.',\n ),\n );\n }\n\n if (encrypted) {\n await getUnlockPromise(true);\n }\n\n const newState = await getNewState(key, value, encrypted, getSnapState);\n\n const size = getJsonSize(newState);\n if (size > STORAGE_SIZE_LIMIT) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: The new state must not exceed ${\n STORAGE_SIZE_LIMIT / 1_000_000\n } MB in size.`,\n });\n }\n\n await updateSnapState(newState, encrypted);\n response.result = null;\n } catch (error) {\n return end(error);\n }\n\n return end();\n}\n\n/**\n * Validate the parameters of the `snap_setState` method.\n *\n * @param params - The parameters to validate.\n * @returns The validated parameters.\n */\nfunction getValidatedParams(params?: unknown) {\n try {\n return create(params, SetStateParametersStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n\n/**\n * Get the new state of the Snap.\n *\n * If the key is `undefined`, the value is expected to be an object. In this\n * case, the value is returned as the new state.\n *\n * If the key is not `undefined`, the value is set in the state at the key. If\n * the key does not exist, it is created (and any missing intermediate keys are\n * created as well).\n *\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @param encrypted - Whether the state is encrypted.\n * @param getSnapState - The `getSnapState` hook.\n * @returns The new state of the Snap.\n */\nasync function getNewState(\n key: string | undefined,\n value: Json,\n encrypted: boolean,\n getSnapState: SetStateHooks['getSnapState'],\n) {\n if (key === undefined) {\n assert(isObject(value));\n return value;\n }\n\n const state = await getSnapState(encrypted);\n return set(state, key, value);\n}\n\n/**\n * Set the value of a key in an object. The key may contain Lodash-style path\n * syntax, e.g., `a.b.c` (with the exception of array syntax). If the key does\n * not exist, it is created (and any missing intermediate keys are created as\n * well).\n *\n * This is a simplified version of Lodash's `set` function, but Lodash doesn't\n * seem to be maintained anymore, so we're using our own implementation.\n *\n * @param object - The object to get the key from.\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @returns The new object with the key set to the value.\n */\nexport function set(\n // eslint-disable-next-line @typescript-eslint/default-param-last\n object: Record<string, Json> | null,\n key: string,\n value: Json,\n): JsonObject {\n const keys = key.split('.');\n const requiredObject = object ?? {};\n let currentObject: Record<string, Json> = requiredObject;\n\n for (let i = 0; i < keys.length; i++) {\n const currentKey = keys[i];\n if (FORBIDDEN_KEYS.includes(currentKey)) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Key contains forbidden characters.',\n );\n }\n\n if (i === keys.length - 1) {\n currentObject[currentKey] = value;\n return requiredObject;\n }\n\n if (\n !hasProperty(currentObject, currentKey) ||\n currentObject[currentKey] === null\n ) {\n currentObject[currentKey] = {};\n } else if (!isObject(currentObject[currentKey])) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Cannot overwrite non-object value.',\n );\n }\n\n currentObject = currentObject[currentKey] as Record<string, Json>;\n }\n\n // This should never be reached.\n /* istanbul ignore next */\n throw new Error('Unexpected error while setting the state.');\n}\n"]}
1
+ {"version":3,"file":"setState.mjs","sourceRoot":"","sources":["../../src/permitted/setState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { PermittedHandlerExport } from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { SetStateParams, SetStateResult } from '@metamask/snaps-sdk';\nimport type { JsonObject } from '@metamask/snaps-sdk/jsx';\nimport { type InferMatching } from '@metamask/snaps-utils';\nimport {\n boolean,\n create,\n object as objectStruct,\n optional,\n StructError,\n} from '@metamask/superstruct';\nimport type {\n PendingJsonRpcResponse,\n Json,\n JsonRpcRequest,\n} from '@metamask/utils';\nimport {\n getJsonSize,\n hasProperty,\n isObject,\n assert,\n JsonStruct,\n} from '@metamask/utils';\n\nimport {\n manageStateBuilder,\n STORAGE_SIZE_LIMIT,\n} from '../restricted/manageState';\nimport type { MethodHooksObject } from '../utils';\nimport { FORBIDDEN_KEYS, StateKeyStruct } from '../utils';\n\nconst hookNames: MethodHooksObject<SetStateHooks> = {\n hasPermission: true,\n getSnapState: true,\n getUnlockPromise: true,\n updateSnapState: true,\n};\n\n/**\n * `snap_setState` sets the state of the Snap.\n */\nexport const setStateHandler: PermittedHandlerExport<\n SetStateHooks,\n SetStateParameters,\n SetStateResult\n> = {\n methodNames: ['snap_setState'],\n implementation: setStateImplementation,\n hookNames,\n};\n\nexport type SetStateHooks = {\n /**\n * Check if the requesting origin has a given permission.\n *\n * @param permissionName - The name of the permission to check.\n * @returns Whether the origin has the permission.\n */\n hasPermission: (permissionName: string) => boolean;\n\n /**\n * Get the state of the requesting Snap.\n *\n * @param encrypted - Whether the state is encrypted.\n * @returns The current state of the Snap.\n */\n getSnapState: (encrypted: boolean) => Promise<Record<string, Json>>;\n\n /**\n * Wait for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Update the state of the requesting Snap.\n *\n * @param newState - The new state of the Snap.\n * @param encrypted - Whether the state should be encrypted.\n */\n updateSnapState: (\n newState: Record<string, Json>,\n encrypted: boolean,\n ) => Promise<void>;\n};\n\nconst SetStateParametersStruct = objectStruct({\n key: optional(StateKeyStruct),\n value: JsonStruct,\n encrypted: optional(boolean()),\n});\n\nexport type SetStateParameters = InferMatching<\n typeof SetStateParametersStruct,\n SetStateParams\n>;\n\n/**\n * The `snap_setState` method implementation.\n *\n * @param request - The JSON-RPC request object.\n * @param response - The JSON-RPC response object.\n * @param _next - The `json-rpc-engine` \"next\" callback. Not used by this\n * function.\n * @param end - The `json-rpc-engine` \"end\" callback.\n * @param hooks - The RPC method hooks.\n * @param hooks.hasPermission - Check whether a given origin has a given\n * permission.\n * @param hooks.getSnapState - Get the state of the requesting Snap.\n * @param hooks.getUnlockPromise - Wait for the extension to be unlocked.\n * @param hooks.updateSnapState - Update the state of the requesting Snap.\n * @returns Nothing.\n */\nasync function setStateImplementation(\n request: JsonRpcRequest<SetStateParameters>,\n response: PendingJsonRpcResponse<SetStateResult>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n {\n hasPermission,\n getSnapState,\n getUnlockPromise,\n updateSnapState,\n }: SetStateHooks,\n): Promise<void> {\n const { params } = request;\n\n if (!hasPermission(manageStateBuilder.targetName)) {\n return end(providerErrors.unauthorized());\n }\n\n try {\n const validatedParams = getValidatedParams(params);\n const { key, value, encrypted = true } = validatedParams;\n\n if (key === undefined && !isObject(value)) {\n return end(\n rpcErrors.invalidParams(\n 'Invalid params: Value must be an object if key is not provided.',\n ),\n );\n }\n\n if (encrypted) {\n await getUnlockPromise(true);\n }\n\n const newState = await getNewState(key, value, encrypted, getSnapState);\n\n const size = getJsonSize(newState);\n if (size > STORAGE_SIZE_LIMIT) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: The new state must not exceed ${\n STORAGE_SIZE_LIMIT / 1_000_000\n } MB in size.`,\n });\n }\n\n await updateSnapState(newState, encrypted);\n response.result = null;\n } catch (error) {\n return end(error);\n }\n\n return end();\n}\n\n/**\n * Validate the parameters of the `snap_setState` method.\n *\n * @param params - The parameters to validate.\n * @returns The validated parameters.\n */\nfunction getValidatedParams(params?: unknown) {\n try {\n return create(params, SetStateParametersStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n\n/**\n * Get the new state of the Snap.\n *\n * If the key is `undefined`, the value is expected to be an object. In this\n * case, the value is returned as the new state.\n *\n * If the key is not `undefined`, the value is set in the state at the key. If\n * the key does not exist, it is created (and any missing intermediate keys are\n * created as well).\n *\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @param encrypted - Whether the state is encrypted.\n * @param getSnapState - The `getSnapState` hook.\n * @returns The new state of the Snap.\n */\nasync function getNewState(\n key: string | undefined,\n value: Json,\n encrypted: boolean,\n getSnapState: SetStateHooks['getSnapState'],\n) {\n if (key === undefined) {\n assert(isObject(value));\n return value;\n }\n\n const state = await getSnapState(encrypted);\n return set(state, key, value);\n}\n\n/**\n * Set the value of a key in an object. The key may contain Lodash-style path\n * syntax, e.g., `a.b.c` (with the exception of array syntax). If the key does\n * not exist, it is created (and any missing intermediate keys are created as\n * well).\n *\n * This is a simplified version of Lodash's `set` function, but Lodash doesn't\n * seem to be maintained anymore, so we're using our own implementation.\n *\n * @param object - The object to get the key from.\n * @param key - The key to set.\n * @param value - The value to set the key to.\n * @returns The new object with the key set to the value.\n */\nexport function set(\n object: Record<string, Json> | null,\n key: string,\n value: Json,\n): JsonObject {\n const keys = key.split('.');\n const requiredObject = object ?? {};\n let currentObject: Record<string, Json> = requiredObject;\n\n for (let i = 0; i < keys.length; i++) {\n const currentKey = keys[i];\n if (FORBIDDEN_KEYS.includes(currentKey)) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Key contains forbidden characters.',\n );\n }\n\n if (i === keys.length - 1) {\n currentObject[currentKey] = value;\n return requiredObject;\n }\n\n if (\n !hasProperty(currentObject, currentKey) ||\n currentObject[currentKey] === null\n ) {\n currentObject[currentKey] = {};\n } else if (!isObject(currentObject[currentKey])) {\n throw rpcErrors.invalidParams(\n 'Invalid params: Cannot overwrite non-object value.',\n );\n }\n\n currentObject = currentObject[currentKey] as Record<string, Json>;\n }\n\n // This should never be reached.\n /* istanbul ignore next */\n throw new Error('Unexpected error while setting the state.');\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.caveatMappers = exports.caveatSpecifications = void 0;
4
+ const permittedCoinTypes_1 = require("./permittedCoinTypes.cjs");
5
+ const permittedDerivationPaths_1 = require("./permittedDerivationPaths.cjs");
6
+ const snapIds_1 = require("./snapIds.cjs");
4
7
  const getBip32Entropy_1 = require("../getBip32Entropy.cjs");
5
8
  const getBip32PublicKey_1 = require("../getBip32PublicKey.cjs");
6
9
  const getBip44Entropy_1 = require("../getBip44Entropy.cjs");
7
10
  const invokeSnap_1 = require("../invokeSnap.cjs");
8
- const permittedCoinTypes_1 = require("./permittedCoinTypes.cjs");
9
- const permittedDerivationPaths_1 = require("./permittedDerivationPaths.cjs");
10
- const snapIds_1 = require("./snapIds.cjs");
11
11
  exports.caveatSpecifications = {
12
12
  ...permittedDerivationPaths_1.PermittedDerivationPathsCaveatSpecification,
13
13
  ...permittedCoinTypes_1.PermittedCoinTypesCaveatSpecification,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/restricted/caveats/index.ts"],"names":[],"mappings":";;;AAGA,4DAA4D;AAC5D,gEAAgE;AAChE,4DAA4D;AAC5D,kDAAkD;AAClD,iEAG8B;AAC9B,6EAGoC;AACpC,2CAA4E;AAE/D,QAAA,oBAAoB,GAAG;IAClC,GAAG,sEAA2C;IAC9C,GAAG,0DAAqC;IACxC,GAAG,oCAA0B;CACrB,CAAC;AAEE,QAAA,aAAa,GAGtB;IACF,CAAC,wCAAsB,CAAC,UAAU,CAAC,EAAE,+DAAoC;IACzE,CAAC,4CAAwB,CAAC,UAAU,CAAC,EAAE,+DAAoC;IAC3E,CAAC,wCAAsB,CAAC,UAAU,CAAC,EAAE,mDAA8B;IACnE,CAAC,8BAAiB,CAAC,UAAU,CAAC,EAAE,6BAAmB;CACpD,CAAC","sourcesContent":["import type { PermissionConstraint } from '@metamask/permission-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { getBip32EntropyBuilder } from '../getBip32Entropy';\nimport { getBip32PublicKeyBuilder } from '../getBip32PublicKey';\nimport { getBip44EntropyBuilder } from '../getBip44Entropy';\nimport { invokeSnapBuilder } from '../invokeSnap';\nimport {\n permittedCoinTypesCaveatMapper,\n PermittedCoinTypesCaveatSpecification,\n} from './permittedCoinTypes';\nimport {\n permittedDerivationPathsCaveatMapper,\n PermittedDerivationPathsCaveatSpecification,\n} from './permittedDerivationPaths';\nimport { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from './snapIds';\n\nexport const caveatSpecifications = {\n ...PermittedDerivationPathsCaveatSpecification,\n ...PermittedCoinTypesCaveatSpecification,\n ...SnapIdsCaveatSpecification,\n} as const;\n\nexport const caveatMappers: Record<\n string,\n (value: Json) => Pick<PermissionConstraint, 'caveats'>\n> = {\n [getBip32EntropyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip32PublicKeyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip44EntropyBuilder.targetName]: permittedCoinTypesCaveatMapper,\n [invokeSnapBuilder.targetName]: snapIdsCaveatMapper,\n};\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/restricted/caveats/index.ts"],"names":[],"mappings":";;;AAGA,iEAG8B;AAC9B,6EAGoC;AACpC,2CAA4E;AAC5E,4DAA4D;AAC5D,gEAAgE;AAChE,4DAA4D;AAC5D,kDAAkD;AAErC,QAAA,oBAAoB,GAAG;IAClC,GAAG,sEAA2C;IAC9C,GAAG,0DAAqC;IACxC,GAAG,oCAA0B;CACrB,CAAC;AAEE,QAAA,aAAa,GAGtB;IACF,CAAC,wCAAsB,CAAC,UAAU,CAAC,EAAE,+DAAoC;IACzE,CAAC,4CAAwB,CAAC,UAAU,CAAC,EAAE,+DAAoC;IAC3E,CAAC,wCAAsB,CAAC,UAAU,CAAC,EAAE,mDAA8B;IACnE,CAAC,8BAAiB,CAAC,UAAU,CAAC,EAAE,6BAAmB;CACpD,CAAC","sourcesContent":["import type { PermissionConstraint } from '@metamask/permission-controller';\nimport type { Json } from '@metamask/utils';\n\nimport {\n permittedCoinTypesCaveatMapper,\n PermittedCoinTypesCaveatSpecification,\n} from './permittedCoinTypes';\nimport {\n permittedDerivationPathsCaveatMapper,\n PermittedDerivationPathsCaveatSpecification,\n} from './permittedDerivationPaths';\nimport { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from './snapIds';\nimport { getBip32EntropyBuilder } from '../getBip32Entropy';\nimport { getBip32PublicKeyBuilder } from '../getBip32PublicKey';\nimport { getBip44EntropyBuilder } from '../getBip44Entropy';\nimport { invokeSnapBuilder } from '../invokeSnap';\n\nexport const caveatSpecifications = {\n ...PermittedDerivationPathsCaveatSpecification,\n ...PermittedCoinTypesCaveatSpecification,\n ...SnapIdsCaveatSpecification,\n} as const;\n\nexport const caveatMappers: Record<\n string,\n (value: Json) => Pick<PermissionConstraint, 'caveats'>\n> = {\n [getBip32EntropyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip32PublicKeyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip44EntropyBuilder.targetName]: permittedCoinTypesCaveatMapper,\n [invokeSnapBuilder.targetName]: snapIdsCaveatMapper,\n};\n"]}
@@ -1,10 +1,10 @@
1
+ import { permittedCoinTypesCaveatMapper, PermittedCoinTypesCaveatSpecification } from "./permittedCoinTypes.mjs";
2
+ import { permittedDerivationPathsCaveatMapper, PermittedDerivationPathsCaveatSpecification } from "./permittedDerivationPaths.mjs";
3
+ import { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from "./snapIds.mjs";
1
4
  import { getBip32EntropyBuilder } from "../getBip32Entropy.mjs";
2
5
  import { getBip32PublicKeyBuilder } from "../getBip32PublicKey.mjs";
3
6
  import { getBip44EntropyBuilder } from "../getBip44Entropy.mjs";
4
7
  import { invokeSnapBuilder } from "../invokeSnap.mjs";
5
- import { permittedCoinTypesCaveatMapper, PermittedCoinTypesCaveatSpecification } from "./permittedCoinTypes.mjs";
6
- import { permittedDerivationPathsCaveatMapper, PermittedDerivationPathsCaveatSpecification } from "./permittedDerivationPaths.mjs";
7
- import { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from "./snapIds.mjs";
8
8
  export const caveatSpecifications = {
9
9
  ...PermittedDerivationPathsCaveatSpecification,
10
10
  ...PermittedCoinTypesCaveatSpecification,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/restricted/caveats/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,+BAA2B;AAC5D,OAAO,EAAE,wBAAwB,EAAE,iCAA6B;AAChE,OAAO,EAAE,sBAAsB,EAAE,+BAA2B;AAC5D,OAAO,EAAE,iBAAiB,EAAE,0BAAsB;AAClD,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACtC,iCAA6B;AAC9B,OAAO,EACL,oCAAoC,EACpC,2CAA2C,EAC5C,uCAAmC;AACpC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,sBAAkB;AAE5E,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,2CAA2C;IAC9C,GAAG,qCAAqC;IACxC,GAAG,0BAA0B;CACrB,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAGtB;IACF,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,oCAAoC;IACzE,CAAC,wBAAwB,CAAC,UAAU,CAAC,EAAE,oCAAoC;IAC3E,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,8BAA8B;IACnE,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,mBAAmB;CACpD,CAAC","sourcesContent":["import type { PermissionConstraint } from '@metamask/permission-controller';\nimport type { Json } from '@metamask/utils';\n\nimport { getBip32EntropyBuilder } from '../getBip32Entropy';\nimport { getBip32PublicKeyBuilder } from '../getBip32PublicKey';\nimport { getBip44EntropyBuilder } from '../getBip44Entropy';\nimport { invokeSnapBuilder } from '../invokeSnap';\nimport {\n permittedCoinTypesCaveatMapper,\n PermittedCoinTypesCaveatSpecification,\n} from './permittedCoinTypes';\nimport {\n permittedDerivationPathsCaveatMapper,\n PermittedDerivationPathsCaveatSpecification,\n} from './permittedDerivationPaths';\nimport { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from './snapIds';\n\nexport const caveatSpecifications = {\n ...PermittedDerivationPathsCaveatSpecification,\n ...PermittedCoinTypesCaveatSpecification,\n ...SnapIdsCaveatSpecification,\n} as const;\n\nexport const caveatMappers: Record<\n string,\n (value: Json) => Pick<PermissionConstraint, 'caveats'>\n> = {\n [getBip32EntropyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip32PublicKeyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip44EntropyBuilder.targetName]: permittedCoinTypesCaveatMapper,\n [invokeSnapBuilder.targetName]: snapIdsCaveatMapper,\n};\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/restricted/caveats/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACtC,iCAA6B;AAC9B,OAAO,EACL,oCAAoC,EACpC,2CAA2C,EAC5C,uCAAmC;AACpC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,sBAAkB;AAC5E,OAAO,EAAE,sBAAsB,EAAE,+BAA2B;AAC5D,OAAO,EAAE,wBAAwB,EAAE,iCAA6B;AAChE,OAAO,EAAE,sBAAsB,EAAE,+BAA2B;AAC5D,OAAO,EAAE,iBAAiB,EAAE,0BAAsB;AAElD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,2CAA2C;IAC9C,GAAG,qCAAqC;IACxC,GAAG,0BAA0B;CACrB,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAGtB;IACF,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,oCAAoC;IACzE,CAAC,wBAAwB,CAAC,UAAU,CAAC,EAAE,oCAAoC;IAC3E,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,8BAA8B;IACnE,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,mBAAmB;CACpD,CAAC","sourcesContent":["import type { PermissionConstraint } from '@metamask/permission-controller';\nimport type { Json } from '@metamask/utils';\n\nimport {\n permittedCoinTypesCaveatMapper,\n PermittedCoinTypesCaveatSpecification,\n} from './permittedCoinTypes';\nimport {\n permittedDerivationPathsCaveatMapper,\n PermittedDerivationPathsCaveatSpecification,\n} from './permittedDerivationPaths';\nimport { snapIdsCaveatMapper, SnapIdsCaveatSpecification } from './snapIds';\nimport { getBip32EntropyBuilder } from '../getBip32Entropy';\nimport { getBip32PublicKeyBuilder } from '../getBip32PublicKey';\nimport { getBip44EntropyBuilder } from '../getBip44Entropy';\nimport { invokeSnapBuilder } from '../invokeSnap';\n\nexport const caveatSpecifications = {\n ...PermittedDerivationPathsCaveatSpecification,\n ...PermittedCoinTypesCaveatSpecification,\n ...SnapIdsCaveatSpecification,\n} as const;\n\nexport const caveatMappers: Record<\n string,\n (value: Json) => Pick<PermissionConstraint, 'caveats'>\n> = {\n [getBip32EntropyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip32PublicKeyBuilder.targetName]: permittedDerivationPathsCaveatMapper,\n [getBip44EntropyBuilder.targetName]: permittedCoinTypesCaveatMapper,\n [invokeSnapBuilder.targetName]: snapIdsCaveatMapper,\n};\n"]}
@@ -43,6 +43,13 @@ function validateBIP44Params(value) {
43
43
  message: 'Invalid "coinType" parameter. Coin type must be a non-negative integer.',
44
44
  });
45
45
  }
46
+ if ((0, utils_1.hasProperty)(value, 'source') &&
47
+ typeof value.source !== 'undefined' &&
48
+ typeof value.source !== 'string') {
49
+ throw rpc_errors_1.rpcErrors.invalidParams({
50
+ message: 'Invalid "source" parameter. Source must be a string if provided.',
51
+ });
52
+ }
46
53
  if (snaps_utils_1.FORBIDDEN_COIN_TYPES.includes(value.coinType)) {
47
54
  throw rpc_errors_1.rpcErrors.invalidParams({
48
55
  message: `Coin type ${value.coinType} is forbidden.`,
@@ -1 +1 @@
1
- {"version":3,"file":"permittedCoinTypes.cjs","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":";;;AAKA,qDAAiE;AAEjE,uDAA6E;AAE7E,2CAA6D;AAE7D;;;;;;;GAOG;AACH,SAAgB,8BAA8B,CAC5C,KAAW;IAEX,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,4BAAc,CAAC,kBAAkB;gBACvC,KAAK;aACN;SACF;KACF,CAAC;AACJ,CAAC;AAXD,wEAWC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CACjC,KAAc;IAEd,IAAI,CAAC,IAAA,qBAAa,EAAC,KAAK,CAAC,IAAI,CAAC,IAAA,mBAAW,EAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QAC7D,MAAM,sBAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,iDAAiD;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,IACE,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjC,KAAK,CAAC,QAAQ,GAAG,CAAC;QAClB,KAAK,CAAC,QAAQ,GAAG,UAAU,EAC3B,CAAC;QACD,MAAM,sBAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EACL,yEAAyE;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,IAAI,kCAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,MAAM,sBAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,aAAa,KAAK,CAAC,QAAQ,gBAAgB;SACrD,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AA1BD,kDA0BC;AAED;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,MAA2B;IAC7D,IACE,CAAC,IAAA,mBAAW,EAAC,MAAM,EAAE,OAAO,CAAC;QAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EACzB,CAAC;QACD,MAAM,sBAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAC5C,CAAC;AAZD,kDAYC;AAEY,QAAA,qCAAqC,GAG9C;IACF,CAAC,4BAAc,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;QACjD,IAAI,EAAE,4BAAc,CAAC,kBAAkB;QACvC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;YAC5B,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;gBACxB,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAE5B,MAAM,QAAQ,GAAI,MAAM,CAAC,KAAiC,CAAC,IAAI,CAC7D,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAC1D,CAAC;gBAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,2BAAc,CAAC,YAAY,CAAC;wBAChC,OAAO,EACL,sGAAsG;qBACzG,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC;QACD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC;KACnD,CAAC;CACH,CAAC","sourcesContent":["import type {\n PermissionConstraint,\n RestrictedMethodCaveatSpecificationConstraint,\n Caveat,\n} from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { GetBip44EntropyParams } from '@metamask/snaps-sdk';\nimport { FORBIDDEN_COIN_TYPES, SnapCaveatType } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\n\n/**\n * Map a raw value from the `initialPermissions` to a caveat specification.\n * Note that this function does not do any validation, that's handled by the\n * PermissionsController when the permission is requested.\n *\n * @param value - The raw value from the `initialPermissions`.\n * @returns The caveat specification.\n */\nexport function permittedCoinTypesCaveatMapper(\n value: Json,\n): Pick<PermissionConstraint, 'caveats'> {\n return {\n caveats: [\n {\n type: SnapCaveatType.PermittedCoinTypes,\n value,\n },\n ],\n };\n}\n\n/**\n * Validate the params for `snap_getBip44Entropy`.\n *\n * @param value - The params to validate.\n * @throws If the params are invalid.\n */\nexport function validateBIP44Params(\n value: unknown,\n): asserts value is GetBip44EntropyParams {\n if (!isPlainObject(value) || !hasProperty(value, 'coinType')) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object containing a coin type.',\n });\n }\n\n if (\n typeof value.coinType !== 'number' ||\n !Number.isInteger(value.coinType) ||\n value.coinType < 0 ||\n value.coinType > 0x7fffffff\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"coinType\" parameter. Coin type must be a non-negative integer.',\n });\n }\n\n if (FORBIDDEN_COIN_TYPES.includes(value.coinType)) {\n throw rpcErrors.invalidParams({\n message: `Coin type ${value.coinType} is forbidden.`,\n });\n }\n}\n\n/**\n * Validate the coin types values associated with a caveat. This checks if the\n * values are non-negative integers (>= 0).\n *\n * @param caveat - The caveat to validate.\n * @throws If the caveat is invalid.\n */\nexport function validateBIP44Caveat(caveat: Caveat<string, any>) {\n if (\n !hasProperty(caveat, 'value') ||\n !Array.isArray(caveat.value) ||\n caveat.value.length === 0\n ) {\n throw rpcErrors.invalidParams({\n message: 'Expected non-empty array of coin types.',\n });\n }\n\n caveat.value.forEach(validateBIP44Params);\n}\n\nexport const PermittedCoinTypesCaveatSpecification: Record<\n SnapCaveatType.PermittedCoinTypes,\n RestrictedMethodCaveatSpecificationConstraint\n> = {\n [SnapCaveatType.PermittedCoinTypes]: Object.freeze({\n type: SnapCaveatType.PermittedCoinTypes,\n decorator: (method, caveat) => {\n return async (args) => {\n const { params } = args;\n validateBIP44Params(params);\n\n const coinType = (caveat.value as GetBip44EntropyParams[]).find(\n (caveatValue) => caveatValue.coinType === params.coinType,\n );\n\n if (!coinType) {\n throw providerErrors.unauthorized({\n message:\n 'The requested coin type is not permitted. Allowed coin types must be specified in the snap manifest.',\n });\n }\n\n return await method(args);\n };\n },\n validator: (caveat) => validateBIP44Caveat(caveat),\n }),\n};\n"]}
1
+ {"version":3,"file":"permittedCoinTypes.cjs","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PermissionConstraint,\n RestrictedMethodCaveatSpecificationConstraint,\n Caveat,\n} from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { GetBip44EntropyParams } from '@metamask/snaps-sdk';\nimport { FORBIDDEN_COIN_TYPES, SnapCaveatType } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\n\n/**\n * Map a raw value from the `initialPermissions` to a caveat specification.\n * Note that this function does not do any validation, that's handled by the\n * PermissionsController when the permission is requested.\n *\n * @param value - The raw value from the `initialPermissions`.\n * @returns The caveat specification.\n */\nexport function permittedCoinTypesCaveatMapper(\n value: Json,\n): Pick<PermissionConstraint, 'caveats'> {\n return {\n caveats: [\n {\n type: SnapCaveatType.PermittedCoinTypes,\n value,\n },\n ],\n };\n}\n\n/**\n * Validate the params for `snap_getBip44Entropy`.\n *\n * @param value - The params to validate.\n * @throws If the params are invalid.\n */\nexport function validateBIP44Params(\n value: unknown,\n): asserts value is GetBip44EntropyParams {\n if (!isPlainObject(value) || !hasProperty(value, 'coinType')) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object containing a coin type.',\n });\n }\n\n if (\n typeof value.coinType !== 'number' ||\n !Number.isInteger(value.coinType) ||\n value.coinType < 0 ||\n value.coinType > 0x7fffffff\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"coinType\" parameter. Coin type must be a non-negative integer.',\n });\n }\n\n if (\n hasProperty(value, 'source') &&\n typeof value.source !== 'undefined' &&\n typeof value.source !== 'string'\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"source\" parameter. Source must be a string if provided.',\n });\n }\n\n if (FORBIDDEN_COIN_TYPES.includes(value.coinType)) {\n throw rpcErrors.invalidParams({\n message: `Coin type ${value.coinType} is forbidden.`,\n });\n }\n}\n\n/**\n * Validate the coin types values associated with a caveat. This checks if the\n * values are non-negative integers (>= 0).\n *\n * @param caveat - The caveat to validate.\n * @throws If the caveat is invalid.\n */\nexport function validateBIP44Caveat(caveat: Caveat<string, any>) {\n if (\n !hasProperty(caveat, 'value') ||\n !Array.isArray(caveat.value) ||\n caveat.value.length === 0\n ) {\n throw rpcErrors.invalidParams({\n message: 'Expected non-empty array of coin types.',\n });\n }\n\n caveat.value.forEach(validateBIP44Params);\n}\n\nexport const PermittedCoinTypesCaveatSpecification: Record<\n SnapCaveatType.PermittedCoinTypes,\n RestrictedMethodCaveatSpecificationConstraint\n> = {\n [SnapCaveatType.PermittedCoinTypes]: Object.freeze({\n type: SnapCaveatType.PermittedCoinTypes,\n decorator: (method, caveat) => {\n return async (args) => {\n const { params } = args;\n validateBIP44Params(params);\n\n const coinType = (caveat.value as GetBip44EntropyParams[]).find(\n (caveatValue) => caveatValue.coinType === params.coinType,\n );\n\n if (!coinType) {\n throw providerErrors.unauthorized({\n message:\n 'The requested coin type is not permitted. Allowed coin types must be specified in the snap manifest.',\n });\n }\n\n return await method(args);\n };\n },\n validator: (caveat) => validateBIP44Caveat(caveat),\n }),\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"permittedCoinTypes.d.cts","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,6CAA6C,EAC7C,MAAM,EACP,wCAAwC;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,4BAA4B;AACjE,OAAO,EAAwB,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,GACV,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CASvC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,qBAAqB,CAwBxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAY9D;AAED,eAAO,MAAM,qCAAqC,EAAE,MAAM,CACxD,cAAc,CAAC,kBAAkB,EACjC,6CAA6C,CAyB9C,CAAC"}
1
+ {"version":3,"file":"permittedCoinTypes.d.cts","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,6CAA6C,EAC7C,MAAM,EACP,wCAAwC;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,4BAA4B;AACjE,OAAO,EAAwB,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,GACV,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CASvC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,qBAAqB,CAmCxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAY9D;AAED,eAAO,MAAM,qCAAqC,EAAE,MAAM,CACxD,cAAc,CAAC,kBAAkB,EACjC,6CAA6C,CAyB9C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"permittedCoinTypes.d.mts","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,6CAA6C,EAC7C,MAAM,EACP,wCAAwC;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,4BAA4B;AACjE,OAAO,EAAwB,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,GACV,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CASvC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,qBAAqB,CAwBxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAY9D;AAED,eAAO,MAAM,qCAAqC,EAAE,MAAM,CACxD,cAAc,CAAC,kBAAkB,EACjC,6CAA6C,CAyB9C,CAAC"}
1
+ {"version":3,"file":"permittedCoinTypes.d.mts","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,6CAA6C,EAC7C,MAAM,EACP,wCAAwC;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,4BAA4B;AACjE,OAAO,EAAwB,cAAc,EAAE,8BAA8B;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,GACV,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CASvC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,qBAAqB,CAmCxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAY9D;AAED,eAAO,MAAM,qCAAqC,EAAE,MAAM,CACxD,cAAc,CAAC,kBAAkB,EACjC,6CAA6C,CAyB9C,CAAC"}
@@ -39,6 +39,13 @@ export function validateBIP44Params(value) {
39
39
  message: 'Invalid "coinType" parameter. Coin type must be a non-negative integer.',
40
40
  });
41
41
  }
42
+ if (hasProperty(value, 'source') &&
43
+ typeof value.source !== 'undefined' &&
44
+ typeof value.source !== 'string') {
45
+ throw rpcErrors.invalidParams({
46
+ message: 'Invalid "source" parameter. Source must be a string if provided.',
47
+ });
48
+ }
42
49
  if (FORBIDDEN_COIN_TYPES.includes(value.coinType)) {
43
50
  throw rpcErrors.invalidParams({
44
51
  message: `Coin type ${value.coinType} is forbidden.`,
@@ -1 +1 @@
1
- {"version":3,"file":"permittedCoinTypes.mjs","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,6BAA6B;AAEjE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,8BAA8B;AAE7E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,wBAAwB;AAE7D;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAAW;IAEX,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,cAAc,CAAC,kBAAkB;gBACvC,KAAK;aACN;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAc;IAEd,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QAC7D,MAAM,SAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,iDAAiD;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,IACE,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjC,KAAK,CAAC,QAAQ,GAAG,CAAC;QAClB,KAAK,CAAC,QAAQ,GAAG,UAAU,EAC3B,CAAC;QACD,MAAM,SAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EACL,yEAAyE;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,IAAI,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,aAAa,KAAK,CAAC,QAAQ,gBAAgB;SACrD,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA2B;IAC7D,IACE,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC;QAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EACzB,CAAC;QACD,MAAM,SAAS,CAAC,aAAa,CAAC;YAC5B,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,qCAAqC,GAG9C;IACF,CAAC,cAAc,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;QACjD,IAAI,EAAE,cAAc,CAAC,kBAAkB;QACvC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;YAC5B,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;gBACxB,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAE5B,MAAM,QAAQ,GAAI,MAAM,CAAC,KAAiC,CAAC,IAAI,CAC7D,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAC1D,CAAC;gBAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,cAAc,CAAC,YAAY,CAAC;wBAChC,OAAO,EACL,sGAAsG;qBACzG,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC;QACD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC;KACnD,CAAC;CACH,CAAC","sourcesContent":["import type {\n PermissionConstraint,\n RestrictedMethodCaveatSpecificationConstraint,\n Caveat,\n} from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { GetBip44EntropyParams } from '@metamask/snaps-sdk';\nimport { FORBIDDEN_COIN_TYPES, SnapCaveatType } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\n\n/**\n * Map a raw value from the `initialPermissions` to a caveat specification.\n * Note that this function does not do any validation, that's handled by the\n * PermissionsController when the permission is requested.\n *\n * @param value - The raw value from the `initialPermissions`.\n * @returns The caveat specification.\n */\nexport function permittedCoinTypesCaveatMapper(\n value: Json,\n): Pick<PermissionConstraint, 'caveats'> {\n return {\n caveats: [\n {\n type: SnapCaveatType.PermittedCoinTypes,\n value,\n },\n ],\n };\n}\n\n/**\n * Validate the params for `snap_getBip44Entropy`.\n *\n * @param value - The params to validate.\n * @throws If the params are invalid.\n */\nexport function validateBIP44Params(\n value: unknown,\n): asserts value is GetBip44EntropyParams {\n if (!isPlainObject(value) || !hasProperty(value, 'coinType')) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object containing a coin type.',\n });\n }\n\n if (\n typeof value.coinType !== 'number' ||\n !Number.isInteger(value.coinType) ||\n value.coinType < 0 ||\n value.coinType > 0x7fffffff\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"coinType\" parameter. Coin type must be a non-negative integer.',\n });\n }\n\n if (FORBIDDEN_COIN_TYPES.includes(value.coinType)) {\n throw rpcErrors.invalidParams({\n message: `Coin type ${value.coinType} is forbidden.`,\n });\n }\n}\n\n/**\n * Validate the coin types values associated with a caveat. This checks if the\n * values are non-negative integers (>= 0).\n *\n * @param caveat - The caveat to validate.\n * @throws If the caveat is invalid.\n */\nexport function validateBIP44Caveat(caveat: Caveat<string, any>) {\n if (\n !hasProperty(caveat, 'value') ||\n !Array.isArray(caveat.value) ||\n caveat.value.length === 0\n ) {\n throw rpcErrors.invalidParams({\n message: 'Expected non-empty array of coin types.',\n });\n }\n\n caveat.value.forEach(validateBIP44Params);\n}\n\nexport const PermittedCoinTypesCaveatSpecification: Record<\n SnapCaveatType.PermittedCoinTypes,\n RestrictedMethodCaveatSpecificationConstraint\n> = {\n [SnapCaveatType.PermittedCoinTypes]: Object.freeze({\n type: SnapCaveatType.PermittedCoinTypes,\n decorator: (method, caveat) => {\n return async (args) => {\n const { params } = args;\n validateBIP44Params(params);\n\n const coinType = (caveat.value as GetBip44EntropyParams[]).find(\n (caveatValue) => caveatValue.coinType === params.coinType,\n );\n\n if (!coinType) {\n throw providerErrors.unauthorized({\n message:\n 'The requested coin type is not permitted. Allowed coin types must be specified in the snap manifest.',\n });\n }\n\n return await method(args);\n };\n },\n validator: (caveat) => validateBIP44Caveat(caveat),\n }),\n};\n"]}
1
+ {"version":3,"file":"permittedCoinTypes.mjs","sourceRoot":"","sources":["../../../src/restricted/caveats/permittedCoinTypes.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PermissionConstraint,\n RestrictedMethodCaveatSpecificationConstraint,\n Caveat,\n} from '@metamask/permission-controller';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { GetBip44EntropyParams } from '@metamask/snaps-sdk';\nimport { FORBIDDEN_COIN_TYPES, SnapCaveatType } from '@metamask/snaps-utils';\nimport type { Json } from '@metamask/utils';\nimport { hasProperty, isPlainObject } from '@metamask/utils';\n\n/**\n * Map a raw value from the `initialPermissions` to a caveat specification.\n * Note that this function does not do any validation, that's handled by the\n * PermissionsController when the permission is requested.\n *\n * @param value - The raw value from the `initialPermissions`.\n * @returns The caveat specification.\n */\nexport function permittedCoinTypesCaveatMapper(\n value: Json,\n): Pick<PermissionConstraint, 'caveats'> {\n return {\n caveats: [\n {\n type: SnapCaveatType.PermittedCoinTypes,\n value,\n },\n ],\n };\n}\n\n/**\n * Validate the params for `snap_getBip44Entropy`.\n *\n * @param value - The params to validate.\n * @throws If the params are invalid.\n */\nexport function validateBIP44Params(\n value: unknown,\n): asserts value is GetBip44EntropyParams {\n if (!isPlainObject(value) || !hasProperty(value, 'coinType')) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object containing a coin type.',\n });\n }\n\n if (\n typeof value.coinType !== 'number' ||\n !Number.isInteger(value.coinType) ||\n value.coinType < 0 ||\n value.coinType > 0x7fffffff\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"coinType\" parameter. Coin type must be a non-negative integer.',\n });\n }\n\n if (\n hasProperty(value, 'source') &&\n typeof value.source !== 'undefined' &&\n typeof value.source !== 'string'\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid \"source\" parameter. Source must be a string if provided.',\n });\n }\n\n if (FORBIDDEN_COIN_TYPES.includes(value.coinType)) {\n throw rpcErrors.invalidParams({\n message: `Coin type ${value.coinType} is forbidden.`,\n });\n }\n}\n\n/**\n * Validate the coin types values associated with a caveat. This checks if the\n * values are non-negative integers (>= 0).\n *\n * @param caveat - The caveat to validate.\n * @throws If the caveat is invalid.\n */\nexport function validateBIP44Caveat(caveat: Caveat<string, any>) {\n if (\n !hasProperty(caveat, 'value') ||\n !Array.isArray(caveat.value) ||\n caveat.value.length === 0\n ) {\n throw rpcErrors.invalidParams({\n message: 'Expected non-empty array of coin types.',\n });\n }\n\n caveat.value.forEach(validateBIP44Params);\n}\n\nexport const PermittedCoinTypesCaveatSpecification: Record<\n SnapCaveatType.PermittedCoinTypes,\n RestrictedMethodCaveatSpecificationConstraint\n> = {\n [SnapCaveatType.PermittedCoinTypes]: Object.freeze({\n type: SnapCaveatType.PermittedCoinTypes,\n decorator: (method, caveat) => {\n return async (args) => {\n const { params } = args;\n validateBIP44Params(params);\n\n const coinType = (caveat.value as GetBip44EntropyParams[]).find(\n (caveatValue) => caveatValue.coinType === params.coinType,\n );\n\n if (!coinType) {\n throw providerErrors.unauthorized({\n message:\n 'The requested coin type is not permitted. Allowed coin types must be specified in the snap manifest.',\n });\n }\n\n return await method(args);\n };\n },\n validator: (caveat) => validateBIP44Caveat(caveat),\n }),\n};\n"]}
@@ -60,10 +60,11 @@ function getBip32EntropyImplementation({ getMnemonic, getUnlockPromise, getClien
60
60
  await getUnlockPromise(true);
61
61
  const { params } = args;
62
62
  (0, utils_1.assert)(params);
63
+ const secretRecoveryPhrase = await (0, utils_2.getSecretRecoveryPhrase)(getMnemonic, params.source);
63
64
  const node = await (0, utils_2.getNode)({
64
65
  curve: params.curve,
65
66
  path: params.path,
66
- secretRecoveryPhrase: await getMnemonic(),
67
+ secretRecoveryPhrase,
67
68
  cryptographicFunctions: getClientCryptography(),
68
69
  });
69
70
  return node.toJSON();
@@ -1 +1 @@
1
- {"version":3,"file":"getBip32Entropy.cjs","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":";;;AAOA,2EAA8E;AAC9E,qDAAiD;AAKjD,uDAAuD;AAEvD,2CAAyC;AAGzC,wCAAmC;AAEnC,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAqC1C;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAA8C,EAAE,EAAE;IAClE,OAAO;QACL,cAAc,EAAE,sCAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,4BAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,6BAA6B,CAAC,WAAW,CAAC;QAChE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,sBAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,4BAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,mCAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAkD;IACjE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEW,QAAA,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,SAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACM;IAC3B,OAAO,KAAK,UAAU,eAAe,CACnC,IAAoD;QAEpD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;QAEf,MAAM,IAAI,GAAG,MAAM,IAAA,eAAO,EAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB,EAAE,MAAM,WAAW,EAAE;YACzC,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAtBD,sEAsBC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32EntropyParams,\n GetBip32EntropyResult,\n} from '@metamask/snaps-sdk';\nimport { SnapCaveatType } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assert } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getNode } from '../utils';\n\nconst targetName = 'snap_getBip32Entropy';\n\nexport type GetBip32EntropyMethodHooks = {\n /**\n * @returns The mnemonic of the user's primary keyring.\n */\n getMnemonic: () => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32EntropySpecificationBuilderOptions = {\n methodHooks: GetBip32EntropyMethodHooks;\n};\n\ntype GetBip32EntropySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32EntropyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\n/**\n * The specification builder for the `snap_getBip32Entropy` permission.\n * `snap_getBip32Entropy` lets the Snap control private keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32Entropy` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32EntropySpecificationBuilderOptions,\n GetBip32EntropySpecification\n> = ({ methodHooks }: GetBip32EntropySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32EntropyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32EntropyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32EntropyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32Entropy`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a `JsonSLIP10Node`.\n * @throws If the params are invalid.\n */\nexport function getBip32EntropyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32EntropyMethodHooks) {\n return async function getBip32Entropy(\n args: RestrictedMethodOptions<GetBip32EntropyParams>,\n ): Promise<GetBip32EntropyResult> {\n await getUnlockPromise(true);\n\n const { params } = args;\n assert(params);\n\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase: await getMnemonic(),\n cryptographicFunctions: getClientCryptography(),\n });\n\n return node.toJSON();\n };\n}\n"]}
1
+ {"version":3,"file":"getBip32Entropy.cjs","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":";;;AAOA,2EAA8E;AAC9E,qDAAiD;AAKjD,uDAAuD;AAEvD,2CAAyC;AAGzC,wCAA4D;AAE5D,MAAM,UAAU,GAAG,sBAAsB,CAAC;AA0C1C;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAA8C,EAAE,EAAE;IAClE,OAAO;QACL,cAAc,EAAE,sCAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,4BAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,6BAA6B,CAAC,WAAW,CAAC;QAChE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,sBAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,4BAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,mCAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAkD;IACjE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEW,QAAA,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,SAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACM;IAC3B,OAAO,KAAK,UAAU,eAAe,CACnC,IAAoD;QAEpD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;QAEf,MAAM,oBAAoB,GAAG,MAAM,IAAA,+BAAuB,EACxD,WAAW,EACX,MAAM,CAAC,MAAM,CACd,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,IAAA,eAAO,EAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB;YACpB,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AA3BD,sEA2BC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32EntropyParams,\n GetBip32EntropyResult,\n} from '@metamask/snaps-sdk';\nimport { SnapCaveatType } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assert } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getSecretRecoveryPhrase, getNode } from '../utils';\n\nconst targetName = 'snap_getBip32Entropy';\n\nexport type GetBip32EntropyMethodHooks = {\n /**\n * Get the mnemonic of the provided source. If no source is provided, the\n * mnemonic of the primary keyring will be returned.\n *\n * @param source - The optional ID of the source to get the mnemonic of.\n * @returns The mnemonic of the provided source, or the default source if no\n * source is provided.\n */\n getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32EntropySpecificationBuilderOptions = {\n methodHooks: GetBip32EntropyMethodHooks;\n};\n\ntype GetBip32EntropySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32EntropyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\n/**\n * The specification builder for the `snap_getBip32Entropy` permission.\n * `snap_getBip32Entropy` lets the Snap control private keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32Entropy` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32EntropySpecificationBuilderOptions,\n GetBip32EntropySpecification\n> = ({ methodHooks }: GetBip32EntropySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32EntropyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32EntropyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32EntropyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32Entropy`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a `JsonSLIP10Node`.\n * @throws If the params are invalid.\n */\nexport function getBip32EntropyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32EntropyMethodHooks) {\n return async function getBip32Entropy(\n args: RestrictedMethodOptions<GetBip32EntropyParams>,\n ): Promise<GetBip32EntropyResult> {\n await getUnlockPromise(true);\n\n const { params } = args;\n assert(params);\n\n const secretRecoveryPhrase = await getSecretRecoveryPhrase(\n getMnemonic,\n params.source,\n );\n\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase,\n cryptographicFunctions: getClientCryptography(),\n });\n\n return node.toJSON();\n };\n}\n"]}
@@ -7,9 +7,14 @@ import type { MethodHooksObject } from "../utils.cjs";
7
7
  declare const targetName = "snap_getBip32Entropy";
8
8
  export type GetBip32EntropyMethodHooks = {
9
9
  /**
10
- * @returns The mnemonic of the user's primary keyring.
10
+ * Get the mnemonic of the provided source. If no source is provided, the
11
+ * mnemonic of the primary keyring will be returned.
12
+ *
13
+ * @param source - The optional ID of the source to get the mnemonic of.
14
+ * @returns The mnemonic of the provided source, or the default source if no
15
+ * source is provided.
11
16
  */
12
- getMnemonic: () => Promise<Uint8Array>;
17
+ getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;
13
18
  /**
14
19
  * Waits for the extension to be unlocked.
15
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"getBip32Entropy.d.cts","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AACjE,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,uBAAuB,EAExB,wCAAwC;AACzC,OAAO,EAAE,cAAc,EAAe,wCAAwC;AAE9E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAGlD,QAAA,MAAM,UAAU,yBAAyB,CAAC;AAE1C,MAAM,MAAM,0BAA0B,GAAG;IACvC;;OAEG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvC;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,sBAAsB,GAAG,SAAS,CAAC;CACjE,CAAC;AAEF,KAAK,0CAA0C,GAAG;IAChD,WAAW,EAAE,0BAA0B,CAAC;CACzC,CAAC;AAiDF,eAAO,MAAM,sBAAsB;;;wBA9CjB,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,oCAAoC,CAAC;wBACtD,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;mBAC3C,6BAA6B;;;EA8C/B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACtB,EAAE,0BAA0B,UAEnB,wBAAwB,qBAAqB,CAAC,KACnD,QAAQ,qBAAqB,CAAC,CAelC"}
1
+ {"version":3,"file":"getBip32Entropy.d.cts","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AACjE,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,uBAAuB,EAExB,wCAAwC;AACzC,OAAO,EAAE,cAAc,EAAe,wCAAwC;AAE9E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAGlD,QAAA,MAAM,UAAU,yBAAyB,CAAC;AAE1C,MAAM,MAAM,0BAA0B,GAAG;IACvC;;;;;;;OAOG;IACH,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,sBAAsB,GAAG,SAAS,CAAC;CACjE,CAAC;AAEF,KAAK,0CAA0C,GAAG;IAChD,WAAW,EAAE,0BAA0B,CAAC;CACzC,CAAC;AAiDF,eAAO,MAAM,sBAAsB;;;wBA9CjB,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,oCAAoC,CAAC;wBACtD,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;mBAC3C,6BAA6B;;;EA8C/B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACtB,EAAE,0BAA0B,UAEnB,wBAAwB,qBAAqB,CAAC,KACnD,QAAQ,qBAAqB,CAAC,CAoBlC"}
@@ -7,9 +7,14 @@ import type { MethodHooksObject } from "../utils.mjs";
7
7
  declare const targetName = "snap_getBip32Entropy";
8
8
  export type GetBip32EntropyMethodHooks = {
9
9
  /**
10
- * @returns The mnemonic of the user's primary keyring.
10
+ * Get the mnemonic of the provided source. If no source is provided, the
11
+ * mnemonic of the primary keyring will be returned.
12
+ *
13
+ * @param source - The optional ID of the source to get the mnemonic of.
14
+ * @returns The mnemonic of the provided source, or the default source if no
15
+ * source is provided.
11
16
  */
12
- getMnemonic: () => Promise<Uint8Array>;
17
+ getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;
13
18
  /**
14
19
  * Waits for the extension to be unlocked.
15
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"getBip32Entropy.d.mts","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AACjE,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,uBAAuB,EAExB,wCAAwC;AACzC,OAAO,EAAE,cAAc,EAAe,wCAAwC;AAE9E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAGlD,QAAA,MAAM,UAAU,yBAAyB,CAAC;AAE1C,MAAM,MAAM,0BAA0B,GAAG;IACvC;;OAEG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvC;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,sBAAsB,GAAG,SAAS,CAAC;CACjE,CAAC;AAEF,KAAK,0CAA0C,GAAG;IAChD,WAAW,EAAE,0BAA0B,CAAC;CACzC,CAAC;AAiDF,eAAO,MAAM,sBAAsB;;;wBA9CjB,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,oCAAoC,CAAC;wBACtD,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;mBAC3C,6BAA6B;;;EA8C/B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACtB,EAAE,0BAA0B,UAEnB,wBAAwB,qBAAqB,CAAC,KACnD,QAAQ,qBAAqB,CAAC,CAelC"}
1
+ {"version":3,"file":"getBip32Entropy.d.mts","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AACjE,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,uBAAuB,EAExB,wCAAwC;AACzC,OAAO,EAAE,cAAc,EAAe,wCAAwC;AAE9E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAGlD,QAAA,MAAM,UAAU,yBAAyB,CAAC;AAE1C,MAAM,MAAM,0BAA0B,GAAG;IACvC;;;;;;;OAOG;IACH,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,uBAAuB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtE;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,sBAAsB,GAAG,SAAS,CAAC;CACjE,CAAC;AAEF,KAAK,0CAA0C,GAAG;IAChD,WAAW,EAAE,0BAA0B,CAAC;CACzC,CAAC;AAiDF,eAAO,MAAM,sBAAsB;;;wBA9CjB,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,oCAAoC,CAAC;wBACtD,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;mBAC3C,6BAA6B;;;EA8C/B,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACtB,EAAE,0BAA0B,UAEnB,wBAAwB,qBAAqB,CAAC,KACnD,QAAQ,qBAAqB,CAAC,CAoBlC"}
@@ -2,7 +2,7 @@ import { PermissionType, SubjectType } from "@metamask/permission-controller";
2
2
  import { rpcErrors } from "@metamask/rpc-errors";
3
3
  import { SnapCaveatType } from "@metamask/snaps-utils";
4
4
  import { assert } from "@metamask/utils";
5
- import { getNode } from "../utils.mjs";
5
+ import { getSecretRecoveryPhrase, getNode } from "../utils.mjs";
6
6
  const targetName = 'snap_getBip32Entropy';
7
7
  /**
8
8
  * The specification builder for the `snap_getBip32Entropy` permission.
@@ -57,10 +57,11 @@ export function getBip32EntropyImplementation({ getMnemonic, getUnlockPromise, g
57
57
  await getUnlockPromise(true);
58
58
  const { params } = args;
59
59
  assert(params);
60
+ const secretRecoveryPhrase = await getSecretRecoveryPhrase(getMnemonic, params.source);
60
61
  const node = await getNode({
61
62
  curve: params.curve,
62
63
  path: params.path,
63
- secretRecoveryPhrase: await getMnemonic(),
64
+ secretRecoveryPhrase,
64
65
  cryptographicFunctions: getClientCryptography(),
65
66
  });
66
67
  return node.toJSON();
@@ -1 +1 @@
1
- {"version":3,"file":"getBip32Entropy.mjs","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,wCAAwC;AAC9E,OAAO,EAAE,SAAS,EAAE,6BAA6B;AAKjD,OAAO,EAAE,cAAc,EAAE,8BAA8B;AAEvD,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAGzC,OAAO,EAAE,OAAO,EAAE,qBAAiB;AAEnC,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAqC1C;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAA8C,EAAE,EAAE;IAClE,OAAO;QACL,cAAc,EAAE,cAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,cAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,6BAA6B,CAAC,WAAW,CAAC;QAChE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,SAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,cAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAkD;IACjE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACM;IAC3B,OAAO,KAAK,UAAU,eAAe,CACnC,IAAoD;QAEpD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,MAAM,CAAC,CAAC;QAEf,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB,EAAE,MAAM,WAAW,EAAE;YACzC,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32EntropyParams,\n GetBip32EntropyResult,\n} from '@metamask/snaps-sdk';\nimport { SnapCaveatType } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assert } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getNode } from '../utils';\n\nconst targetName = 'snap_getBip32Entropy';\n\nexport type GetBip32EntropyMethodHooks = {\n /**\n * @returns The mnemonic of the user's primary keyring.\n */\n getMnemonic: () => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32EntropySpecificationBuilderOptions = {\n methodHooks: GetBip32EntropyMethodHooks;\n};\n\ntype GetBip32EntropySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32EntropyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\n/**\n * The specification builder for the `snap_getBip32Entropy` permission.\n * `snap_getBip32Entropy` lets the Snap control private keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32Entropy` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32EntropySpecificationBuilderOptions,\n GetBip32EntropySpecification\n> = ({ methodHooks }: GetBip32EntropySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32EntropyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32EntropyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32EntropyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32Entropy`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a `JsonSLIP10Node`.\n * @throws If the params are invalid.\n */\nexport function getBip32EntropyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32EntropyMethodHooks) {\n return async function getBip32Entropy(\n args: RestrictedMethodOptions<GetBip32EntropyParams>,\n ): Promise<GetBip32EntropyResult> {\n await getUnlockPromise(true);\n\n const { params } = args;\n assert(params);\n\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase: await getMnemonic(),\n cryptographicFunctions: getClientCryptography(),\n });\n\n return node.toJSON();\n };\n}\n"]}
1
+ {"version":3,"file":"getBip32Entropy.mjs","sourceRoot":"","sources":["../../src/restricted/getBip32Entropy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,wCAAwC;AAC9E,OAAO,EAAE,SAAS,EAAE,6BAA6B;AAKjD,OAAO,EAAE,cAAc,EAAE,8BAA8B;AAEvD,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAGzC,OAAO,EAAE,uBAAuB,EAAE,OAAO,EAAE,qBAAiB;AAE5D,MAAM,UAAU,GAAG,sBAAsB,CAAC;AA0C1C;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAA8C,EAAE,EAAE;IAClE,OAAO;QACL,cAAc,EAAE,cAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,cAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,6BAA6B,CAAC,WAAW,CAAC;QAChE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,SAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,cAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAkD;IACjE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAAC,EAC5C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACM;IAC3B,OAAO,KAAK,UAAU,eAAe,CACnC,IAAoD;QAEpD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,MAAM,CAAC,CAAC;QAEf,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,CACxD,WAAW,EACX,MAAM,CAAC,MAAM,CACd,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB;YACpB,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32EntropyParams,\n GetBip32EntropyResult,\n} from '@metamask/snaps-sdk';\nimport { SnapCaveatType } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assert } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getSecretRecoveryPhrase, getNode } from '../utils';\n\nconst targetName = 'snap_getBip32Entropy';\n\nexport type GetBip32EntropyMethodHooks = {\n /**\n * Get the mnemonic of the provided source. If no source is provided, the\n * mnemonic of the primary keyring will be returned.\n *\n * @param source - The optional ID of the source to get the mnemonic of.\n * @returns The mnemonic of the provided source, or the default source if no\n * source is provided.\n */\n getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32EntropySpecificationBuilderOptions = {\n methodHooks: GetBip32EntropyMethodHooks;\n};\n\ntype GetBip32EntropySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32EntropyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\n/**\n * The specification builder for the `snap_getBip32Entropy` permission.\n * `snap_getBip32Entropy` lets the Snap control private keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32Entropy` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32EntropySpecificationBuilderOptions,\n GetBip32EntropySpecification\n> = ({ methodHooks }: GetBip32EntropySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32EntropyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32EntropyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32EntropyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32Entropy`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a `JsonSLIP10Node`.\n * @throws If the params are invalid.\n */\nexport function getBip32EntropyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32EntropyMethodHooks) {\n return async function getBip32Entropy(\n args: RestrictedMethodOptions<GetBip32EntropyParams>,\n ): Promise<GetBip32EntropyResult> {\n await getUnlockPromise(true);\n\n const { params } = args;\n assert(params);\n\n const secretRecoveryPhrase = await getSecretRecoveryPhrase(\n getMnemonic,\n params.source,\n );\n\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase,\n cryptographicFunctions: getClientCryptography(),\n });\n\n return node.toJSON();\n };\n}\n"]}
@@ -12,6 +12,7 @@ exports.Bip32PublicKeyArgsStruct = (0, snaps_utils_1.bip32entropy)((0, superstru
12
12
  path: snaps_utils_1.Bip32PathStruct,
13
13
  curve: snaps_utils_1.CurveStruct,
14
14
  compressed: (0, superstruct_1.optional)((0, superstruct_1.boolean)()),
15
+ source: (0, superstruct_1.optional)((0, superstruct_1.string)()),
15
16
  }));
16
17
  /**
17
18
  * The specification builder for the `snap_getBip32PublicKey` permission.
@@ -66,10 +67,11 @@ function getBip32PublicKeyImplementation({ getMnemonic, getUnlockPromise, getCli
66
67
  await getUnlockPromise(true);
67
68
  (0, utils_1.assertStruct)(args.params, exports.Bip32PublicKeyArgsStruct, 'Invalid BIP-32 public key params', rpc_errors_1.rpcErrors.invalidParams);
68
69
  const { params } = args;
70
+ const secretRecoveryPhrase = await (0, utils_2.getSecretRecoveryPhrase)(getMnemonic, params.source);
69
71
  const node = await (0, utils_2.getNode)({
70
72
  curve: params.curve,
71
73
  path: params.path,
72
- secretRecoveryPhrase: await getMnemonic(),
74
+ secretRecoveryPhrase,
73
75
  cryptographicFunctions: getClientCryptography(),
74
76
  });
75
77
  if (params.compressed) {
@@ -1 +1 @@
1
- {"version":3,"file":"getBip32PublicKey.cjs","sourceRoot":"","sources":["../../src/restricted/getBip32PublicKey.ts"],"names":[],"mappings":";;;AAOA,2EAA8E;AAC9E,qDAAiD;AAKjD,uDAK+B;AAC/B,uDAAkE;AAElE,2CAA+C;AAG/C,wCAAmC;AAEnC,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAqC/B,QAAA,wBAAwB,GAAG,IAAA,0BAAY,EAClD,IAAA,oBAAM,EAAC;IACL,IAAI,EAAE,6BAAe;IACrB,KAAK,EAAE,yBAAW;IAClB,UAAU,EAAE,IAAA,sBAAQ,EAAC,IAAA,qBAAO,GAAE,CAAC;CAChC,CAAC,CACH,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAAgD,EAAE,EAAE;IACpE,OAAO;QACL,cAAc,EAAE,sCAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,4BAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,+BAA+B,CAAC,WAAW,CAAC;QAClE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,sBAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,4BAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,mCAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAoD;IACnE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEW,QAAA,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACQ;IAC7B,OAAO,KAAK,UAAU,iBAAiB,CACrC,IAAsD;QAEtD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAA,oBAAY,EACV,IAAI,CAAC,MAAM,EACX,gCAAwB,EACxB,kCAAkC,EAClC,sBAAS,CAAC,aAAa,CACxB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,IAAA,eAAO,EAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB,EAAE,MAAM,WAAW,EAAE;YACzC,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,mBAAmB,CAAC;QAClC,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC;AA/BD,0EA+BC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32PublicKeyParams,\n GetBip32PublicKeyResult,\n} from '@metamask/snaps-sdk';\nimport {\n bip32entropy,\n Bip32PathStruct,\n CurveStruct,\n SnapCaveatType,\n} from '@metamask/snaps-utils';\nimport { boolean, object, optional } from '@metamask/superstruct';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assertStruct } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getNode } from '../utils';\n\nconst targetName = 'snap_getBip32PublicKey';\n\nexport type GetBip32PublicKeyMethodHooks = {\n /**\n * @returns The mnemonic of the user's primary keyring.\n */\n getMnemonic: () => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32PublicKeySpecificationBuilderOptions = {\n methodHooks: GetBip32PublicKeyMethodHooks;\n};\n\ntype GetBip32PublicKeySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32PublicKeyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\nexport const Bip32PublicKeyArgsStruct = bip32entropy(\n object({\n path: Bip32PathStruct,\n curve: CurveStruct,\n compressed: optional(boolean()),\n }),\n);\n\n/**\n * The specification builder for the `snap_getBip32PublicKey` permission.\n * `snap_getBip32PublicKey` lets the Snap retrieve public keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32PublicKey` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32PublicKeySpecificationBuilderOptions,\n GetBip32PublicKeySpecification\n> = ({ methodHooks }: GetBip32PublicKeySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32PublicKeyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32PublicKeyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32PublicKeyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32PublicKey`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a public key.\n * @throws If the params are invalid.\n */\nexport function getBip32PublicKeyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32PublicKeyMethodHooks) {\n return async function getBip32PublicKey(\n args: RestrictedMethodOptions<GetBip32PublicKeyParams>,\n ): Promise<GetBip32PublicKeyResult> {\n await getUnlockPromise(true);\n\n assertStruct(\n args.params,\n Bip32PublicKeyArgsStruct,\n 'Invalid BIP-32 public key params',\n rpcErrors.invalidParams,\n );\n\n const { params } = args;\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase: await getMnemonic(),\n cryptographicFunctions: getClientCryptography(),\n });\n\n if (params.compressed) {\n return node.compressedPublicKey;\n }\n\n return node.publicKey;\n };\n}\n"]}
1
+ {"version":3,"file":"getBip32PublicKey.cjs","sourceRoot":"","sources":["../../src/restricted/getBip32PublicKey.ts"],"names":[],"mappings":";;;AAOA,2EAA8E;AAC9E,qDAAiD;AAKjD,uDAK+B;AAC/B,uDAA0E;AAE1E,2CAA+C;AAG/C,wCAA4D;AAE5D,MAAM,UAAU,GAAG,wBAAwB,CAAC;AA0C/B,QAAA,wBAAwB,GAAG,IAAA,0BAAY,EAClD,IAAA,oBAAM,EAAC;IACL,IAAI,EAAE,6BAAe;IACrB,KAAK,EAAE,yBAAW;IAClB,UAAU,EAAE,IAAA,sBAAQ,EAAC,IAAA,qBAAO,GAAE,CAAC;IAC/B,MAAM,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;CAC3B,CAAC,CACH,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAItB,CAAC,EAAE,WAAW,EAAgD,EAAE,EAAE;IACpE,OAAO;QACL,cAAc,EAAE,sCAAc,CAAC,gBAAgB;QAC/C,UAAU;QACV,cAAc,EAAE,CAAC,4BAAc,CAAC,wBAAwB,CAAC;QACzD,oBAAoB,EAAE,+BAA+B,CAAC,WAAW,CAAC;QAClE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACzB,IACE,OAAO,EAAE,MAAM,KAAK,CAAC;gBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAc,CAAC,wBAAwB,EAC3D,CAAC;gBACD,MAAM,sBAAS,CAAC,aAAa,CAAC;oBAC5B,OAAO,EAAE,sBAAsB,4BAAc,CAAC,wBAAwB,WAAW;iBAClF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,YAAY,EAAE,CAAC,mCAAW,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAoD;IACnE,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEW,QAAA,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,UAAU;IACV,oBAAoB;IACpB,WAAW;CACH,CAAC,CAAC;AAEZ;;;;;;;;;;;GAWG;AACH,SAAgB,+BAA+B,CAAC,EAC9C,WAAW,EACX,gBAAgB,EAChB,qBAAqB,GACQ;IAC7B,OAAO,KAAK,UAAU,iBAAiB,CACrC,IAAsD;QAEtD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAA,oBAAY,EACV,IAAI,CAAC,MAAM,EACX,gCAAwB,EACxB,kCAAkC,EAClC,sBAAS,CAAC,aAAa,CACxB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACxB,MAAM,oBAAoB,GAAG,MAAM,IAAA,+BAAuB,EACxD,WAAW,EACX,MAAM,CAAC,MAAM,CACd,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,IAAA,eAAO,EAAC;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,oBAAoB;YACpB,sBAAsB,EAAE,qBAAqB,EAAE;SAChD,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,mBAAmB,CAAC;QAClC,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC;AApCD,0EAoCC","sourcesContent":["import type { CryptographicFunctions } from '@metamask/key-tree';\nimport type {\n PermissionSpecificationBuilder,\n PermissionValidatorConstraint,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n GetBip32PublicKeyParams,\n GetBip32PublicKeyResult,\n} from '@metamask/snaps-sdk';\nimport {\n bip32entropy,\n Bip32PathStruct,\n CurveStruct,\n SnapCaveatType,\n} from '@metamask/snaps-utils';\nimport { boolean, object, optional, string } from '@metamask/superstruct';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { assertStruct } from '@metamask/utils';\n\nimport type { MethodHooksObject } from '../utils';\nimport { getSecretRecoveryPhrase, getNode } from '../utils';\n\nconst targetName = 'snap_getBip32PublicKey';\n\nexport type GetBip32PublicKeyMethodHooks = {\n /**\n * Get the mnemonic of the provided source. If no source is provided, the\n * mnemonic of the primary keyring will be returned.\n *\n * @param source - The optional ID of the source to get the mnemonic of.\n * @returns The mnemonic of the provided source, or the default source if no\n * source is provided.\n */\n getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;\n\n /**\n * Waits for the extension to be unlocked.\n *\n * @returns A promise that resolves once the extension is unlocked.\n */\n getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;\n\n /**\n * Get the cryptographic functions to use for the client. This may return an\n * empty object or `undefined` to fall back to the default cryptographic\n * functions.\n *\n * @returns The cryptographic functions to use for the client.\n */\n getClientCryptography: () => CryptographicFunctions | undefined;\n};\n\ntype GetBip32PublicKeySpecificationBuilderOptions = {\n methodHooks: GetBip32PublicKeyMethodHooks;\n};\n\ntype GetBip32PublicKeySpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof targetName;\n methodImplementation: ReturnType<typeof getBip32PublicKeyImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n validator: PermissionValidatorConstraint;\n}>;\n\nexport const Bip32PublicKeyArgsStruct = bip32entropy(\n object({\n path: Bip32PathStruct,\n curve: CurveStruct,\n compressed: optional(boolean()),\n source: optional(string()),\n }),\n);\n\n/**\n * The specification builder for the `snap_getBip32PublicKey` permission.\n * `snap_getBip32PublicKey` lets the Snap retrieve public keys for a particular\n * BIP-32 node.\n *\n * @param options - The specification builder options.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_getBip32PublicKey` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n GetBip32PublicKeySpecificationBuilderOptions,\n GetBip32PublicKeySpecification\n> = ({ methodHooks }: GetBip32PublicKeySpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName,\n allowedCaveats: [SnapCaveatType.PermittedDerivationPaths],\n methodImplementation: getBip32PublicKeyImplementation(methodHooks),\n validator: ({ caveats }) => {\n if (\n caveats?.length !== 1 ||\n caveats[0].type !== SnapCaveatType.PermittedDerivationPaths\n ) {\n throw rpcErrors.invalidParams({\n message: `Expected a single \"${SnapCaveatType.PermittedDerivationPaths}\" caveat.`,\n });\n }\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<GetBip32PublicKeyMethodHooks> = {\n getMnemonic: true,\n getUnlockPromise: true,\n getClientCryptography: true,\n};\n\nexport const getBip32PublicKeyBuilder = Object.freeze({\n targetName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_getBip32PublicKey`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.getMnemonic - A function to retrieve the Secret Recovery Phrase of the user.\n * @param hooks.getUnlockPromise - A function that resolves once the MetaMask extension is unlocked\n * and prompts the user to unlock their MetaMask if it is locked.\n * @param hooks.getClientCryptography - A function to retrieve the cryptographic\n * functions to use for the client.\n * @returns The method implementation which returns a public key.\n * @throws If the params are invalid.\n */\nexport function getBip32PublicKeyImplementation({\n getMnemonic,\n getUnlockPromise,\n getClientCryptography,\n}: GetBip32PublicKeyMethodHooks) {\n return async function getBip32PublicKey(\n args: RestrictedMethodOptions<GetBip32PublicKeyParams>,\n ): Promise<GetBip32PublicKeyResult> {\n await getUnlockPromise(true);\n\n assertStruct(\n args.params,\n Bip32PublicKeyArgsStruct,\n 'Invalid BIP-32 public key params',\n rpcErrors.invalidParams,\n );\n\n const { params } = args;\n const secretRecoveryPhrase = await getSecretRecoveryPhrase(\n getMnemonic,\n params.source,\n );\n\n const node = await getNode({\n curve: params.curve,\n path: params.path,\n secretRecoveryPhrase,\n cryptographicFunctions: getClientCryptography(),\n });\n\n if (params.compressed) {\n return node.compressedPublicKey;\n }\n\n return node.publicKey;\n };\n}\n"]}
@@ -7,9 +7,14 @@ import type { MethodHooksObject } from "../utils.cjs";
7
7
  declare const targetName = "snap_getBip32PublicKey";
8
8
  export type GetBip32PublicKeyMethodHooks = {
9
9
  /**
10
- * @returns The mnemonic of the user's primary keyring.
10
+ * Get the mnemonic of the provided source. If no source is provided, the
11
+ * mnemonic of the primary keyring will be returned.
12
+ *
13
+ * @param source - The optional ID of the source to get the mnemonic of.
14
+ * @returns The mnemonic of the provided source, or the default source if no
15
+ * source is provided.
11
16
  */
12
- getMnemonic: () => Promise<Uint8Array>;
17
+ getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;
13
18
  /**
14
19
  * Waits for the extension to be unlocked.
15
20
  *
@@ -31,11 +36,13 @@ type GetBip32PublicKeySpecificationBuilderOptions = {
31
36
  export declare const Bip32PublicKeyArgsStruct: import("@metamask/superstruct").Struct<{
32
37
  curve: "ed25519" | "ed25519Bip32" | "secp256k1";
33
38
  path: string[];
39
+ source?: string | undefined;
34
40
  compressed?: boolean | undefined;
35
41
  }, {
36
42
  path: import("@metamask/superstruct").Struct<string[], import("@metamask/superstruct").Struct<string, null>>;
37
43
  curve: import("@metamask/superstruct").Describe<"ed25519" | "ed25519Bip32" | "secp256k1">;
38
44
  compressed: import("@metamask/superstruct").Struct<boolean | undefined, null>;
45
+ source: import("@metamask/superstruct").Struct<string | undefined, null>;
39
46
  }>;
40
47
  export declare const getBip32PublicKeyBuilder: Readonly<{
41
48
  readonly targetName: "snap_getBip32PublicKey";