@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.
- package/CHANGELOG.md +15 -3
- package/dist/cjs/endowments/caveats/generic.js +40 -0
- package/dist/cjs/endowments/caveats/generic.js.map +1 -0
- package/dist/cjs/endowments/caveats/index.js +21 -0
- package/dist/cjs/endowments/caveats/index.js.map +1 -0
- package/dist/cjs/endowments/caveats/requestTime.js +99 -0
- package/dist/cjs/endowments/caveats/requestTime.js.map +1 -0
- package/dist/cjs/endowments/cronjob.js +100 -0
- package/dist/cjs/endowments/cronjob.js.map +1 -0
- package/dist/cjs/endowments/enum.js +26 -0
- package/dist/cjs/endowments/enum.js.map +1 -0
- package/dist/cjs/endowments/ethereum-provider.js +43 -0
- package/dist/cjs/endowments/ethereum-provider.js.map +1 -0
- package/dist/cjs/endowments/home-page.js +37 -0
- package/dist/cjs/endowments/home-page.js.map +1 -0
- package/dist/cjs/endowments/index.js +121 -0
- package/dist/cjs/endowments/index.js.map +1 -0
- package/dist/cjs/endowments/keyring.js +104 -0
- package/dist/cjs/endowments/keyring.js.map +1 -0
- package/dist/cjs/endowments/lifecycle-hooks.js +37 -0
- package/dist/cjs/endowments/lifecycle-hooks.js.map +1 -0
- package/dist/cjs/endowments/name-lookup.js +148 -0
- package/dist/cjs/endowments/name-lookup.js.map +1 -0
- package/dist/cjs/endowments/network-access.js +44 -0
- package/dist/cjs/endowments/network-access.js.map +1 -0
- package/dist/cjs/endowments/rpc.js +103 -0
- package/dist/cjs/endowments/rpc.js.map +1 -0
- package/dist/cjs/endowments/signature-insight.js +110 -0
- package/dist/cjs/endowments/signature-insight.js.map +1 -0
- package/dist/cjs/endowments/transaction-insight.js +111 -0
- package/dist/cjs/endowments/transaction-insight.js.map +1 -0
- package/dist/cjs/endowments/web-assembly.js +42 -0
- package/dist/cjs/endowments/web-assembly.js.map +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/permissions.js +62 -0
- package/dist/cjs/permissions.js.map +1 -0
- package/dist/cjs/permitted/createInterface.js +68 -0
- package/dist/cjs/permitted/createInterface.js.map +1 -0
- package/dist/cjs/permitted/getFile.js +1 -1
- package/dist/cjs/permitted/getFile.js.map +1 -1
- package/dist/cjs/permitted/getInterfaceState.js +67 -0
- package/dist/cjs/permitted/getInterfaceState.js.map +1 -0
- package/dist/cjs/permitted/handlers.js +7 -1
- package/dist/cjs/permitted/handlers.js.map +1 -1
- package/dist/cjs/permitted/index.js.map +1 -1
- package/dist/cjs/permitted/updateInterface.js +70 -0
- package/dist/cjs/permitted/updateInterface.js.map +1 -0
- package/dist/cjs/restricted/dialog.js +51 -24
- package/dist/cjs/restricted/dialog.js.map +1 -1
- package/dist/esm/endowments/caveats/generic.js +40 -0
- package/dist/esm/endowments/caveats/generic.js.map +1 -0
- package/dist/esm/endowments/caveats/index.js +4 -0
- package/dist/esm/endowments/caveats/index.js.map +1 -0
- package/dist/esm/endowments/caveats/requestTime.js +93 -0
- package/dist/esm/endowments/caveats/requestTime.js.map +1 -0
- package/dist/esm/endowments/cronjob.js +99 -0
- package/dist/esm/endowments/cronjob.js.map +1 -0
- package/dist/esm/endowments/enum.js +16 -0
- package/dist/esm/endowments/enum.js.map +1 -0
- package/dist/esm/endowments/ethereum-provider.js +33 -0
- package/dist/esm/endowments/ethereum-provider.js.map +1 -0
- package/dist/esm/endowments/home-page.js +27 -0
- package/dist/esm/endowments/home-page.js.map +1 -0
- package/dist/esm/endowments/index.js +68 -0
- package/dist/esm/endowments/index.js.map +1 -0
- package/dist/esm/endowments/keyring.js +95 -0
- package/dist/esm/endowments/keyring.js.map +1 -0
- package/dist/esm/endowments/lifecycle-hooks.js +27 -0
- package/dist/esm/endowments/lifecycle-hooks.js.map +1 -0
- package/dist/esm/endowments/name-lookup.js +146 -0
- package/dist/esm/endowments/name-lookup.js.map +1 -0
- package/dist/esm/endowments/network-access.js +34 -0
- package/dist/esm/endowments/network-access.js.map +1 -0
- package/dist/esm/endowments/rpc.js +92 -0
- package/dist/esm/endowments/rpc.js.map +1 -0
- package/dist/esm/endowments/signature-insight.js +103 -0
- package/dist/esm/endowments/signature-insight.js.map +1 -0
- package/dist/esm/endowments/transaction-insight.js +104 -0
- package/dist/esm/endowments/transaction-insight.js.map +1 -0
- package/dist/esm/endowments/web-assembly.js +32 -0
- package/dist/esm/endowments/web-assembly.js.map +1 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/permissions.js +51 -0
- package/dist/esm/permissions.js.map +1 -0
- package/dist/esm/permitted/createInterface.js +58 -0
- package/dist/esm/permitted/createInterface.js.map +1 -0
- package/dist/esm/permitted/getFile.js +1 -1
- package/dist/esm/permitted/getFile.js.map +1 -1
- package/dist/esm/permitted/getInterfaceState.js +57 -0
- package/dist/esm/permitted/getInterfaceState.js.map +1 -0
- package/dist/esm/permitted/handlers.js +7 -1
- package/dist/esm/permitted/handlers.js.map +1 -1
- package/dist/esm/permitted/index.js.map +1 -1
- package/dist/esm/permitted/updateInterface.js +60 -0
- package/dist/esm/permitted/updateInterface.js.map +1 -0
- package/dist/esm/restricted/dialog.js +55 -29
- package/dist/esm/restricted/dialog.js.map +1 -1
- package/dist/types/endowments/caveats/generic.d.ts +19 -0
- package/dist/types/endowments/caveats/index.d.ts +2 -0
- package/dist/types/endowments/caveats/requestTime.d.ts +29 -0
- package/dist/types/endowments/cronjob.d.ts +51 -0
- package/dist/types/endowments/enum.d.ts +13 -0
- package/dist/types/endowments/ethereum-provider.d.ts +14 -0
- package/dist/types/endowments/home-page.d.ts +15 -0
- package/dist/types/endowments/index.d.ts +131 -0
- package/dist/types/endowments/keyring.d.ts +39 -0
- package/dist/types/endowments/lifecycle-hooks.d.ts +15 -0
- package/dist/types/endowments/name-lookup.d.ts +49 -0
- package/dist/types/endowments/network-access.d.ts +14 -0
- package/dist/types/endowments/rpc.d.ts +38 -0
- package/dist/types/endowments/signature-insight.d.ts +39 -0
- package/dist/types/endowments/transaction-insight.d.ts +39 -0
- package/dist/types/endowments/web-assembly.d.ts +14 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/permissions.d.ts +16 -0
- package/dist/types/permitted/createInterface.d.ts +150 -0
- package/dist/types/permitted/getInterfaceState.d.ts +18 -0
- package/dist/types/permitted/handlers.d.ts +4 -1
- package/dist/types/permitted/index.d.ts +4 -1
- package/dist/types/permitted/updateInterface.d.ts +152 -0
- package/dist/types/restricted/dialog.d.ts +776 -14
- 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
|
-
|
|
53
|
-
|
|
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
|
|
70
|
+
const AlertParametersWithContentStruct = (0, _superstruct.object)({
|
|
70
71
|
type: (0, _snapssdk.enumValue)(_snapssdk.DialogType.Alert),
|
|
71
72
|
content: _snapssdk.ComponentStruct
|
|
72
73
|
});
|
|
73
|
-
const
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
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,
|
|
164
|
+
return (0, _snapsutils.createUnion)(params, struct, 'type');
|
|
129
165
|
} catch (error) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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":"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"}
|
|
@@ -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 @@
|
|
|
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"}
|