@metamask/snaps-rpc-methods 5.0.0 → 6.0.0

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 +15 -3
  2. package/dist/cjs/endowments/caveats/generic.js +40 -0
  3. package/dist/cjs/endowments/caveats/generic.js.map +1 -0
  4. package/dist/cjs/endowments/caveats/index.js +21 -0
  5. package/dist/cjs/endowments/caveats/index.js.map +1 -0
  6. package/dist/cjs/endowments/caveats/requestTime.js +99 -0
  7. package/dist/cjs/endowments/caveats/requestTime.js.map +1 -0
  8. package/dist/cjs/endowments/cronjob.js +100 -0
  9. package/dist/cjs/endowments/cronjob.js.map +1 -0
  10. package/dist/cjs/endowments/enum.js +26 -0
  11. package/dist/cjs/endowments/enum.js.map +1 -0
  12. package/dist/cjs/endowments/ethereum-provider.js +43 -0
  13. package/dist/cjs/endowments/ethereum-provider.js.map +1 -0
  14. package/dist/cjs/endowments/home-page.js +37 -0
  15. package/dist/cjs/endowments/home-page.js.map +1 -0
  16. package/dist/cjs/endowments/index.js +121 -0
  17. package/dist/cjs/endowments/index.js.map +1 -0
  18. package/dist/cjs/endowments/keyring.js +104 -0
  19. package/dist/cjs/endowments/keyring.js.map +1 -0
  20. package/dist/cjs/endowments/lifecycle-hooks.js +37 -0
  21. package/dist/cjs/endowments/lifecycle-hooks.js.map +1 -0
  22. package/dist/cjs/endowments/name-lookup.js +148 -0
  23. package/dist/cjs/endowments/name-lookup.js.map +1 -0
  24. package/dist/cjs/endowments/network-access.js +44 -0
  25. package/dist/cjs/endowments/network-access.js.map +1 -0
  26. package/dist/cjs/endowments/rpc.js +103 -0
  27. package/dist/cjs/endowments/rpc.js.map +1 -0
  28. package/dist/cjs/endowments/signature-insight.js +110 -0
  29. package/dist/cjs/endowments/signature-insight.js.map +1 -0
  30. package/dist/cjs/endowments/transaction-insight.js +111 -0
  31. package/dist/cjs/endowments/transaction-insight.js.map +1 -0
  32. package/dist/cjs/endowments/web-assembly.js +42 -0
  33. package/dist/cjs/endowments/web-assembly.js.map +1 -0
  34. package/dist/cjs/index.js +3 -1
  35. package/dist/cjs/index.js.map +1 -1
  36. package/dist/cjs/permissions.js +62 -0
  37. package/dist/cjs/permissions.js.map +1 -0
  38. package/dist/cjs/permitted/createInterface.js +68 -0
  39. package/dist/cjs/permitted/createInterface.js.map +1 -0
  40. package/dist/cjs/permitted/getFile.js +1 -1
  41. package/dist/cjs/permitted/getFile.js.map +1 -1
  42. package/dist/cjs/permitted/getInterfaceState.js +67 -0
  43. package/dist/cjs/permitted/getInterfaceState.js.map +1 -0
  44. package/dist/cjs/permitted/handlers.js +7 -1
  45. package/dist/cjs/permitted/handlers.js.map +1 -1
  46. package/dist/cjs/permitted/index.js.map +1 -1
  47. package/dist/cjs/permitted/updateInterface.js +70 -0
  48. package/dist/cjs/permitted/updateInterface.js.map +1 -0
  49. package/dist/cjs/restricted/dialog.js +51 -24
  50. package/dist/cjs/restricted/dialog.js.map +1 -1
  51. package/dist/esm/endowments/caveats/generic.js +40 -0
  52. package/dist/esm/endowments/caveats/generic.js.map +1 -0
  53. package/dist/esm/endowments/caveats/index.js +4 -0
  54. package/dist/esm/endowments/caveats/index.js.map +1 -0
  55. package/dist/esm/endowments/caveats/requestTime.js +93 -0
  56. package/dist/esm/endowments/caveats/requestTime.js.map +1 -0
  57. package/dist/esm/endowments/cronjob.js +99 -0
  58. package/dist/esm/endowments/cronjob.js.map +1 -0
  59. package/dist/esm/endowments/enum.js +16 -0
  60. package/dist/esm/endowments/enum.js.map +1 -0
  61. package/dist/esm/endowments/ethereum-provider.js +33 -0
  62. package/dist/esm/endowments/ethereum-provider.js.map +1 -0
  63. package/dist/esm/endowments/home-page.js +27 -0
  64. package/dist/esm/endowments/home-page.js.map +1 -0
  65. package/dist/esm/endowments/index.js +68 -0
  66. package/dist/esm/endowments/index.js.map +1 -0
  67. package/dist/esm/endowments/keyring.js +95 -0
  68. package/dist/esm/endowments/keyring.js.map +1 -0
  69. package/dist/esm/endowments/lifecycle-hooks.js +27 -0
  70. package/dist/esm/endowments/lifecycle-hooks.js.map +1 -0
  71. package/dist/esm/endowments/name-lookup.js +146 -0
  72. package/dist/esm/endowments/name-lookup.js.map +1 -0
  73. package/dist/esm/endowments/network-access.js +34 -0
  74. package/dist/esm/endowments/network-access.js.map +1 -0
  75. package/dist/esm/endowments/rpc.js +92 -0
  76. package/dist/esm/endowments/rpc.js.map +1 -0
  77. package/dist/esm/endowments/signature-insight.js +103 -0
  78. package/dist/esm/endowments/signature-insight.js.map +1 -0
  79. package/dist/esm/endowments/transaction-insight.js +104 -0
  80. package/dist/esm/endowments/transaction-insight.js.map +1 -0
  81. package/dist/esm/endowments/web-assembly.js +32 -0
  82. package/dist/esm/endowments/web-assembly.js.map +1 -0
  83. package/dist/esm/index.js +3 -1
  84. package/dist/esm/index.js.map +1 -1
  85. package/dist/esm/permissions.js +51 -0
  86. package/dist/esm/permissions.js.map +1 -0
  87. package/dist/esm/permitted/createInterface.js +58 -0
  88. package/dist/esm/permitted/createInterface.js.map +1 -0
  89. package/dist/esm/permitted/getFile.js +1 -1
  90. package/dist/esm/permitted/getFile.js.map +1 -1
  91. package/dist/esm/permitted/getInterfaceState.js +57 -0
  92. package/dist/esm/permitted/getInterfaceState.js.map +1 -0
  93. package/dist/esm/permitted/handlers.js +7 -1
  94. package/dist/esm/permitted/handlers.js.map +1 -1
  95. package/dist/esm/permitted/index.js.map +1 -1
  96. package/dist/esm/permitted/updateInterface.js +60 -0
  97. package/dist/esm/permitted/updateInterface.js.map +1 -0
  98. package/dist/esm/restricted/dialog.js +55 -29
  99. package/dist/esm/restricted/dialog.js.map +1 -1
  100. package/dist/types/endowments/caveats/generic.d.ts +19 -0
  101. package/dist/types/endowments/caveats/index.d.ts +2 -0
  102. package/dist/types/endowments/caveats/requestTime.d.ts +29 -0
  103. package/dist/types/endowments/cronjob.d.ts +51 -0
  104. package/dist/types/endowments/enum.d.ts +13 -0
  105. package/dist/types/endowments/ethereum-provider.d.ts +14 -0
  106. package/dist/types/endowments/home-page.d.ts +15 -0
  107. package/dist/types/endowments/index.d.ts +131 -0
  108. package/dist/types/endowments/keyring.d.ts +39 -0
  109. package/dist/types/endowments/lifecycle-hooks.d.ts +15 -0
  110. package/dist/types/endowments/name-lookup.d.ts +49 -0
  111. package/dist/types/endowments/network-access.d.ts +14 -0
  112. package/dist/types/endowments/rpc.d.ts +38 -0
  113. package/dist/types/endowments/signature-insight.d.ts +39 -0
  114. package/dist/types/endowments/transaction-insight.d.ts +39 -0
  115. package/dist/types/endowments/web-assembly.d.ts +14 -0
  116. package/dist/types/index.d.ts +4 -2
  117. package/dist/types/permissions.d.ts +16 -0
  118. package/dist/types/permitted/createInterface.d.ts +150 -0
  119. package/dist/types/permitted/getInterfaceState.d.ts +18 -0
  120. package/dist/types/permitted/handlers.d.ts +4 -1
  121. package/dist/types/permitted/index.d.ts +4 -1
  122. package/dist/types/permitted/updateInterface.d.ts +152 -0
  123. package/dist/types/restricted/dialog.d.ts +776 -14
  124. package/package.json +5 -5
@@ -20,6 +20,7 @@ const _permissioncontroller = require("@metamask/permission-controller");
20
20
  const _rpcerrors = require("@metamask/rpc-errors");
21
21
  const _snapssdk = require("@metamask/snaps-sdk");
22
22
  const _snapsutils = require("@metamask/snaps-utils");
23
+ const _utils = require("@metamask/utils");
23
24
  const _superstruct = require("superstruct");
24
25
  const methodName = 'snap_dialog';
25
26
  const PlaceholderStruct = (0, _superstruct.optional)((0, _superstruct.size)((0, _superstruct.string)(), 1, 40));
@@ -49,8 +50,8 @@ const PlaceholderStruct = (0, _superstruct.optional)((0, _superstruct.size)((0,
49
50
  };
50
51
  const methodHooks = {
51
52
  showDialog: true,
52
- isOnPhishingList: true,
53
- maybeUpdatePhishingList: true
53
+ createInterface: true,
54
+ getInterface: true
54
55
  };
55
56
  const dialogBuilder = Object.freeze({
56
57
  targetName: methodName,
@@ -66,20 +67,45 @@ const BaseParamsStruct = (0, _superstruct.type)({
66
67
  _snapssdk.DialogType.Prompt
67
68
  ])
68
69
  });
69
- const AlertParametersStruct = (0, _superstruct.object)({
70
+ const AlertParametersWithContentStruct = (0, _superstruct.object)({
70
71
  type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Alert),
71
72
  content: _snapssdk.ComponentStruct
72
73
  });
73
- const ConfirmationParametersStruct = (0, _superstruct.object)({
74
+ const AlertParametersWithIdStruct = (0, _superstruct.object)({
75
+ type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Alert),
76
+ id: (0, _superstruct.string)()
77
+ });
78
+ const AlertParametersStruct = (0, _snapssdk.union)([
79
+ AlertParametersWithContentStruct,
80
+ AlertParametersWithIdStruct
81
+ ]);
82
+ const ConfirmationParametersWithContentStruct = (0, _superstruct.object)({
74
83
  type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Confirmation),
75
84
  content: _snapssdk.ComponentStruct
76
85
  });
77
- const PromptParametersStruct = (0, _superstruct.object)({
86
+ const ConfirmationParametersWithIdStruct = (0, _superstruct.object)({
87
+ type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Confirmation),
88
+ id: (0, _superstruct.string)()
89
+ });
90
+ const ConfirmationParametersStruct = (0, _snapssdk.union)([
91
+ ConfirmationParametersWithContentStruct,
92
+ ConfirmationParametersWithIdStruct
93
+ ]);
94
+ const PromptParametersWithContentStruct = (0, _superstruct.object)({
78
95
  type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Prompt),
79
96
  content: _snapssdk.ComponentStruct,
80
97
  placeholder: PlaceholderStruct
81
98
  });
82
- const DialogParametersStruct = (0, _superstruct.union)([
99
+ const PromptParametersWithIdStruct = (0, _superstruct.object)({
100
+ type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Prompt),
101
+ id: (0, _superstruct.string)(),
102
+ placeholder: PlaceholderStruct
103
+ });
104
+ const PromptParametersStruct = (0, _snapssdk.union)([
105
+ PromptParametersWithContentStruct,
106
+ PromptParametersWithIdStruct
107
+ ]);
108
+ const DialogParametersStruct = (0, _snapssdk.union)([
83
109
  AlertParametersStruct,
84
110
  ConfirmationParametersStruct,
85
111
  PromptParametersStruct
@@ -89,16 +115,26 @@ const structs = {
89
115
  [_snapssdk.DialogType.Confirmation]: ConfirmationParametersStruct,
90
116
  [_snapssdk.DialogType.Prompt]: PromptParametersStruct
91
117
  };
92
- function getDialogImplementation({ showDialog, isOnPhishingList, maybeUpdatePhishingList }) {
118
+ function getDialogImplementation({ showDialog, createInterface, getInterface }) {
93
119
  return async function dialogImplementation(args) {
94
120
  const { params, context: { origin } } = args;
95
121
  const validatedType = getValidatedType(params);
96
122
  const validatedParams = getValidatedParams(params, structs[validatedType]);
97
- const { content } = validatedParams;
98
- await maybeUpdatePhishingList();
99
- (0, _snapsutils.validateComponentLinks)(content, isOnPhishingList);
100
123
  const placeholder = validatedParams.type === _snapssdk.DialogType.Prompt ? validatedParams.placeholder : undefined;
101
- return showDialog(origin, validatedType, content, placeholder);
124
+ if ((0, _utils.hasProperty)(validatedParams, 'content')) {
125
+ const id = await createInterface(origin, validatedParams.content);
126
+ return showDialog(origin, validatedType, id, placeholder);
127
+ }
128
+ // Verify that the passed interface ID is valid.
129
+ // This will throw if the interface ID is invalid (not created by the snap or doesn't exist)
130
+ try {
131
+ getInterface(origin, validatedParams.id);
132
+ } catch (error) {
133
+ throw _rpcerrors.rpcErrors.invalidParams({
134
+ message: `Invalid params: ${error.message}`
135
+ });
136
+ }
137
+ return showDialog(origin, validatedType, validatedParams.id, placeholder);
102
138
  };
103
139
  }
104
140
  /**
@@ -125,20 +161,11 @@ function getDialogImplementation({ showDialog, isOnPhishingList, maybeUpdatePhis
125
161
  * @returns The validated confirm method parameter object.
126
162
  */ function getValidatedParams(params, struct) {
127
163
  try {
128
- return (0, _superstruct.create)(params, struct);
164
+ return (0, _snapsutils.createUnion)(params, struct, 'type');
129
165
  } catch (error) {
130
- if (error instanceof _superstruct.StructError) {
131
- const { key, type: errorType } = error;
132
- if (key === 'placeholder' && errorType === 'never') {
133
- throw _rpcerrors.rpcErrors.invalidParams({
134
- message: 'Invalid params: Alerts or confirmations may not specify a "placeholder" field.'
135
- });
136
- }
137
- throw _rpcerrors.rpcErrors.invalidParams({
138
- message: `Invalid params: ${error.message}.`
139
- });
140
- }
141
- /* istanbul ignore next */ throw _rpcerrors.rpcErrors.internal();
166
+ throw _rpcerrors.rpcErrors.invalidParams({
167
+ message: `Invalid params: ${error.message}`
168
+ });
142
169
  }
143
170
  }
144
171
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/restricted/dialog.ts"],"sourcesContent":["import type {\n PermissionSpecificationBuilder,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { DialogType, ComponentStruct, enumValue } from '@metamask/snaps-sdk';\nimport type { DialogParams, EnumToUnion, Component } from '@metamask/snaps-sdk';\nimport { validateComponentLinks } from '@metamask/snaps-utils';\nimport type { InferMatching } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n create,\n enums,\n object,\n optional,\n size,\n string,\n StructError,\n type,\n union,\n} from 'superstruct';\n\nimport { type MethodHooksObject } from '../utils';\n\nconst methodName = 'snap_dialog';\n\nconst PlaceholderStruct = optional(size(string(), 1, 40));\n\nexport type Placeholder = Infer<typeof PlaceholderStruct>;\n\ntype ShowDialog = (\n snapId: string,\n type: EnumToUnion<DialogType>,\n content: Component,\n placeholder?: Placeholder,\n) => Promise<null | boolean | string>;\n\ntype MaybeUpdatePhisingList = () => Promise<void>;\ntype IsOnPhishingList = (url: string) => boolean;\n\nexport type DialogMethodHooks = {\n /**\n * @param snapId - The ID of the Snap that created the alert.\n * @param type - The dialog type.\n * @param content - The dialog custom UI.\n * @param placeholder - The placeholder for the Prompt dialog input.\n */\n showDialog: ShowDialog;\n\n maybeUpdatePhishingList: MaybeUpdatePhisingList;\n\n /**\n * @param url - The URL to check against the phishing list.\n */\n isOnPhishingList: IsOnPhishingList;\n};\n\ntype DialogSpecificationBuilderOptions = {\n allowedCaveats?: Readonly<NonEmptyArray<string>> | null;\n methodHooks: DialogMethodHooks;\n};\n\ntype DialogSpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof methodName;\n methodImplementation: ReturnType<typeof getDialogImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * The specification builder for the `snap_dialog` permission. `snap_dialog`\n * lets the Snap display one of the following dialogs to the user:\n * - An alert, for displaying information.\n * - A confirmation, for accepting or rejecting some action.\n * - A prompt, for inputting some information.\n *\n * @param options - The specification builder options.\n * @param options.allowedCaveats - The optional allowed caveats for the\n * permission.\n * @param options.methodHooks - The RPC method hooks needed by the method\n * implementation.\n * @returns The specification for the `snap_dialog` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n DialogSpecificationBuilderOptions,\n DialogSpecification\n> = ({\n allowedCaveats = null,\n methodHooks,\n}: DialogSpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName: methodName,\n allowedCaveats,\n methodImplementation: getDialogImplementation(methodHooks),\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<DialogMethodHooks> = {\n showDialog: true,\n isOnPhishingList: true,\n maybeUpdatePhishingList: true,\n};\n\nexport const dialogBuilder = Object.freeze({\n targetName: methodName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n// Note: We use `type` here instead of `object` because `type` does not validate\n// the keys of the object, which is what we want.\nconst BaseParamsStruct = type({\n type: enums([DialogType.Alert, DialogType.Confirmation, DialogType.Prompt]),\n});\n\nconst AlertParametersStruct = object({\n type: enumValue(DialogType.Alert),\n content: ComponentStruct,\n});\n\nconst ConfirmationParametersStruct = object({\n type: enumValue(DialogType.Confirmation),\n content: ComponentStruct,\n});\n\nconst PromptParametersStruct = object({\n type: enumValue(DialogType.Prompt),\n content: ComponentStruct,\n placeholder: PlaceholderStruct,\n});\n\nconst DialogParametersStruct = union([\n AlertParametersStruct,\n ConfirmationParametersStruct,\n PromptParametersStruct,\n]);\n\nexport type DialogParameters = InferMatching<\n typeof DialogParametersStruct,\n DialogParams\n>;\n\nconst structs = {\n [DialogType.Alert]: AlertParametersStruct,\n [DialogType.Confirmation]: ConfirmationParametersStruct,\n [DialogType.Prompt]: PromptParametersStruct,\n};\n\n/**\n * Builds the method implementation for `snap_dialog`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.showDialog - A function that shows the specified dialog in the\n * MetaMask UI and returns the appropriate value for the dialog type.\n * @param hooks.isOnPhishingList - A function that checks a link against the\n * phishing list and return true if it's in, otherwise false.\n * @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.\n * @returns The method implementation which return value depends on the dialog\n * type, valid return types are: string, boolean, null.\n */\nexport function getDialogImplementation({\n showDialog,\n isOnPhishingList,\n maybeUpdatePhishingList,\n}: DialogMethodHooks) {\n return async function dialogImplementation(\n args: RestrictedMethodOptions<DialogParameters>,\n ): Promise<boolean | null | string> {\n const {\n params,\n context: { origin },\n } = args;\n\n const validatedType = getValidatedType(params);\n const validatedParams = getValidatedParams(params, structs[validatedType]);\n\n const { content } = validatedParams;\n\n await maybeUpdatePhishingList();\n\n validateComponentLinks(content, isOnPhishingList);\n\n const placeholder =\n validatedParams.type === DialogType.Prompt\n ? validatedParams.placeholder\n : undefined;\n\n return showDialog(origin, validatedType, content, placeholder);\n };\n}\n\n/**\n * Get the validated type of the dialog parameters. Throws an error if the type\n * is invalid.\n *\n * @param params - The parameters to validate.\n * @returns The validated type of the dialog parameters.\n */\nfunction getValidatedType(params: unknown): DialogType {\n try {\n return create(params, BaseParamsStruct).type;\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `The \"type\" property must be one of: ${Object.values(\n DialogType,\n ).join(', ')}.`,\n });\n }\n}\n\n/**\n * Validates the confirm method `params` and returns them cast to the correct\n * type. Throws if validation fails.\n *\n * @param params - The unvalidated params object from the method request.\n * @param struct - The struct to validate the params against.\n * @returns The validated confirm method parameter object.\n */\nfunction getValidatedParams(\n params: unknown,\n struct: Struct<any>,\n): DialogParameters {\n try {\n return create(params, struct);\n } catch (error) {\n if (error instanceof StructError) {\n const { key, type: errorType } = error;\n\n if (key === 'placeholder' && errorType === 'never') {\n throw rpcErrors.invalidParams({\n message:\n 'Invalid params: Alerts or confirmations may not specify a \"placeholder\" field.',\n });\n }\n\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}.`,\n });\n }\n\n /* istanbul ignore next */\n throw rpcErrors.internal();\n }\n}\n"],"names":["dialogBuilder","getDialogImplementation","methodName","PlaceholderStruct","optional","size","string","specificationBuilder","allowedCaveats","methodHooks","permissionType","PermissionType","RestrictedMethod","targetName","methodImplementation","subjectTypes","SubjectType","Snap","showDialog","isOnPhishingList","maybeUpdatePhishingList","Object","freeze","BaseParamsStruct","type","enums","DialogType","Alert","Confirmation","Prompt","AlertParametersStruct","object","enumValue","content","ComponentStruct","ConfirmationParametersStruct","PromptParametersStruct","placeholder","DialogParametersStruct","union","structs","dialogImplementation","args","params","context","origin","validatedType","getValidatedType","validatedParams","getValidatedParams","validateComponentLinks","undefined","create","error","rpcErrors","invalidParams","message","values","join","struct","StructError","key","errorType","internal"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/restricted/dialog.ts"],"sourcesContent":["import type {\n PermissionSpecificationBuilder,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport {\n DialogType,\n ComponentStruct,\n enumValue,\n union,\n} from '@metamask/snaps-sdk';\nimport type {\n DialogParams,\n EnumToUnion,\n Component,\n InterfaceState,\n SnapId,\n} from '@metamask/snaps-sdk';\nimport { createUnion } from '@metamask/snaps-utils';\nimport type { InferMatching } from '@metamask/snaps-utils';\nimport { hasProperty, type NonEmptyArray } from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n create,\n enums,\n object,\n optional,\n size,\n string,\n type,\n} from 'superstruct';\n\nimport { type MethodHooksObject } from '../utils';\n\nconst methodName = 'snap_dialog';\n\nconst PlaceholderStruct = optional(size(string(), 1, 40));\n\nexport type Placeholder = Infer<typeof PlaceholderStruct>;\n\ntype ShowDialog = (\n snapId: string,\n type: EnumToUnion<DialogType>,\n id: string,\n placeholder?: Placeholder,\n) => Promise<null | boolean | string>;\n\ntype CreateInterface = (snapId: string, content: Component) => Promise<string>;\ntype GetInterface = (\n snapId: string,\n id: string,\n) => { content: Component; snapId: SnapId; state: InterfaceState };\n\nexport type DialogMethodHooks = {\n /**\n * @param snapId - The ID of the Snap that created the alert.\n * @param type - The dialog type.\n * @param id - The interface ID.\n * @param placeholder - The placeholder for the Prompt dialog input.\n */\n showDialog: ShowDialog;\n\n /**\n * @param snapId - The Snap ID creating the interface.\n * @param content - The content of the interface.\n */\n createInterface: CreateInterface;\n /**\n * @param snapId - The SnapId requesting the interface.\n * @param id - The interface ID.\n */\n getInterface: GetInterface;\n};\n\ntype DialogSpecificationBuilderOptions = {\n allowedCaveats?: Readonly<NonEmptyArray<string>> | null;\n methodHooks: DialogMethodHooks;\n};\n\ntype DialogSpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof methodName;\n methodImplementation: ReturnType<typeof getDialogImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * The specification builder for the `snap_dialog` permission. `snap_dialog`\n * lets the Snap display one of the following dialogs to the user:\n * - An alert, for displaying information.\n * - A confirmation, for accepting or rejecting some action.\n * - A prompt, for inputting some information.\n *\n * @param options - The specification builder options.\n * @param options.allowedCaveats - The optional allowed caveats for the\n * permission.\n * @param options.methodHooks - The RPC method hooks needed by the method\n * implementation.\n * @returns The specification for the `snap_dialog` permission.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n DialogSpecificationBuilderOptions,\n DialogSpecification\n> = ({\n allowedCaveats = null,\n methodHooks,\n}: DialogSpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName: methodName,\n allowedCaveats,\n methodImplementation: getDialogImplementation(methodHooks),\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<DialogMethodHooks> = {\n showDialog: true,\n createInterface: true,\n getInterface: true,\n};\n\nexport const dialogBuilder = Object.freeze({\n targetName: methodName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n// Note: We use `type` here instead of `object` because `type` does not validate\n// the keys of the object, which is what we want.\nconst BaseParamsStruct = type({\n type: enums([DialogType.Alert, DialogType.Confirmation, DialogType.Prompt]),\n});\n\nconst AlertParametersWithContentStruct = object({\n type: enumValue(DialogType.Alert),\n content: ComponentStruct,\n});\nconst AlertParametersWithIdStruct = object({\n type: enumValue(DialogType.Alert),\n id: string(),\n});\n\nconst AlertParametersStruct = union([\n AlertParametersWithContentStruct,\n AlertParametersWithIdStruct,\n]);\n\nconst ConfirmationParametersWithContentStruct = object({\n type: enumValue(DialogType.Confirmation),\n content: ComponentStruct,\n});\n\nconst ConfirmationParametersWithIdStruct = object({\n type: enumValue(DialogType.Confirmation),\n id: string(),\n});\n\nconst ConfirmationParametersStruct = union([\n ConfirmationParametersWithContentStruct,\n ConfirmationParametersWithIdStruct,\n]);\n\nconst PromptParametersWithContentStruct = object({\n type: enumValue(DialogType.Prompt),\n content: ComponentStruct,\n placeholder: PlaceholderStruct,\n});\n\nconst PromptParametersWithIdStruct = object({\n type: enumValue(DialogType.Prompt),\n id: string(),\n placeholder: PlaceholderStruct,\n});\n\nconst PromptParametersStruct = union([\n PromptParametersWithContentStruct,\n PromptParametersWithIdStruct,\n]);\n\nconst DialogParametersStruct = union([\n AlertParametersStruct,\n ConfirmationParametersStruct,\n PromptParametersStruct,\n]);\n\nexport type DialogParameters = InferMatching<\n typeof DialogParametersStruct,\n DialogParams\n>;\n\nconst structs = {\n [DialogType.Alert]: AlertParametersStruct,\n [DialogType.Confirmation]: ConfirmationParametersStruct,\n [DialogType.Prompt]: PromptParametersStruct,\n};\n\n/**\n * Builds the method implementation for `snap_dialog`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.showDialog - A function that shows the specified dialog in the\n * MetaMask UI and returns the appropriate value for the dialog type.\n * @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.\n * @param hooks.getInterface - A function that gets an interface from SnapInterfaceController.\n * @returns The method implementation which return value depends on the dialog\n * type, valid return types are: string, boolean, null.\n */\nexport function getDialogImplementation({\n showDialog,\n createInterface,\n getInterface,\n}: DialogMethodHooks) {\n return async function dialogImplementation(\n args: RestrictedMethodOptions<DialogParameters>,\n ): Promise<boolean | null | string> {\n const {\n params,\n context: { origin },\n } = args;\n\n const validatedType = getValidatedType(params);\n const validatedParams = getValidatedParams(params, structs[validatedType]);\n\n const placeholder =\n validatedParams.type === DialogType.Prompt\n ? validatedParams.placeholder\n : undefined;\n\n if (hasProperty(validatedParams, 'content')) {\n const id = await createInterface(\n origin,\n validatedParams.content as Component,\n );\n return showDialog(origin, validatedType, id, placeholder);\n }\n\n // Verify that the passed interface ID is valid.\n // This will throw if the interface ID is invalid (not created by the snap or doesn't exist)\n try {\n getInterface(origin, validatedParams.id);\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}`,\n });\n }\n\n return showDialog(origin, validatedType, validatedParams.id, placeholder);\n };\n}\n\n/**\n * Get the validated type of the dialog parameters. Throws an error if the type\n * is invalid.\n *\n * @param params - The parameters to validate.\n * @returns The validated type of the dialog parameters.\n */\nfunction getValidatedType(params: unknown): DialogType {\n try {\n return create(params, BaseParamsStruct).type;\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `The \"type\" property must be one of: ${Object.values(\n DialogType,\n ).join(', ')}.`,\n });\n }\n}\n\n/**\n * Validates the confirm method `params` and returns them cast to the correct\n * type. Throws if validation fails.\n *\n * @param params - The unvalidated params object from the method request.\n * @param struct - The struct to validate the params against.\n * @returns The validated confirm method parameter object.\n */\nfunction getValidatedParams(\n params: unknown,\n struct: Struct<any, any>,\n): DialogParameters {\n try {\n return createUnion(params, struct, 'type');\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}`,\n });\n }\n}\n"],"names":["dialogBuilder","getDialogImplementation","methodName","PlaceholderStruct","optional","size","string","specificationBuilder","allowedCaveats","methodHooks","permissionType","PermissionType","RestrictedMethod","targetName","methodImplementation","subjectTypes","SubjectType","Snap","showDialog","createInterface","getInterface","Object","freeze","BaseParamsStruct","type","enums","DialogType","Alert","Confirmation","Prompt","AlertParametersWithContentStruct","object","enumValue","content","ComponentStruct","AlertParametersWithIdStruct","id","AlertParametersStruct","union","ConfirmationParametersWithContentStruct","ConfirmationParametersWithIdStruct","ConfirmationParametersStruct","PromptParametersWithContentStruct","placeholder","PromptParametersWithIdStruct","PromptParametersStruct","DialogParametersStruct","structs","dialogImplementation","args","params","context","origin","validatedType","getValidatedType","validatedParams","getValidatedParams","undefined","hasProperty","error","rpcErrors","invalidParams","message","create","values","join","struct","createUnion"],"mappings":";;;;;;;;;;;IA6HaA,aAAa;eAAbA;;IAsFGC,uBAAuB;eAAvBA;;;sCA9M4B;2BAClB;0BAMnB;4BAQqB;uBAEoB;6BAUzC;AAIP,MAAMC,aAAa;AAEnB,MAAMC,oBAAoBC,IAAAA,qBAAQ,EAACC,IAAAA,iBAAI,EAACC,IAAAA,mBAAM,KAAI,GAAG;AAkDrD;;;;;;;;;;;;;CAaC,GACD,MAAMC,uBAIF,CAAC,EACHC,iBAAiB,IAAI,EACrBC,WAAW,EACuB;IAClC,OAAO;QACLC,gBAAgBC,oCAAc,CAACC,gBAAgB;QAC/CC,YAAYX;QACZM;QACAM,sBAAsBb,wBAAwBQ;QAC9CM,cAAc;YAACC,iCAAW,CAACC,IAAI;SAAC;IAClC;AACF;AAEA,MAAMR,cAAoD;IACxDS,YAAY;IACZC,iBAAiB;IACjBC,cAAc;AAChB;AAEO,MAAMpB,gBAAgBqB,OAAOC,MAAM,CAAC;IACzCT,YAAYX;IACZK;IACAE;AACF;AAEA,gFAAgF;AAChF,iDAAiD;AACjD,MAAMc,mBAAmBC,IAAAA,iBAAI,EAAC;IAC5BA,MAAMC,IAAAA,kBAAK,EAAC;QAACC,oBAAU,CAACC,KAAK;QAAED,oBAAU,CAACE,YAAY;QAAEF,oBAAU,CAACG,MAAM;KAAC;AAC5E;AAEA,MAAMC,mCAAmCC,IAAAA,mBAAM,EAAC;IAC9CP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACC,KAAK;IAChCM,SAASC,yBAAe;AAC1B;AACA,MAAMC,8BAA8BJ,IAAAA,mBAAM,EAAC;IACzCP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACC,KAAK;IAChCS,IAAI9B,IAAAA,mBAAM;AACZ;AAEA,MAAM+B,wBAAwBC,IAAAA,eAAK,EAAC;IAClCR;IACAK;CACD;AAED,MAAMI,0CAA0CR,IAAAA,mBAAM,EAAC;IACrDP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACE,YAAY;IACvCK,SAASC,yBAAe;AAC1B;AAEA,MAAMM,qCAAqCT,IAAAA,mBAAM,EAAC;IAChDP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACE,YAAY;IACvCQ,IAAI9B,IAAAA,mBAAM;AACZ;AAEA,MAAMmC,+BAA+BH,IAAAA,eAAK,EAAC;IACzCC;IACAC;CACD;AAED,MAAME,oCAAoCX,IAAAA,mBAAM,EAAC;IAC/CP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACG,MAAM;IACjCI,SAASC,yBAAe;IACxBS,aAAaxC;AACf;AAEA,MAAMyC,+BAA+Bb,IAAAA,mBAAM,EAAC;IAC1CP,MAAMQ,IAAAA,mBAAS,EAACN,oBAAU,CAACG,MAAM;IACjCO,IAAI9B,IAAAA,mBAAM;IACVqC,aAAaxC;AACf;AAEA,MAAM0C,yBAAyBP,IAAAA,eAAK,EAAC;IACnCI;IACAE;CACD;AAED,MAAME,yBAAyBR,IAAAA,eAAK,EAAC;IACnCD;IACAI;IACAI;CACD;AAOD,MAAME,UAAU;IACd,CAACrB,oBAAU,CAACC,KAAK,CAAC,EAAEU;IACpB,CAACX,oBAAU,CAACE,YAAY,CAAC,EAAEa;IAC3B,CAACf,oBAAU,CAACG,MAAM,CAAC,EAAEgB;AACvB;AAaO,SAAS5C,wBAAwB,EACtCiB,UAAU,EACVC,eAAe,EACfC,YAAY,EACM;IAClB,OAAO,eAAe4B,qBACpBC,IAA+C;QAE/C,MAAM,EACJC,MAAM,EACNC,SAAS,EAAEC,MAAM,EAAE,EACpB,GAAGH;QAEJ,MAAMI,gBAAgBC,iBAAiBJ;QACvC,MAAMK,kBAAkBC,mBAAmBN,QAAQH,OAAO,CAACM,cAAc;QAEzE,MAAMV,cACJY,gBAAgB/B,IAAI,KAAKE,oBAAU,CAACG,MAAM,GACtC0B,gBAAgBZ,WAAW,GAC3Bc;QAEN,IAAIC,IAAAA,kBAAW,EAACH,iBAAiB,YAAY;YAC3C,MAAMnB,KAAK,MAAMjB,gBACfiC,QACAG,gBAAgBtB,OAAO;YAEzB,OAAOf,WAAWkC,QAAQC,eAAejB,IAAIO;QAC/C;QAEA,gDAAgD;QAChD,4FAA4F;QAC5F,IAAI;YACFvB,aAAagC,QAAQG,gBAAgBnB,EAAE;QACzC,EAAE,OAAOuB,OAAO;YACd,MAAMC,oBAAS,CAACC,aAAa,CAAC;gBAC5BC,SAAS,CAAC,gBAAgB,EAAEH,MAAMG,OAAO,CAAC,CAAC;YAC7C;QACF;QAEA,OAAO5C,WAAWkC,QAAQC,eAAeE,gBAAgBnB,EAAE,EAAEO;IAC/D;AACF;AAEA;;;;;;CAMC,GACD,SAASW,iBAAiBJ,MAAe;IACvC,IAAI;QACF,OAAOa,IAAAA,mBAAM,EAACb,QAAQ3B,kBAAkBC,IAAI;IAC9C,EAAE,OAAOmC,OAAO;QACd,MAAMC,oBAAS,CAACC,aAAa,CAAC;YAC5BC,SAAS,CAAC,oCAAoC,EAAEzC,OAAO2C,MAAM,CAC3DtC,oBAAU,EACVuC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjB;IACF;AACF;AAEA;;;;;;;CAOC,GACD,SAAST,mBACPN,MAAe,EACfgB,MAAwB;IAExB,IAAI;QACF,OAAOC,IAAAA,uBAAW,EAACjB,QAAQgB,QAAQ;IACrC,EAAE,OAAOP,OAAO;QACd,MAAMC,oBAAS,CAACC,aAAa,CAAC;YAC5BC,SAAS,CAAC,gBAAgB,EAAEH,MAAMG,OAAO,CAAC,CAAC;QAC7C;IACF;AACF"}
@@ -0,0 +1,40 @@
1
+ import { rpcErrors } from '@metamask/rpc-errors';
2
+ /**
3
+ * Create a generic permission validator that validates the presence of certain caveats.
4
+ *
5
+ * This validator only validates the types of the caveats, not the values.
6
+ *
7
+ * @param caveatsToValidate - A list of objects that represent caveats.
8
+ * @param caveatsToValidate.type - The string defining the caveat type.
9
+ * @param caveatsToValidate.optional - An optional boolean flag that defines
10
+ * whether the caveat is optional or not.
11
+ * @returns A function that validates a permission.
12
+ */ export function createGenericPermissionValidator(caveatsToValidate) {
13
+ const validCaveatTypes = new Set(caveatsToValidate.map((caveat)=>caveat.type));
14
+ const requiredCaveats = caveatsToValidate.filter((caveat)=>!caveat.optional);
15
+ return function({ caveats }) {
16
+ const actualCaveats = caveats ?? [];
17
+ const passedCaveatTypes = actualCaveats.map((caveat)=>caveat.type);
18
+ const passedCaveatsSet = new Set(passedCaveatTypes);
19
+ // Disallow duplicates
20
+ if (passedCaveatsSet.size !== passedCaveatTypes.length) {
21
+ throw rpcErrors.invalidParams({
22
+ message: 'Duplicate caveats are not allowed.'
23
+ });
24
+ }
25
+ // Disallow caveats that don't match expected types
26
+ if (!actualCaveats.every((caveat)=>validCaveatTypes.has(caveat.type))) {
27
+ throw rpcErrors.invalidParams({
28
+ message: `Expected the following caveats: ${caveatsToValidate.map((caveat)=>`"${caveat.type}"`).join(', ')}, received ${actualCaveats.map((caveat)=>`"${caveat.type}"`).join(', ')}.`
29
+ });
30
+ }
31
+ // Fail if not all required caveats are specified
32
+ if (!requiredCaveats.every((caveat)=>passedCaveatsSet.has(caveat.type))) {
33
+ throw rpcErrors.invalidParams({
34
+ message: `Expected the following caveats: ${requiredCaveats.map((caveat)=>`"${caveat.type}"`).join(', ')}.`
35
+ });
36
+ }
37
+ };
38
+ }
39
+
40
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/endowments/caveats/generic.ts"],"sourcesContent":["import type {\n PermissionConstraint,\n PermissionValidatorConstraint,\n} from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { Json } from '@metamask/utils';\n\nexport type CaveatMapperReturnValue = Pick<PermissionConstraint, 'caveats'>;\n\nexport type CaveatMapperFunction = (value: Json) => CaveatMapperReturnValue;\n\n/**\n * Create a generic permission validator that validates the presence of certain caveats.\n *\n * This validator only validates the types of the caveats, not the values.\n *\n * @param caveatsToValidate - A list of objects that represent caveats.\n * @param caveatsToValidate.type - The string defining the caveat type.\n * @param caveatsToValidate.optional - An optional boolean flag that defines\n * whether the caveat is optional or not.\n * @returns A function that validates a permission.\n */\nexport function createGenericPermissionValidator(\n caveatsToValidate: {\n type: string;\n optional?: boolean;\n }[],\n): PermissionValidatorConstraint {\n const validCaveatTypes = new Set(\n caveatsToValidate.map((caveat) => caveat.type),\n );\n const requiredCaveats = caveatsToValidate.filter(\n (caveat) => !caveat.optional,\n );\n\n return function ({ caveats }) {\n const actualCaveats = caveats ?? [];\n const passedCaveatTypes = actualCaveats.map((caveat) => caveat.type);\n const passedCaveatsSet = new Set(passedCaveatTypes);\n\n // Disallow duplicates\n if (passedCaveatsSet.size !== passedCaveatTypes.length) {\n throw rpcErrors.invalidParams({\n message: 'Duplicate caveats are not allowed.',\n });\n }\n\n // Disallow caveats that don't match expected types\n if (!actualCaveats.every((caveat) => validCaveatTypes.has(caveat.type))) {\n throw rpcErrors.invalidParams({\n message: `Expected the following caveats: ${caveatsToValidate\n .map((caveat) => `\"${caveat.type}\"`)\n .join(', ')}, received ${actualCaveats\n .map((caveat) => `\"${caveat.type}\"`)\n .join(', ')}.`,\n });\n }\n\n // Fail if not all required caveats are specified\n if (!requiredCaveats.every((caveat) => passedCaveatsSet.has(caveat.type))) {\n throw rpcErrors.invalidParams({\n message: `Expected the following caveats: ${requiredCaveats\n .map((caveat) => `\"${caveat.type}\"`)\n .join(', ')}.`,\n });\n }\n };\n}\n"],"names":["rpcErrors","createGenericPermissionValidator","caveatsToValidate","validCaveatTypes","Set","map","caveat","type","requiredCaveats","filter","optional","caveats","actualCaveats","passedCaveatTypes","passedCaveatsSet","size","length","invalidParams","message","every","has","join"],"mappings":"AAIA,SAASA,SAAS,QAAQ,uBAAuB;AAOjD;;;;;;;;;;CAUC,GACD,OAAO,SAASC,iCACdC,iBAGG;IAEH,MAAMC,mBAAmB,IAAIC,IAC3BF,kBAAkBG,GAAG,CAAC,CAACC,SAAWA,OAAOC,IAAI;IAE/C,MAAMC,kBAAkBN,kBAAkBO,MAAM,CAC9C,CAACH,SAAW,CAACA,OAAOI,QAAQ;IAG9B,OAAO,SAAU,EAAEC,OAAO,EAAE;QAC1B,MAAMC,gBAAgBD,WAAW,EAAE;QACnC,MAAME,oBAAoBD,cAAcP,GAAG,CAAC,CAACC,SAAWA,OAAOC,IAAI;QACnE,MAAMO,mBAAmB,IAAIV,IAAIS;QAEjC,sBAAsB;QACtB,IAAIC,iBAAiBC,IAAI,KAAKF,kBAAkBG,MAAM,EAAE;YACtD,MAAMhB,UAAUiB,aAAa,CAAC;gBAC5BC,SAAS;YACX;QACF;QAEA,mDAAmD;QACnD,IAAI,CAACN,cAAcO,KAAK,CAAC,CAACb,SAAWH,iBAAiBiB,GAAG,CAACd,OAAOC,IAAI,IAAI;YACvE,MAAMP,UAAUiB,aAAa,CAAC;gBAC5BC,SAAS,CAAC,gCAAgC,EAAEhB,kBACzCG,GAAG,CAAC,CAACC,SAAW,CAAC,CAAC,EAAEA,OAAOC,IAAI,CAAC,CAAC,CAAC,EAClCc,IAAI,CAAC,MAAM,WAAW,EAAET,cACxBP,GAAG,CAAC,CAACC,SAAW,CAAC,CAAC,EAAEA,OAAOC,IAAI,CAAC,CAAC,CAAC,EAClCc,IAAI,CAAC,MAAM,CAAC,CAAC;YAClB;QACF;QAEA,iDAAiD;QACjD,IAAI,CAACb,gBAAgBW,KAAK,CAAC,CAACb,SAAWQ,iBAAiBM,GAAG,CAACd,OAAOC,IAAI,IAAI;YACzE,MAAMP,UAAUiB,aAAa,CAAC;gBAC5BC,SAAS,CAAC,gCAAgC,EAAEV,gBACzCH,GAAG,CAAC,CAACC,SAAW,CAAC,CAAC,EAAEA,OAAOC,IAAI,CAAC,CAAC,CAAC,EAClCc,IAAI,CAAC,MAAM,CAAC,CAAC;YAClB;QACF;IACF;AACF"}
@@ -0,0 +1,4 @@
1
+ export * from './generic';
2
+ export * from './requestTime';
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/endowments/caveats/index.ts"],"sourcesContent":["export * from './generic';\nexport * from './requestTime';\n"],"names":[],"mappings":"AAAA,cAAc,YAAY;AAC1B,cAAc,gBAAgB"}
@@ -0,0 +1,93 @@
1
+ import { rpcErrors } from '@metamask/rpc-errors';
2
+ import { MaxRequestTimeStruct, SnapCaveatType } from '@metamask/snaps-utils';
3
+ import { assertStruct, hasProperty, isObject } from '@metamask/utils';
4
+ /**
5
+ * Asserts that the given value is a valid `maxRequestTime` value.
6
+ *
7
+ * @param value - The value to assert.
8
+ * @param ErrorWrapper - An optional error wrapper to use. Defaults to
9
+ * {@link AssertionError}.
10
+ * @throws If the value is not a valid `maxRequestTime` value.
11
+ */ function assertIsMaxRequestTime(value, ErrorWrapper) {
12
+ assertStruct(value, MaxRequestTimeStruct, 'Invalid maxRequestTime', ErrorWrapper);
13
+ }
14
+ /**
15
+ * Validate the value of a caveat. This does not validate the type of the
16
+ * caveat itself, only the value of the caveat.
17
+ *
18
+ * @param caveat - The caveat to validate.
19
+ * @throws If the caveat value is invalid.
20
+ */ function validateMaxRequestTimeCaveat(caveat) {
21
+ if (!hasProperty(caveat, 'value')) {
22
+ throw rpcErrors.invalidParams({
23
+ message: 'Invalid maxRequestTime caveat.'
24
+ });
25
+ }
26
+ const { value } = caveat;
27
+ assertIsMaxRequestTime(value, rpcErrors.invalidParams);
28
+ }
29
+ /**
30
+ * Map a raw value from the `initialPermissions` to a caveat specification.
31
+ * Note that this function does not do any validation, that's handled by the
32
+ * PermissionsController when the permission is requested.
33
+ *
34
+ * @param value - The raw value from the `initialPermissions`.
35
+ * @returns The caveat specification.
36
+ */ export function getMaxRequestTimeCaveatMapper(value) {
37
+ if (!value || !isObject(value) || isObject(value) && !hasProperty(value, 'maxRequestTime')) {
38
+ return {
39
+ caveats: null
40
+ };
41
+ }
42
+ return {
43
+ caveats: [
44
+ {
45
+ type: SnapCaveatType.MaxRequestTime,
46
+ value: value.maxRequestTime
47
+ }
48
+ ]
49
+ };
50
+ }
51
+ /**
52
+ * Creates a wrapping caveat mapper that creates the `maxRequestTime` caveat
53
+ * and merges it with any other caveats created by the mapper function.
54
+ *
55
+ * @param mapper - Another caveat mapper function.
56
+ * @returns The caveat specification.
57
+ */ export function createMaxRequestTimeMapper(mapper) {
58
+ return function(value) {
59
+ // We assume this to be used only with caveats of this type
60
+ const { maxRequestTime, ...rest } = value;
61
+ const mapperResult = mapper(rest);
62
+ if (!maxRequestTime) {
63
+ return mapperResult;
64
+ }
65
+ return {
66
+ ...mapperResult,
67
+ caveats: [
68
+ ...mapperResult.caveats ?? [],
69
+ {
70
+ type: SnapCaveatType.MaxRequestTime,
71
+ value: maxRequestTime
72
+ }
73
+ ]
74
+ };
75
+ };
76
+ }
77
+ /**
78
+ * Getter function to get the {@link MaxRequestTime} caveat value from a permission if specified.
79
+ *
80
+ * @param permission - The permission to get the caveat value from.
81
+ * @returns The caveat value if present, otherwise null.
82
+ */ export function getMaxRequestTimeCaveat(permission) {
83
+ const foundCaveat = permission?.caveats?.find((caveat)=>caveat.type === SnapCaveatType.MaxRequestTime);
84
+ return (foundCaveat?.value) ?? null;
85
+ }
86
+ export const maxRequestTimeCaveatSpecifications = {
87
+ [SnapCaveatType.MaxRequestTime]: Object.freeze({
88
+ type: SnapCaveatType.MaxRequestTime,
89
+ validator: (caveat)=>validateMaxRequestTimeCaveat(caveat)
90
+ })
91
+ };
92
+
93
+ //# sourceMappingURL=requestTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/endowments/caveats/requestTime.ts"],"sourcesContent":["import type {\n Caveat,\n CaveatSpecificationConstraint,\n PermissionConstraint,\n} from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { MaxRequestTimeStruct, SnapCaveatType } from '@metamask/snaps-utils';\nimport type { AssertionErrorConstructor, Json } from '@metamask/utils';\nimport { assertStruct, hasProperty, isObject } from '@metamask/utils';\n\nimport type { CaveatMapperFunction, CaveatMapperReturnValue } from './generic';\n\n/**\n * Asserts that the given value is a valid `maxRequestTime` value.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid `maxRequestTime` value.\n */\nfunction assertIsMaxRequestTime(\n value: unknown, // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is number {\n assertStruct(\n value,\n MaxRequestTimeStruct,\n 'Invalid maxRequestTime',\n ErrorWrapper,\n );\n}\n\n/**\n * Validate the value of a caveat. This does not validate the type of the\n * caveat itself, only the value of the caveat.\n *\n * @param caveat - The caveat to validate.\n * @throws If the caveat value is invalid.\n */\nfunction validateMaxRequestTimeCaveat(caveat: Caveat<string, any>) {\n if (!hasProperty(caveat, 'value')) {\n throw rpcErrors.invalidParams({\n message: 'Invalid maxRequestTime caveat.',\n });\n }\n\n const { value } = caveat;\n assertIsMaxRequestTime(value, rpcErrors.invalidParams);\n}\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 getMaxRequestTimeCaveatMapper(\n value: Json,\n): CaveatMapperReturnValue {\n if (\n !value ||\n !isObject(value) ||\n (isObject(value) && !hasProperty(value, 'maxRequestTime'))\n ) {\n return { caveats: null };\n }\n return {\n caveats: [\n {\n type: SnapCaveatType.MaxRequestTime,\n value: value.maxRequestTime,\n },\n ],\n };\n}\n\n/**\n * Creates a wrapping caveat mapper that creates the `maxRequestTime` caveat\n * and merges it with any other caveats created by the mapper function.\n *\n * @param mapper - Another caveat mapper function.\n * @returns The caveat specification.\n */\nexport function createMaxRequestTimeMapper(\n mapper: CaveatMapperFunction,\n): CaveatMapperFunction {\n return function (value: Json) {\n // We assume this to be used only with caveats of this type\n const { maxRequestTime, ...rest } = value as Record<string, Json>;\n\n const mapperResult = mapper(rest);\n\n if (!maxRequestTime) {\n return mapperResult;\n }\n\n return {\n ...mapperResult,\n caveats: [\n ...(mapperResult.caveats ?? []),\n {\n type: SnapCaveatType.MaxRequestTime,\n value: maxRequestTime,\n },\n ],\n };\n };\n}\n\n/**\n * Getter function to get the {@link MaxRequestTime} caveat value from a permission if specified.\n *\n * @param permission - The permission to get the caveat value from.\n * @returns The caveat value if present, otherwise null.\n */\nexport function getMaxRequestTimeCaveat(\n permission?: PermissionConstraint,\n): number | null {\n const foundCaveat = permission?.caveats?.find(\n (caveat) => caveat.type === SnapCaveatType.MaxRequestTime,\n );\n return (foundCaveat?.value as number) ?? null;\n}\n\nexport const maxRequestTimeCaveatSpecifications: Record<\n SnapCaveatType.MaxRequestTime,\n CaveatSpecificationConstraint\n> = {\n [SnapCaveatType.MaxRequestTime]: Object.freeze({\n type: SnapCaveatType.MaxRequestTime,\n validator: (caveat: Caveat<string, any>) =>\n validateMaxRequestTimeCaveat(caveat),\n }),\n};\n"],"names":["rpcErrors","MaxRequestTimeStruct","SnapCaveatType","assertStruct","hasProperty","isObject","assertIsMaxRequestTime","value","ErrorWrapper","validateMaxRequestTimeCaveat","caveat","invalidParams","message","getMaxRequestTimeCaveatMapper","caveats","type","MaxRequestTime","maxRequestTime","createMaxRequestTimeMapper","mapper","rest","mapperResult","getMaxRequestTimeCaveat","permission","foundCaveat","find","maxRequestTimeCaveatSpecifications","Object","freeze","validator"],"mappings":"AAKA,SAASA,SAAS,QAAQ,uBAAuB;AACjD,SAASC,oBAAoB,EAAEC,cAAc,QAAQ,wBAAwB;AAE7E,SAASC,YAAY,EAAEC,WAAW,EAAEC,QAAQ,QAAQ,kBAAkB;AAItE;;;;;;;CAOC,GACD,SAASC,uBACPC,KAAc,EACdC,YAAwC;IAExCL,aACEI,OACAN,sBACA,0BACAO;AAEJ;AAEA;;;;;;CAMC,GACD,SAASC,6BAA6BC,MAA2B;IAC/D,IAAI,CAACN,YAAYM,QAAQ,UAAU;QACjC,MAAMV,UAAUW,aAAa,CAAC;YAC5BC,SAAS;QACX;IACF;IAEA,MAAM,EAAEL,KAAK,EAAE,GAAGG;IAClBJ,uBAAuBC,OAAOP,UAAUW,aAAa;AACvD;AAEA;;;;;;;CAOC,GACD,OAAO,SAASE,8BACdN,KAAW;IAEX,IACE,CAACA,SACD,CAACF,SAASE,UACTF,SAASE,UAAU,CAACH,YAAYG,OAAO,mBACxC;QACA,OAAO;YAAEO,SAAS;QAAK;IACzB;IACA,OAAO;QACLA,SAAS;YACP;gBACEC,MAAMb,eAAec,cAAc;gBACnCT,OAAOA,MAAMU,cAAc;YAC7B;SACD;IACH;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,2BACdC,MAA4B;IAE5B,OAAO,SAAUZ,KAAW;QAC1B,2DAA2D;QAC3D,MAAM,EAAEU,cAAc,EAAE,GAAGG,MAAM,GAAGb;QAEpC,MAAMc,eAAeF,OAAOC;QAE5B,IAAI,CAACH,gBAAgB;YACnB,OAAOI;QACT;QAEA,OAAO;YACL,GAAGA,YAAY;YACfP,SAAS;mBACHO,aAAaP,OAAO,IAAI,EAAE;gBAC9B;oBACEC,MAAMb,eAAec,cAAc;oBACnCT,OAAOU;gBACT;aACD;QACH;IACF;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASK,wBACdC,UAAiC;IAEjC,MAAMC,cAAcD,YAAYT,SAASW,KACvC,CAACf,SAAWA,OAAOK,IAAI,KAAKb,eAAec,cAAc;IAE3D,OAAO,CAACQ,aAAajB,KAAe,KAAK;AAC3C;AAEA,OAAO,MAAMmB,qCAGT;IACF,CAACxB,eAAec,cAAc,CAAC,EAAEW,OAAOC,MAAM,CAAC;QAC7Cb,MAAMb,eAAec,cAAc;QACnCa,WAAW,CAACnB,SACVD,6BAA6BC;IACjC;AACF,EAAE"}
@@ -0,0 +1,99 @@
1
+ import { PermissionType, SubjectType } from '@metamask/permission-controller';
2
+ import { rpcErrors } from '@metamask/rpc-errors';
3
+ import { SnapCaveatType, isCronjobSpecificationArray } from '@metamask/snaps-utils';
4
+ import { assert, hasProperty, isPlainObject } from '@metamask/utils';
5
+ import { SnapEndowments } from './enum';
6
+ const permissionName = SnapEndowments.Cronjob;
7
+ /**
8
+ * `endowment:cronjob` returns nothing; it is intended to be used as a flag to determine whether the snap wants to run cronjobs.
9
+ *
10
+ * @param _builderOptions - Optional specification builder options.
11
+ * @returns The specification for the cronjob endowment.
12
+ */ const specificationBuilder = (_builderOptions)=>{
13
+ return {
14
+ permissionType: PermissionType.Endowment,
15
+ targetName: permissionName,
16
+ allowedCaveats: [
17
+ SnapCaveatType.SnapCronjob
18
+ ],
19
+ endowmentGetter: (_getterOptions)=>undefined,
20
+ subjectTypes: [
21
+ SubjectType.Snap
22
+ ]
23
+ };
24
+ };
25
+ export const cronjobEndowmentBuilder = Object.freeze({
26
+ targetName: permissionName,
27
+ specificationBuilder
28
+ });
29
+ /**
30
+ * Map a raw value from the `initialPermissions` to a caveat specification.
31
+ * Note that this function does not do any validation, that's handled by the
32
+ * PermissionsController when the permission is requested.
33
+ *
34
+ * @param value - The raw value from the `initialPermissions`.
35
+ * @returns The caveat specification.
36
+ */ export function getCronjobCaveatMapper(value) {
37
+ return {
38
+ caveats: [
39
+ {
40
+ type: SnapCaveatType.SnapCronjob,
41
+ value
42
+ }
43
+ ]
44
+ };
45
+ }
46
+ /**
47
+ * Getter function to get the cronjobs from a permission.
48
+ *
49
+ * This does basic validation of the caveat, but does not validate the type or
50
+ * value of the namespaces object itself, as this is handled by the
51
+ * `PermissionsController` when the permission is requested.
52
+ *
53
+ * @param permission - The permission to get the keyring namespaces from.
54
+ * @returns The cronjobs, or `null` if the permission does not have a
55
+ * cronjob caveat.
56
+ */ export function getCronjobCaveatJobs(permission) {
57
+ if (!permission?.caveats) {
58
+ return null;
59
+ }
60
+ assert(permission.caveats.length === 1);
61
+ assert(permission.caveats[0].type === SnapCaveatType.SnapCronjob);
62
+ const caveat = permission.caveats[0];
63
+ return (caveat.value?.jobs) ?? null;
64
+ }
65
+ /**
66
+ * Validate the cronjob specification values associated with a caveat.
67
+ * This validates that the value is a non-empty array with valid
68
+ * cronjob expression and request object.
69
+ *
70
+ * @param caveat - The caveat to validate.
71
+ * @throws If the value is invalid.
72
+ */ export function validateCronjobCaveat(caveat) {
73
+ if (!hasProperty(caveat, 'value') || !isPlainObject(caveat.value)) {
74
+ throw rpcErrors.invalidParams({
75
+ message: 'Expected a plain object.'
76
+ });
77
+ }
78
+ const { value } = caveat;
79
+ if (!hasProperty(value, 'jobs') || !isPlainObject(value)) {
80
+ throw rpcErrors.invalidParams({
81
+ message: 'Expected a plain object.'
82
+ });
83
+ }
84
+ if (!isCronjobSpecificationArray(value.jobs)) {
85
+ throw rpcErrors.invalidParams({
86
+ message: 'Expected a valid cronjob specification array.'
87
+ });
88
+ }
89
+ }
90
+ /**
91
+ * Caveat specification for the Cronjob.
92
+ */ export const cronjobCaveatSpecifications = {
93
+ [SnapCaveatType.SnapCronjob]: Object.freeze({
94
+ type: SnapCaveatType.SnapCronjob,
95
+ validator: (caveat)=>validateCronjobCaveat(caveat)
96
+ })
97
+ };
98
+
99
+ //# sourceMappingURL=cronjob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/endowments/cronjob.ts"],"sourcesContent":["import type {\n PermissionSpecificationBuilder,\n EndowmentGetterParams,\n ValidPermissionSpecification,\n PermissionConstraint,\n Caveat,\n CaveatSpecificationConstraint,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { CronjobSpecification } from '@metamask/snaps-utils';\nimport {\n SnapCaveatType,\n isCronjobSpecificationArray,\n} from '@metamask/snaps-utils';\nimport type { Json, NonEmptyArray } from '@metamask/utils';\nimport { assert, hasProperty, isPlainObject } from '@metamask/utils';\n\nimport { SnapEndowments } from './enum';\n\nconst permissionName = SnapEndowments.Cronjob;\n\ntype CronjobEndowmentSpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.Endowment;\n targetName: typeof permissionName;\n endowmentGetter: (_options?: any) => undefined;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * `endowment:cronjob` returns nothing; it is intended to be used as a flag to determine whether the snap wants to run cronjobs.\n *\n * @param _builderOptions - Optional specification builder options.\n * @returns The specification for the cronjob endowment.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.Endowment,\n any,\n CronjobEndowmentSpecification\n> = (_builderOptions?: any) => {\n return {\n permissionType: PermissionType.Endowment,\n targetName: permissionName,\n allowedCaveats: [SnapCaveatType.SnapCronjob],\n endowmentGetter: (_getterOptions?: EndowmentGetterParams) => undefined,\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nexport const cronjobEndowmentBuilder = Object.freeze({\n targetName: permissionName,\n specificationBuilder,\n} as const);\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 getCronjobCaveatMapper(\n value: Json,\n): Pick<PermissionConstraint, 'caveats'> {\n return {\n caveats: [\n {\n type: SnapCaveatType.SnapCronjob,\n value,\n },\n ],\n };\n}\n\n/**\n * Getter function to get the cronjobs from a permission.\n *\n * This does basic validation of the caveat, but does not validate the type or\n * value of the namespaces object itself, as this is handled by the\n * `PermissionsController` when the permission is requested.\n *\n * @param permission - The permission to get the keyring namespaces from.\n * @returns The cronjobs, or `null` if the permission does not have a\n * cronjob caveat.\n */\nexport function getCronjobCaveatJobs(\n permission?: PermissionConstraint,\n): CronjobSpecification[] | null {\n if (!permission?.caveats) {\n return null;\n }\n\n assert(permission.caveats.length === 1);\n assert(permission.caveats[0].type === SnapCaveatType.SnapCronjob);\n\n const caveat = permission.caveats[0] as Caveat<string, { jobs: Json[] }>;\n\n return (caveat.value?.jobs as CronjobSpecification[]) ?? null;\n}\n\n/**\n * Validate the cronjob specification values associated with a caveat.\n * This validates that the value is a non-empty array with valid\n * cronjob expression and request object.\n *\n * @param caveat - The caveat to validate.\n * @throws If the value is invalid.\n */\nexport function validateCronjobCaveat(caveat: Caveat<string, any>) {\n if (!hasProperty(caveat, 'value') || !isPlainObject(caveat.value)) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object.',\n });\n }\n\n const { value } = caveat;\n\n if (!hasProperty(value, 'jobs') || !isPlainObject(value)) {\n throw rpcErrors.invalidParams({\n message: 'Expected a plain object.',\n });\n }\n\n if (!isCronjobSpecificationArray(value.jobs)) {\n throw rpcErrors.invalidParams({\n message: 'Expected a valid cronjob specification array.',\n });\n }\n}\n\n/**\n * Caveat specification for the Cronjob.\n */\nexport const cronjobCaveatSpecifications: Record<\n SnapCaveatType.SnapCronjob,\n CaveatSpecificationConstraint\n> = {\n [SnapCaveatType.SnapCronjob]: Object.freeze({\n type: SnapCaveatType.SnapCronjob,\n validator: (caveat) => validateCronjobCaveat(caveat),\n }),\n};\n"],"names":["PermissionType","SubjectType","rpcErrors","SnapCaveatType","isCronjobSpecificationArray","assert","hasProperty","isPlainObject","SnapEndowments","permissionName","Cronjob","specificationBuilder","_builderOptions","permissionType","Endowment","targetName","allowedCaveats","SnapCronjob","endowmentGetter","_getterOptions","undefined","subjectTypes","Snap","cronjobEndowmentBuilder","Object","freeze","getCronjobCaveatMapper","value","caveats","type","getCronjobCaveatJobs","permission","length","caveat","jobs","validateCronjobCaveat","invalidParams","message","cronjobCaveatSpecifications","validator"],"mappings":"AAQA,SAASA,cAAc,EAAEC,WAAW,QAAQ,kCAAkC;AAC9E,SAASC,SAAS,QAAQ,uBAAuB;AAEjD,SACEC,cAAc,EACdC,2BAA2B,QACtB,wBAAwB;AAE/B,SAASC,MAAM,EAAEC,WAAW,EAAEC,aAAa,QAAQ,kBAAkB;AAErE,SAASC,cAAc,QAAQ,SAAS;AAExC,MAAMC,iBAAiBD,eAAeE,OAAO;AAS7C;;;;;CAKC,GACD,MAAMC,uBAIF,CAACC;IACH,OAAO;QACLC,gBAAgBb,eAAec,SAAS;QACxCC,YAAYN;QACZO,gBAAgB;YAACb,eAAec,WAAW;SAAC;QAC5CC,iBAAiB,CAACC,iBAA2CC;QAC7DC,cAAc;YAACpB,YAAYqB,IAAI;SAAC;IAClC;AACF;AAEA,OAAO,MAAMC,0BAA0BC,OAAOC,MAAM,CAAC;IACnDV,YAAYN;IACZE;AACF,GAAY;AAEZ;;;;;;;CAOC,GACD,OAAO,SAASe,uBACdC,KAAW;IAEX,OAAO;QACLC,SAAS;YACP;gBACEC,MAAM1B,eAAec,WAAW;gBAChCU;YACF;SACD;IACH;AACF;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASG,qBACdC,UAAiC;IAEjC,IAAI,CAACA,YAAYH,SAAS;QACxB,OAAO;IACT;IAEAvB,OAAO0B,WAAWH,OAAO,CAACI,MAAM,KAAK;IACrC3B,OAAO0B,WAAWH,OAAO,CAAC,EAAE,CAACC,IAAI,KAAK1B,eAAec,WAAW;IAEhE,MAAMgB,SAASF,WAAWH,OAAO,CAAC,EAAE;IAEpC,OAAO,CAACK,OAAON,KAAK,EAAEO,IAA8B,KAAK;AAC3D;AAEA;;;;;;;CAOC,GACD,OAAO,SAASC,sBAAsBF,MAA2B;IAC/D,IAAI,CAAC3B,YAAY2B,QAAQ,YAAY,CAAC1B,cAAc0B,OAAON,KAAK,GAAG;QACjE,MAAMzB,UAAUkC,aAAa,CAAC;YAC5BC,SAAS;QACX;IACF;IAEA,MAAM,EAAEV,KAAK,EAAE,GAAGM;IAElB,IAAI,CAAC3B,YAAYqB,OAAO,WAAW,CAACpB,cAAcoB,QAAQ;QACxD,MAAMzB,UAAUkC,aAAa,CAAC;YAC5BC,SAAS;QACX;IACF;IAEA,IAAI,CAACjC,4BAA4BuB,MAAMO,IAAI,GAAG;QAC5C,MAAMhC,UAAUkC,aAAa,CAAC;YAC5BC,SAAS;QACX;IACF;AACF;AAEA;;CAEC,GACD,OAAO,MAAMC,8BAGT;IACF,CAACnC,eAAec,WAAW,CAAC,EAAEO,OAAOC,MAAM,CAAC;QAC1CI,MAAM1B,eAAec,WAAW;QAChCsB,WAAW,CAACN,SAAWE,sBAAsBF;IAC/C;AACF,EAAE"}
@@ -0,0 +1,16 @@
1
+ export var SnapEndowments;
2
+ (function(SnapEndowments) {
3
+ SnapEndowments["NetworkAccess"] = 'endowment:network-access';
4
+ SnapEndowments["SignatureInsight"] = 'endowment:signature-insight';
5
+ SnapEndowments["TransactionInsight"] = 'endowment:transaction-insight';
6
+ SnapEndowments["Cronjob"] = 'endowment:cronjob';
7
+ SnapEndowments["EthereumProvider"] = 'endowment:ethereum-provider';
8
+ SnapEndowments["Rpc"] = 'endowment:rpc';
9
+ SnapEndowments["WebAssemblyAccess"] = 'endowment:webassembly';
10
+ SnapEndowments["NameLookup"] = 'endowment:name-lookup';
11
+ SnapEndowments["LifecycleHooks"] = 'endowment:lifecycle-hooks';
12
+ SnapEndowments["Keyring"] = 'endowment:keyring';
13
+ SnapEndowments["HomePage"] = 'endowment:page-home';
14
+ })(SnapEndowments || (SnapEndowments = {}));
15
+
16
+ //# sourceMappingURL=enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/endowments/enum.ts"],"sourcesContent":["export enum SnapEndowments {\n NetworkAccess = 'endowment:network-access',\n SignatureInsight = 'endowment:signature-insight',\n TransactionInsight = 'endowment:transaction-insight',\n Cronjob = 'endowment:cronjob',\n EthereumProvider = 'endowment:ethereum-provider',\n Rpc = 'endowment:rpc',\n WebAssemblyAccess = 'endowment:webassembly',\n NameLookup = 'endowment:name-lookup',\n LifecycleHooks = 'endowment:lifecycle-hooks',\n Keyring = 'endowment:keyring',\n HomePage = 'endowment:page-home',\n}\n"],"names":["SnapEndowments","NetworkAccess","SignatureInsight","TransactionInsight","Cronjob","EthereumProvider","Rpc","WebAssemblyAccess","NameLookup","LifecycleHooks","Keyring","HomePage"],"mappings":"WAAO;UAAKA,cAAc;IAAdA,eACVC,mBAAgB;IADND,eAEVE,sBAAmB;IAFTF,eAGVG,wBAAqB;IAHXH,eAIVI,aAAU;IAJAJ,eAKVK,sBAAmB;IALTL,eAMVM,SAAM;IANIN,eAOVO,uBAAoB;IAPVP,eAQVQ,gBAAa;IARHR,eASVS,oBAAiB;IATPT,eAUVU,aAAU;IAVAV,eAWVW,cAAW;GAXDX,mBAAAA"}
@@ -0,0 +1,33 @@
1
+ import { PermissionType, SubjectType } from '@metamask/permission-controller';
2
+ import { SnapEndowments } from './enum';
3
+ const permissionName = SnapEndowments.EthereumProvider;
4
+ /**
5
+ * `endowment:ethereum-provider` returns the name of the ethereum global browser API.
6
+ * This is intended to populate the endowments of the
7
+ * SES Compartment in which a Snap executes.
8
+ *
9
+ * This populates the global scope with an EIP-1193 provider, which DOES NOT implement all legacy functionality exposed to dapps.
10
+ *
11
+ * @param _builderOptions - Optional specification builder options.
12
+ * @returns The specification for the network endowment.
13
+ */ const specificationBuilder = (_builderOptions)=>{
14
+ return {
15
+ permissionType: PermissionType.Endowment,
16
+ targetName: permissionName,
17
+ allowedCaveats: null,
18
+ endowmentGetter: (_getterOptions)=>{
19
+ return [
20
+ 'ethereum'
21
+ ];
22
+ },
23
+ subjectTypes: [
24
+ SubjectType.Snap
25
+ ]
26
+ };
27
+ };
28
+ export const ethereumProviderEndowmentBuilder = Object.freeze({
29
+ targetName: permissionName,
30
+ specificationBuilder
31
+ });
32
+
33
+ //# sourceMappingURL=ethereum-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/endowments/ethereum-provider.ts"],"sourcesContent":["import type {\n EndowmentGetterParams,\n PermissionSpecificationBuilder,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\n\nimport { SnapEndowments } from './enum';\n\nconst permissionName = SnapEndowments.EthereumProvider;\n\ntype EthereumProviderEndowmentSpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.Endowment;\n targetName: typeof permissionName;\n endowmentGetter: (_options?: any) => ['ethereum'];\n allowedCaveats: null;\n}>;\n\n/**\n * `endowment:ethereum-provider` returns the name of the ethereum global browser API.\n * This is intended to populate the endowments of the\n * SES Compartment in which a Snap executes.\n *\n * This populates the global scope with an EIP-1193 provider, which DOES NOT implement all legacy functionality exposed to dapps.\n *\n * @param _builderOptions - Optional specification builder options.\n * @returns The specification for the network endowment.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.Endowment,\n any,\n EthereumProviderEndowmentSpecification\n> = (_builderOptions?: any) => {\n return {\n permissionType: PermissionType.Endowment,\n targetName: permissionName,\n allowedCaveats: null,\n endowmentGetter: (_getterOptions?: EndowmentGetterParams) => {\n return ['ethereum'];\n },\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nexport const ethereumProviderEndowmentBuilder = Object.freeze({\n targetName: permissionName,\n specificationBuilder,\n} as const);\n"],"names":["PermissionType","SubjectType","SnapEndowments","permissionName","EthereumProvider","specificationBuilder","_builderOptions","permissionType","Endowment","targetName","allowedCaveats","endowmentGetter","_getterOptions","subjectTypes","Snap","ethereumProviderEndowmentBuilder","Object","freeze"],"mappings":"AAKA,SAASA,cAAc,EAAEC,WAAW,QAAQ,kCAAkC;AAE9E,SAASC,cAAc,QAAQ,SAAS;AAExC,MAAMC,iBAAiBD,eAAeE,gBAAgB;AAStD;;;;;;;;;CASC,GACD,MAAMC,uBAIF,CAACC;IACH,OAAO;QACLC,gBAAgBP,eAAeQ,SAAS;QACxCC,YAAYN;QACZO,gBAAgB;QAChBC,iBAAiB,CAACC;YAChB,OAAO;gBAAC;aAAW;QACrB;QACAC,cAAc;YAACZ,YAAYa,IAAI;SAAC;IAClC;AACF;AAEA,OAAO,MAAMC,mCAAmCC,OAAOC,MAAM,CAAC;IAC5DR,YAAYN;IACZE;AACF,GAAY"}
@@ -0,0 +1,27 @@
1
+ import { PermissionType, SubjectType } from '@metamask/permission-controller';
2
+ import { SnapEndowments } from './enum';
3
+ const permissionName = SnapEndowments.HomePage;
4
+ /**
5
+ * `endowment:page-home` returns nothing; it is intended to be used as a
6
+ * flag by the snap controller to detect whether the snap has the capability to
7
+ * use the snap home page feature.
8
+ *
9
+ * @param _builderOptions - Optional specification builder options.
10
+ * @returns The specification for the `snap-pages` endowment.
11
+ */ const specificationBuilder = (_builderOptions)=>{
12
+ return {
13
+ permissionType: PermissionType.Endowment,
14
+ targetName: permissionName,
15
+ allowedCaveats: null,
16
+ endowmentGetter: (_getterOptions)=>undefined,
17
+ subjectTypes: [
18
+ SubjectType.Snap
19
+ ]
20
+ };
21
+ };
22
+ export const homePageEndowmentBuilder = Object.freeze({
23
+ targetName: permissionName,
24
+ specificationBuilder
25
+ });
26
+
27
+ //# sourceMappingURL=home-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/endowments/home-page.ts"],"sourcesContent":["import type {\n PermissionSpecificationBuilder,\n EndowmentGetterParams,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport type { NonEmptyArray } from '@metamask/utils';\n\nimport { SnapEndowments } from './enum';\n\nconst permissionName = SnapEndowments.HomePage;\n\ntype HomePageEndowmentSpecification = ValidPermissionSpecification<{\n permissionType: PermissionType.Endowment;\n targetName: typeof permissionName;\n endowmentGetter: (_options?: EndowmentGetterParams) => undefined;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * `endowment:page-home` returns nothing; it is intended to be used as a\n * flag by the snap controller to detect whether the snap has the capability to\n * use the snap home page feature.\n *\n * @param _builderOptions - Optional specification builder options.\n * @returns The specification for the `snap-pages` endowment.\n */\nconst specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.Endowment,\n any,\n HomePageEndowmentSpecification\n> = (_builderOptions?: unknown) => {\n return {\n permissionType: PermissionType.Endowment,\n targetName: permissionName,\n allowedCaveats: null,\n endowmentGetter: (_getterOptions?: EndowmentGetterParams) => undefined,\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nexport const homePageEndowmentBuilder = Object.freeze({\n targetName: permissionName,\n specificationBuilder,\n} as const);\n"],"names":["PermissionType","SubjectType","SnapEndowments","permissionName","HomePage","specificationBuilder","_builderOptions","permissionType","Endowment","targetName","allowedCaveats","endowmentGetter","_getterOptions","undefined","subjectTypes","Snap","homePageEndowmentBuilder","Object","freeze"],"mappings":"AAKA,SAASA,cAAc,EAAEC,WAAW,QAAQ,kCAAkC;AAG9E,SAASC,cAAc,QAAQ,SAAS;AAExC,MAAMC,iBAAiBD,eAAeE,QAAQ;AAS9C;;;;;;;CAOC,GACD,MAAMC,uBAIF,CAACC;IACH,OAAO;QACLC,gBAAgBP,eAAeQ,SAAS;QACxCC,YAAYN;QACZO,gBAAgB;QAChBC,iBAAiB,CAACC,iBAA2CC;QAC7DC,cAAc;YAACb,YAAYc,IAAI;SAAC;IAClC;AACF;AAEA,OAAO,MAAMC,2BAA2BC,OAAOC,MAAM,CAAC;IACpDT,YAAYN;IACZE;AACF,GAAY"}