@metamask/snaps-controllers 12.1.0 → 12.3.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 +27 -1
- package/dist/cronjob/CronjobController.cjs +13 -4
- package/dist/cronjob/CronjobController.cjs.map +1 -1
- package/dist/cronjob/CronjobController.d.cts.map +1 -1
- package/dist/cronjob/CronjobController.d.mts.map +1 -1
- package/dist/cronjob/CronjobController.mjs +15 -6
- package/dist/cronjob/CronjobController.mjs.map +1 -1
- package/dist/interface/SnapInterfaceController.cjs +15 -1
- package/dist/interface/SnapInterfaceController.cjs.map +1 -1
- package/dist/interface/SnapInterfaceController.d.cts +10 -2
- package/dist/interface/SnapInterfaceController.d.cts.map +1 -1
- package/dist/interface/SnapInterfaceController.d.mts +10 -2
- package/dist/interface/SnapInterfaceController.d.mts.map +1 -1
- package/dist/interface/SnapInterfaceController.mjs +17 -3
- package/dist/interface/SnapInterfaceController.mjs.map +1 -1
- package/dist/interface/utils.cjs +104 -4
- package/dist/interface/utils.cjs.map +1 -1
- package/dist/interface/utils.d.cts +71 -2
- package/dist/interface/utils.d.cts.map +1 -1
- package/dist/interface/utils.d.mts +71 -2
- package/dist/interface/utils.d.mts.map +1 -1
- package/dist/interface/utils.mjs +101 -5
- package/dist/interface/utils.mjs.map +1 -1
- package/dist/multichain/MultichainRouter.cjs +1 -0
- package/dist/multichain/MultichainRouter.cjs.map +1 -1
- package/dist/multichain/MultichainRouter.d.cts +1 -0
- package/dist/multichain/MultichainRouter.d.cts.map +1 -1
- package/dist/multichain/MultichainRouter.d.mts +1 -0
- package/dist/multichain/MultichainRouter.d.mts.map +1 -1
- package/dist/multichain/MultichainRouter.mjs +1 -0
- package/dist/multichain/MultichainRouter.mjs.map +1 -1
- package/dist/services/AbstractExecutionService.cjs +127 -202
- package/dist/services/AbstractExecutionService.cjs.map +1 -1
- package/dist/services/AbstractExecutionService.d.cts +8 -53
- package/dist/services/AbstractExecutionService.d.cts.map +1 -1
- package/dist/services/AbstractExecutionService.d.mts +8 -53
- package/dist/services/AbstractExecutionService.d.mts.map +1 -1
- package/dist/services/AbstractExecutionService.mjs +127 -202
- package/dist/services/AbstractExecutionService.mjs.map +1 -1
- package/dist/services/iframe/IframeExecutionService.cjs +2 -2
- package/dist/services/iframe/IframeExecutionService.cjs.map +1 -1
- package/dist/services/iframe/IframeExecutionService.d.cts +1 -1
- package/dist/services/iframe/IframeExecutionService.d.cts.map +1 -1
- package/dist/services/iframe/IframeExecutionService.d.mts +1 -1
- package/dist/services/iframe/IframeExecutionService.d.mts.map +1 -1
- package/dist/services/iframe/IframeExecutionService.mjs +2 -2
- package/dist/services/iframe/IframeExecutionService.mjs.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.cjs +5 -5
- package/dist/services/offscreen/OffscreenExecutionService.cjs.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.cts +4 -4
- package/dist/services/offscreen/OffscreenExecutionService.d.cts.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.d.mts +4 -4
- package/dist/services/offscreen/OffscreenExecutionService.d.mts.map +1 -1
- package/dist/services/offscreen/OffscreenExecutionService.mjs +5 -5
- package/dist/services/offscreen/OffscreenExecutionService.mjs.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.cjs +6 -6
- package/dist/services/proxy/ProxyExecutionService.cjs.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.cts +4 -4
- package/dist/services/proxy/ProxyExecutionService.d.cts.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.d.mts +4 -4
- package/dist/services/proxy/ProxyExecutionService.d.mts.map +1 -1
- package/dist/services/proxy/ProxyExecutionService.mjs +6 -6
- package/dist/services/proxy/ProxyExecutionService.mjs.map +1 -1
- package/dist/services/webview/WebViewExecutionService.cjs +6 -6
- package/dist/services/webview/WebViewExecutionService.cjs.map +1 -1
- package/dist/services/webview/WebViewExecutionService.d.cts +5 -5
- package/dist/services/webview/WebViewExecutionService.d.cts.map +1 -1
- package/dist/services/webview/WebViewExecutionService.d.mts +5 -5
- package/dist/services/webview/WebViewExecutionService.d.mts.map +1 -1
- package/dist/services/webview/WebViewExecutionService.mjs +6 -6
- package/dist/services/webview/WebViewExecutionService.mjs.map +1 -1
- package/dist/snaps/SnapController.cjs +60 -72
- package/dist/snaps/SnapController.cjs.map +1 -1
- package/dist/snaps/SnapController.d.cts +19 -10
- package/dist/snaps/SnapController.d.cts.map +1 -1
- package/dist/snaps/SnapController.d.mts +19 -10
- package/dist/snaps/SnapController.d.mts.map +1 -1
- package/dist/snaps/SnapController.mjs +61 -73
- package/dist/snaps/SnapController.mjs.map +1 -1
- package/dist/snaps/registry/json.cjs +4 -2
- package/dist/snaps/registry/json.cjs.map +1 -1
- package/dist/snaps/registry/json.d.cts.map +1 -1
- package/dist/snaps/registry/json.d.mts.map +1 -1
- package/dist/snaps/registry/json.mjs +4 -2
- package/dist/snaps/registry/json.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/snaps/RequestQueue.cjs +0 -44
- package/dist/snaps/RequestQueue.cjs.map +0 -1
- package/dist/snaps/RequestQueue.d.cts +0 -25
- package/dist/snaps/RequestQueue.d.cts.map +0 -1
- package/dist/snaps/RequestQueue.d.mts +0 -25
- package/dist/snaps/RequestQueue.d.mts.map +0 -1
- package/dist/snaps/RequestQueue.mjs +0 -40
- package/dist/snaps/RequestQueue.mjs.map +0 -1
|
@@ -6,7 +6,7 @@ import type { InterfaceState, SnapId, ComponentOrElement, InterfaceContext, Fung
|
|
|
6
6
|
import { ContentType } from "@metamask/snaps-sdk";
|
|
7
7
|
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
8
8
|
import type { InternalAccount } from "@metamask/snaps-utils";
|
|
9
|
-
import type { CaipAssetType, Json } from "@metamask/utils";
|
|
9
|
+
import type { CaipAssetType, CaipChainId, Json } from "@metamask/utils";
|
|
10
10
|
import type { GetSnap } from "../snaps/index.cjs";
|
|
11
11
|
declare const controllerName = "SnapInterfaceController";
|
|
12
12
|
export type CreateInterface = {
|
|
@@ -37,6 +37,14 @@ type AccountsControllerGetAccountByAddressAction = {
|
|
|
37
37
|
type: `AccountsController:getAccountByAddress`;
|
|
38
38
|
handler: (address: string) => InternalAccount | undefined;
|
|
39
39
|
};
|
|
40
|
+
type AccountsControllerGetSelectedMultichainAccountAction = {
|
|
41
|
+
type: `AccountsController:getSelectedMultichainAccount`;
|
|
42
|
+
handler: () => InternalAccount;
|
|
43
|
+
};
|
|
44
|
+
type AccountsControllerListMultichainAccountsAction = {
|
|
45
|
+
type: `AccountsController:listMultichainAccounts`;
|
|
46
|
+
handler: (chainId?: CaipChainId) => InternalAccount[];
|
|
47
|
+
};
|
|
40
48
|
export type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<typeof controllerName, SnapInterfaceControllerState>;
|
|
41
49
|
type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<'MultichainAssetsController', {
|
|
42
50
|
assetsMetadata: {
|
|
@@ -46,7 +54,7 @@ type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<'Multic
|
|
|
46
54
|
[account: string]: CaipAssetType[];
|
|
47
55
|
};
|
|
48
56
|
}>;
|
|
49
|
-
export type SnapInterfaceControllerAllowedActions = TestOrigin | HasApprovalRequest | AcceptRequest | GetSnap | MultichainAssetsControllerGetStateAction | AccountsControllerGetAccountByAddressAction;
|
|
57
|
+
export type SnapInterfaceControllerAllowedActions = TestOrigin | HasApprovalRequest | AcceptRequest | GetSnap | MultichainAssetsControllerGetStateAction | AccountsControllerGetSelectedMultichainAccountAction | AccountsControllerGetAccountByAddressAction | AccountsControllerListMultichainAccountsAction;
|
|
50
58
|
export type SnapInterfaceControllerActions = CreateInterface | GetInterface | UpdateInterface | DeleteInterface | UpdateInterfaceState | ResolveInterface | SnapInterfaceControllerGetStateAction;
|
|
51
59
|
export type SnapInterfaceControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, SnapInterfaceControllerState>;
|
|
52
60
|
type OtherNotification = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapInterfaceController.d.cts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EACnB,sCAAsC;AACvC,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,sCAAsC;AAChE,OAAO,KAAK,EACV,cAAc,EACd,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACtB,4BAA4B;AAC7B,OAAO,EAAE,WAAW,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
|
1
|
+
{"version":3,"file":"SnapInterfaceController.d.cts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import type { InterfaceState, SnapId, ComponentOrElement, InterfaceContext, Fung
|
|
|
6
6
|
import { ContentType } from "@metamask/snaps-sdk";
|
|
7
7
|
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
8
8
|
import type { InternalAccount } from "@metamask/snaps-utils";
|
|
9
|
-
import type { CaipAssetType, Json } from "@metamask/utils";
|
|
9
|
+
import type { CaipAssetType, CaipChainId, Json } from "@metamask/utils";
|
|
10
10
|
import type { GetSnap } from "../snaps/index.mjs";
|
|
11
11
|
declare const controllerName = "SnapInterfaceController";
|
|
12
12
|
export type CreateInterface = {
|
|
@@ -37,6 +37,14 @@ type AccountsControllerGetAccountByAddressAction = {
|
|
|
37
37
|
type: `AccountsController:getAccountByAddress`;
|
|
38
38
|
handler: (address: string) => InternalAccount | undefined;
|
|
39
39
|
};
|
|
40
|
+
type AccountsControllerGetSelectedMultichainAccountAction = {
|
|
41
|
+
type: `AccountsController:getSelectedMultichainAccount`;
|
|
42
|
+
handler: () => InternalAccount;
|
|
43
|
+
};
|
|
44
|
+
type AccountsControllerListMultichainAccountsAction = {
|
|
45
|
+
type: `AccountsController:listMultichainAccounts`;
|
|
46
|
+
handler: (chainId?: CaipChainId) => InternalAccount[];
|
|
47
|
+
};
|
|
40
48
|
export type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<typeof controllerName, SnapInterfaceControllerState>;
|
|
41
49
|
type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<'MultichainAssetsController', {
|
|
42
50
|
assetsMetadata: {
|
|
@@ -46,7 +54,7 @@ type MultichainAssetsControllerGetStateAction = ControllerGetStateAction<'Multic
|
|
|
46
54
|
[account: string]: CaipAssetType[];
|
|
47
55
|
};
|
|
48
56
|
}>;
|
|
49
|
-
export type SnapInterfaceControllerAllowedActions = TestOrigin | HasApprovalRequest | AcceptRequest | GetSnap | MultichainAssetsControllerGetStateAction | AccountsControllerGetAccountByAddressAction;
|
|
57
|
+
export type SnapInterfaceControllerAllowedActions = TestOrigin | HasApprovalRequest | AcceptRequest | GetSnap | MultichainAssetsControllerGetStateAction | AccountsControllerGetSelectedMultichainAccountAction | AccountsControllerGetAccountByAddressAction | AccountsControllerListMultichainAccountsAction;
|
|
50
58
|
export type SnapInterfaceControllerActions = CreateInterface | GetInterface | UpdateInterface | DeleteInterface | UpdateInterfaceState | ResolveInterface | SnapInterfaceControllerGetStateAction;
|
|
51
59
|
export type SnapInterfaceControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, SnapInterfaceControllerState>;
|
|
52
60
|
type OtherNotification = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapInterfaceController.d.mts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EACnB,sCAAsC;AACvC,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,sCAAsC;AAChE,OAAO,KAAK,EACV,cAAc,EACd,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACtB,4BAA4B;AAC7B,OAAO,EAAE,WAAW,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,gCAAgC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;
|
|
1
|
+
{"version":3,"file":"SnapInterfaceController.d.mts","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _SnapInterfaceController_instances, _SnapInterfaceController_registerMessageHandlers, _SnapInterfaceController_validateArgs, _SnapInterfaceController_validateApproval, _SnapInterfaceController_checkPhishingList, _SnapInterfaceController_hasApprovalRequest, _SnapInterfaceController_acceptApprovalRequest, _SnapInterfaceController_getAccountByAddress, _SnapInterfaceController_getAssetsState, _SnapInterfaceController_getSnap, _SnapInterfaceController_validateContent, _SnapInterfaceController_onNotificationsListUpdated;
|
|
6
|
+
var _SnapInterfaceController_instances, _SnapInterfaceController_registerMessageHandlers, _SnapInterfaceController_validateArgs, _SnapInterfaceController_validateApproval, _SnapInterfaceController_checkPhishingList, _SnapInterfaceController_hasApprovalRequest, _SnapInterfaceController_acceptApprovalRequest, _SnapInterfaceController_getSelectedAccount, _SnapInterfaceController_listAccounts, _SnapInterfaceController_getAccountByAddress, _SnapInterfaceController_getAssetsState, _SnapInterfaceController_getSnap, _SnapInterfaceController_validateContent, _SnapInterfaceController_onNotificationsListUpdated;
|
|
7
7
|
import { BaseController } from "@metamask/base-controller";
|
|
8
8
|
import { ContentType } from "@metamask/snaps-sdk";
|
|
9
|
-
import { getJsonSizeUnsafe, validateJsxElements } from "@metamask/snaps-utils";
|
|
9
|
+
import { getJsonSizeUnsafe, snapOwnsAccount, validateJsxElements } from "@metamask/snaps-utils";
|
|
10
10
|
import { assert, hasProperty, parseCaipAccountId } from "@metamask/utils";
|
|
11
11
|
import { castDraft } from "immer";
|
|
12
12
|
import { nanoid } from "nanoid";
|
|
13
|
-
import { constructState, getJsxInterface, validateInterfaceContext } from "./utils.mjs";
|
|
13
|
+
import { constructState, getJsxInterface, isMatchingChainId, validateInterfaceContext } from "./utils.mjs";
|
|
14
14
|
const MAX_UI_CONTENT_SIZE = 10000000; // 10 mb
|
|
15
15
|
const controllerName = 'SnapInterfaceController';
|
|
16
16
|
/**
|
|
@@ -60,6 +60,9 @@ export class SnapInterfaceController extends BaseController {
|
|
|
60
60
|
const componentState = constructState({}, element, {
|
|
61
61
|
getAssetsState: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getAssetsState).bind(this),
|
|
62
62
|
getAccountByAddress: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getAccountByAddress).bind(this),
|
|
63
|
+
getSelectedAccount: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getSelectedAccount).bind(this),
|
|
64
|
+
listAccounts: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_listAccounts).bind(this),
|
|
65
|
+
snapOwnsAccount: (account) => snapOwnsAccount(snapId, account),
|
|
63
66
|
});
|
|
64
67
|
this.update((draftState) => {
|
|
65
68
|
// @ts-expect-error - TS2589: Type instantiation is excessively deep and
|
|
@@ -102,6 +105,9 @@ export class SnapInterfaceController extends BaseController {
|
|
|
102
105
|
const newState = constructState(oldState, element, {
|
|
103
106
|
getAssetsState: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getAssetsState).bind(this),
|
|
104
107
|
getAccountByAddress: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getAccountByAddress).bind(this),
|
|
108
|
+
getSelectedAccount: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_getSelectedAccount).bind(this),
|
|
109
|
+
listAccounts: __classPrivateFieldGet(this, _SnapInterfaceController_instances, "m", _SnapInterfaceController_listAccounts).bind(this),
|
|
110
|
+
snapOwnsAccount: (account) => snapOwnsAccount(snapId, account),
|
|
105
111
|
});
|
|
106
112
|
this.update((draftState) => {
|
|
107
113
|
draftState.interfaces[id].state = newState;
|
|
@@ -176,6 +182,14 @@ _SnapInterfaceController_instances = new WeakSet(), _SnapInterfaceController_reg
|
|
|
176
182
|
*/
|
|
177
183
|
async function _SnapInterfaceController_acceptApprovalRequest(id, value) {
|
|
178
184
|
await this.messagingSystem.call('ApprovalController:acceptRequest', id, value);
|
|
185
|
+
}, _SnapInterfaceController_getSelectedAccount = function _SnapInterfaceController_getSelectedAccount() {
|
|
186
|
+
return this.messagingSystem.call('AccountsController:getSelectedMultichainAccount');
|
|
187
|
+
}, _SnapInterfaceController_listAccounts = function _SnapInterfaceController_listAccounts(chainIds) {
|
|
188
|
+
const accounts = this.messagingSystem.call('AccountsController:listMultichainAccounts');
|
|
189
|
+
if (!chainIds || chainIds.length === 0) {
|
|
190
|
+
return accounts;
|
|
191
|
+
}
|
|
192
|
+
return accounts.filter((account) => account.scopes.some((scope) => isMatchingChainId(scope, chainIds)));
|
|
179
193
|
}, _SnapInterfaceController_getAccountByAddress = function _SnapInterfaceController_getAccountByAddress(address) {
|
|
180
194
|
const { address: parsedAddress } = parseCaipAccountId(address);
|
|
181
195
|
return this.messagingSystem.call('AccountsController:getAccountByAddress', parsedAddress);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapInterfaceController.mjs","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest,\n HasApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { TestOrigin } from '@metamask/phishing-controller';\nimport type {\n InterfaceState,\n SnapId,\n ComponentOrElement,\n InterfaceContext,\n FungibleAssetMetadata,\n} from '@metamask/snaps-sdk';\nimport { ContentType } from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport type { InternalAccount } from '@metamask/snaps-utils';\nimport { getJsonSizeUnsafe, validateJsxElements } from '@metamask/snaps-utils';\nimport type { CaipAccountId, CaipAssetType, Json } from '@metamask/utils';\nimport { assert, hasProperty, parseCaipAccountId } from '@metamask/utils';\nimport { castDraft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport {\n constructState,\n getJsxInterface,\n validateInterfaceContext,\n} from './utils';\nimport type { GetSnap } from '../snaps';\n\nconst MAX_UI_CONTENT_SIZE = 10_000_000; // 10 mb\n\nconst controllerName = 'SnapInterfaceController';\n\nexport type CreateInterface = {\n type: `${typeof controllerName}:createInterface`;\n handler: SnapInterfaceController['createInterface'];\n};\n\nexport type GetInterface = {\n type: `${typeof controllerName}:getInterface`;\n handler: SnapInterfaceController['getInterface'];\n};\n\nexport type UpdateInterface = {\n type: `${typeof controllerName}:updateInterface`;\n handler: SnapInterfaceController['updateInterface'];\n};\n\nexport type DeleteInterface = {\n type: `${typeof controllerName}:deleteInterface`;\n handler: SnapInterfaceController['deleteInterface'];\n};\n\nexport type UpdateInterfaceState = {\n type: `${typeof controllerName}:updateInterfaceState`;\n handler: SnapInterfaceController['updateInterfaceState'];\n};\n\nexport type ResolveInterface = {\n type: `${typeof controllerName}:resolveInterface`;\n handler: SnapInterfaceController['resolveInterface'];\n};\n\ntype AccountsControllerGetAccountByAddressAction = {\n type: `AccountsController:getAccountByAddress`;\n handler: (address: string) => InternalAccount | undefined;\n};\n\nexport type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapInterfaceControllerState\n>;\n\ntype MultichainAssetsControllerGetStateAction = ControllerGetStateAction<\n 'MultichainAssetsController',\n {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n }\n>;\n\nexport type SnapInterfaceControllerAllowedActions =\n | TestOrigin\n | HasApprovalRequest\n | AcceptRequest\n | GetSnap\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetAccountByAddressAction;\n\nexport type SnapInterfaceControllerActions =\n | CreateInterface\n | GetInterface\n | UpdateInterface\n | DeleteInterface\n | UpdateInterfaceState\n | ResolveInterface\n | SnapInterfaceControllerGetStateAction;\n\nexport type SnapInterfaceControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SnapInterfaceControllerState\n >;\n\ntype OtherNotification = { type: string; [key: string]: unknown };\n\nexport type ExpandedView = {\n title: string;\n interfaceId: string;\n footerLink?: { href: string; text: string };\n};\n\ntype NormalSnapNotificationData = { message: string; origin: string };\n\ntype ExpandedSnapNotificationData = {\n message: string;\n origin: string;\n detailedView: ExpandedView;\n};\n\ntype SnapNotification = {\n type: 'snap';\n data: NormalSnapNotificationData | ExpandedSnapNotificationData;\n readDate: string | null;\n};\n\ntype Notification = OtherNotification | SnapNotification;\n\ntype NotificationListUpdatedEvent = {\n type: 'NotificationServicesController:notificationsListUpdated';\n payload: [Notification[]];\n};\n\nexport type SnapInterfaceControllerEvents =\n | SnapInterfaceControllerStateChangeEvent\n | NotificationListUpdatedEvent;\n\nexport type SnapInterfaceControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapInterfaceControllerActions | SnapInterfaceControllerAllowedActions,\n SnapInterfaceControllerEvents,\n SnapInterfaceControllerAllowedActions['type'],\n SnapInterfaceControllerEvents['type']\n>;\n\nexport type StoredInterface = {\n snapId: SnapId;\n content: JSXElement;\n state: InterfaceState;\n context: InterfaceContext | null;\n contentType: ContentType | null;\n};\n\nexport type SnapInterfaceControllerState = {\n interfaces: Record<string, StoredInterface>;\n};\n\nexport type SnapInterfaceControllerArgs = {\n messenger: SnapInterfaceControllerMessenger;\n state?: SnapInterfaceControllerState;\n};\n\n/**\n * Use this controller to manage snaps UI interfaces using RPC method hooks.\n */\nexport class SnapInterfaceController extends BaseController<\n typeof controllerName,\n SnapInterfaceControllerState,\n SnapInterfaceControllerMessenger\n> {\n constructor({ messenger, state }: SnapInterfaceControllerArgs) {\n super({\n messenger,\n metadata: {\n interfaces: {\n persist: (interfaces: Record<string, StoredInterface>) => {\n return Object.entries(interfaces).reduce<\n Record<string, StoredInterface>\n >((persistedInterfaces, [id, snapInterface]) => {\n switch (snapInterface.contentType) {\n case ContentType.Notification:\n persistedInterfaces[id] = snapInterface;\n return persistedInterfaces;\n default:\n return persistedInterfaces;\n }\n }, {});\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: { interfaces: {}, ...state },\n });\n\n this.messagingSystem.subscribe(\n 'NotificationServicesController:notificationsListUpdated',\n this.#onNotificationsListUpdated.bind(this),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:createInterface`,\n this.createInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getInterface`,\n this.getInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterface`,\n this.updateInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:deleteInterface`,\n this.deleteInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterfaceState`,\n this.updateInterfaceState.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:resolveInterface`,\n this.resolveInterface.bind(this),\n );\n }\n\n /**\n * Create an interface in the controller state with the associated data.\n *\n * @param snapId - The snap id that created the interface.\n * @param content - The interface content.\n * @param context - An optional interface context object.\n * @param contentType - The type of content.\n * @returns The newly interface id.\n */\n async createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n context?: InterfaceContext,\n contentType?: ContentType,\n ) {\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const id = nanoid();\n const componentState = constructState({}, element, {\n getAssetsState: this.#getAssetsState.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n });\n\n this.update((draftState) => {\n // @ts-expect-error - TS2589: Type instantiation is excessively deep and\n // possibly infinite.\n draftState.interfaces[id] = {\n snapId,\n content: castDraft(element),\n state: componentState,\n context: context ?? null,\n contentType: contentType ?? null,\n };\n });\n\n return id;\n }\n\n /**\n * Get the data of a given interface id.\n *\n * @param snapId - The snap id requesting the interface data.\n * @param id - The interface id.\n * @returns The interface state.\n */\n getInterface(snapId: SnapId, id: string) {\n this.#validateArgs(snapId, id);\n\n return this.state.interfaces[id];\n }\n\n /**\n * Update the interface with the given content.\n *\n * @param snapId - The snap id requesting the update.\n * @param id - The interface id.\n * @param content - The new content.\n * @param context - An optional interface context object.\n */\n async updateInterface(\n snapId: SnapId,\n id: string,\n content: ComponentOrElement,\n context?: InterfaceContext,\n ) {\n this.#validateArgs(snapId, id);\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const oldState = this.state.interfaces[id].state;\n const newState = constructState(oldState, element, {\n getAssetsState: this.#getAssetsState.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n });\n\n this.update((draftState) => {\n draftState.interfaces[id].state = newState;\n draftState.interfaces[id].content = castDraft(element);\n if (context) {\n draftState.interfaces[id].context = context;\n }\n });\n }\n\n /**\n * Delete an interface from state.\n *\n * @param id - The interface id.\n */\n deleteInterface(id: string) {\n this.update((draftState) => {\n delete draftState.interfaces[id];\n });\n }\n\n /**\n * Update the interface state.\n *\n * @param id - The interface id.\n * @param state - The new state.\n */\n updateInterfaceState(id: string, state: InterfaceState) {\n this.update((draftState) => {\n draftState.interfaces[id].state = state;\n });\n }\n\n /**\n * Resolve the promise of a given interface approval request.\n * The approval needs to have the same ID as the interface.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async resolveInterface(snapId: SnapId, id: string, value: Json) {\n this.#validateArgs(snapId, id);\n this.#validateApproval(id);\n\n await this.#acceptApprovalRequest(id, value);\n\n this.deleteInterface(id);\n }\n\n /**\n * Utility function to validate the args passed to the other methods.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n */\n #validateArgs(snapId: SnapId, id: string) {\n const existingInterface = this.state.interfaces[id];\n\n assert(\n existingInterface !== undefined,\n `Interface with id '${id}' not found.`,\n );\n assert(\n existingInterface.snapId === snapId,\n `Interface not created by ${snapId}.`,\n );\n }\n\n /**\n * Utility function to validate that the approval request exists.\n *\n * @param id - The interface id.\n */\n #validateApproval(id: string) {\n assert(\n this.#hasApprovalRequest(id),\n `Approval request with id '${id}' not found.`,\n );\n }\n\n /**\n * Check an origin against the phishing list.\n *\n * @param origin - The origin to check.\n * @returns True if the origin is on the phishing list, otherwise false.\n */\n #checkPhishingList(origin: string) {\n return this.messagingSystem.call('PhishingController:testOrigin', origin)\n .result;\n }\n\n /**\n * Check if an approval request exists for a given interface by looking up\n * if the ApprovalController has a request with the given interface ID.\n *\n * @param id - The interface id.\n * @returns True if an approval request exists, otherwise false.\n */\n #hasApprovalRequest(id: string) {\n return this.messagingSystem.call('ApprovalController:hasRequest', {\n id,\n });\n }\n\n /**\n * Accept an approval request for a given interface.\n *\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async #acceptApprovalRequest(id: string, value: Json) {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n value,\n );\n }\n\n /**\n * Get an account by its address.\n *\n * @param address - The account address.\n * @returns The account or undefined if not found.\n */\n #getAccountByAddress(address: CaipAccountId) {\n const { address: parsedAddress } = parseCaipAccountId(address);\n\n return this.messagingSystem.call(\n 'AccountsController:getAccountByAddress',\n parsedAddress,\n );\n }\n\n /**\n * Get the MultichainAssetsController state.\n *\n * @returns The MultichainAssetsController state.\n */\n #getAssetsState() {\n return this.messagingSystem.call('MultichainAssetsController:getState');\n }\n\n /**\n * Get a snap by its id.\n *\n * @param id - The snap id.\n * @returns The snap.\n */\n #getSnap(id: string) {\n return this.messagingSystem.call('SnapController:get', id);\n }\n\n /**\n * Utility function to validate the components of an interface.\n * Throws if something is invalid.\n *\n * @param element - The JSX element to verify.\n */\n async #validateContent(element: JSXElement) {\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(element);\n assert(\n size <= MAX_UI_CONTENT_SIZE,\n `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1000000} MB.`,\n );\n\n validateJsxElements(element, {\n isOnPhishingList: this.#checkPhishingList.bind(this),\n getSnap: this.#getSnap.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n });\n }\n\n #onNotificationsListUpdated(notificationsList: Notification[]) {\n const snapNotificationsWithInterface = notificationsList.filter(\n (notification) => {\n return (\n notification.type === 'snap' &&\n hasProperty((notification as SnapNotification).data, 'detailedView')\n );\n },\n );\n\n const interfaceIdSet = new Set(\n snapNotificationsWithInterface.map(\n (notification) =>\n (\n (notification as SnapNotification)\n .data as ExpandedSnapNotificationData\n ).detailedView.interfaceId,\n ),\n );\n\n this.update((state) => {\n Object.entries(state.interfaces).forEach(([id, snapInterface]) => {\n if (\n snapInterface.contentType === ContentType.Notification &&\n !interfaceIdSet.has(id)\n ) {\n delete state.interfaces[id];\n }\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SnapInterfaceController.mjs","sourceRoot":"","sources":["../../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest,\n HasApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { TestOrigin } from '@metamask/phishing-controller';\nimport type {\n InterfaceState,\n SnapId,\n ComponentOrElement,\n InterfaceContext,\n FungibleAssetMetadata,\n} from '@metamask/snaps-sdk';\nimport { ContentType } from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport type { InternalAccount } from '@metamask/snaps-utils';\nimport {\n getJsonSizeUnsafe,\n snapOwnsAccount,\n validateJsxElements,\n} from '@metamask/snaps-utils';\nimport type {\n CaipAccountId,\n CaipAssetType,\n CaipChainId,\n Json,\n} from '@metamask/utils';\nimport { assert, hasProperty, parseCaipAccountId } from '@metamask/utils';\nimport { castDraft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport {\n constructState,\n getJsxInterface,\n isMatchingChainId,\n validateInterfaceContext,\n} from './utils';\nimport type { GetSnap } from '../snaps';\n\nconst MAX_UI_CONTENT_SIZE = 10_000_000; // 10 mb\n\nconst controllerName = 'SnapInterfaceController';\n\nexport type CreateInterface = {\n type: `${typeof controllerName}:createInterface`;\n handler: SnapInterfaceController['createInterface'];\n};\n\nexport type GetInterface = {\n type: `${typeof controllerName}:getInterface`;\n handler: SnapInterfaceController['getInterface'];\n};\n\nexport type UpdateInterface = {\n type: `${typeof controllerName}:updateInterface`;\n handler: SnapInterfaceController['updateInterface'];\n};\n\nexport type DeleteInterface = {\n type: `${typeof controllerName}:deleteInterface`;\n handler: SnapInterfaceController['deleteInterface'];\n};\n\nexport type UpdateInterfaceState = {\n type: `${typeof controllerName}:updateInterfaceState`;\n handler: SnapInterfaceController['updateInterfaceState'];\n};\n\nexport type ResolveInterface = {\n type: `${typeof controllerName}:resolveInterface`;\n handler: SnapInterfaceController['resolveInterface'];\n};\n\ntype AccountsControllerGetAccountByAddressAction = {\n type: `AccountsController:getAccountByAddress`;\n handler: (address: string) => InternalAccount | undefined;\n};\n\ntype AccountsControllerGetSelectedMultichainAccountAction = {\n type: `AccountsController:getSelectedMultichainAccount`;\n handler: () => InternalAccount;\n};\n\ntype AccountsControllerListMultichainAccountsAction = {\n type: `AccountsController:listMultichainAccounts`;\n handler: (chainId?: CaipChainId) => InternalAccount[];\n};\n\nexport type SnapInterfaceControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SnapInterfaceControllerState\n>;\n\ntype MultichainAssetsControllerGetStateAction = ControllerGetStateAction<\n 'MultichainAssetsController',\n {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n }\n>;\n\nexport type SnapInterfaceControllerAllowedActions =\n | TestOrigin\n | HasApprovalRequest\n | AcceptRequest\n | GetSnap\n | MultichainAssetsControllerGetStateAction\n | AccountsControllerGetSelectedMultichainAccountAction\n | AccountsControllerGetAccountByAddressAction\n | AccountsControllerListMultichainAccountsAction;\n\nexport type SnapInterfaceControllerActions =\n | CreateInterface\n | GetInterface\n | UpdateInterface\n | DeleteInterface\n | UpdateInterfaceState\n | ResolveInterface\n | SnapInterfaceControllerGetStateAction;\n\nexport type SnapInterfaceControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SnapInterfaceControllerState\n >;\n\ntype OtherNotification = { type: string; [key: string]: unknown };\n\nexport type ExpandedView = {\n title: string;\n interfaceId: string;\n footerLink?: { href: string; text: string };\n};\n\ntype NormalSnapNotificationData = { message: string; origin: string };\n\ntype ExpandedSnapNotificationData = {\n message: string;\n origin: string;\n detailedView: ExpandedView;\n};\n\ntype SnapNotification = {\n type: 'snap';\n data: NormalSnapNotificationData | ExpandedSnapNotificationData;\n readDate: string | null;\n};\n\ntype Notification = OtherNotification | SnapNotification;\n\ntype NotificationListUpdatedEvent = {\n type: 'NotificationServicesController:notificationsListUpdated';\n payload: [Notification[]];\n};\n\nexport type SnapInterfaceControllerEvents =\n | SnapInterfaceControllerStateChangeEvent\n | NotificationListUpdatedEvent;\n\nexport type SnapInterfaceControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n SnapInterfaceControllerActions | SnapInterfaceControllerAllowedActions,\n SnapInterfaceControllerEvents,\n SnapInterfaceControllerAllowedActions['type'],\n SnapInterfaceControllerEvents['type']\n>;\n\nexport type StoredInterface = {\n snapId: SnapId;\n content: JSXElement;\n state: InterfaceState;\n context: InterfaceContext | null;\n contentType: ContentType | null;\n};\n\nexport type SnapInterfaceControllerState = {\n interfaces: Record<string, StoredInterface>;\n};\n\nexport type SnapInterfaceControllerArgs = {\n messenger: SnapInterfaceControllerMessenger;\n state?: SnapInterfaceControllerState;\n};\n\n/**\n * Use this controller to manage snaps UI interfaces using RPC method hooks.\n */\nexport class SnapInterfaceController extends BaseController<\n typeof controllerName,\n SnapInterfaceControllerState,\n SnapInterfaceControllerMessenger\n> {\n constructor({ messenger, state }: SnapInterfaceControllerArgs) {\n super({\n messenger,\n metadata: {\n interfaces: {\n persist: (interfaces: Record<string, StoredInterface>) => {\n return Object.entries(interfaces).reduce<\n Record<string, StoredInterface>\n >((persistedInterfaces, [id, snapInterface]) => {\n switch (snapInterface.contentType) {\n case ContentType.Notification:\n persistedInterfaces[id] = snapInterface;\n return persistedInterfaces;\n default:\n return persistedInterfaces;\n }\n }, {});\n },\n anonymous: false,\n },\n },\n name: controllerName,\n state: { interfaces: {}, ...state },\n });\n\n this.messagingSystem.subscribe(\n 'NotificationServicesController:notificationsListUpdated',\n this.#onNotificationsListUpdated.bind(this),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:createInterface`,\n this.createInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getInterface`,\n this.getInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterface`,\n this.updateInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:deleteInterface`,\n this.deleteInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterfaceState`,\n this.updateInterfaceState.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:resolveInterface`,\n this.resolveInterface.bind(this),\n );\n }\n\n /**\n * Create an interface in the controller state with the associated data.\n *\n * @param snapId - The snap id that created the interface.\n * @param content - The interface content.\n * @param context - An optional interface context object.\n * @param contentType - The type of content.\n * @returns The newly interface id.\n */\n async createInterface(\n snapId: SnapId,\n content: ComponentOrElement,\n context?: InterfaceContext,\n contentType?: ContentType,\n ) {\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const id = nanoid();\n const componentState = constructState({}, element, {\n getAssetsState: this.#getAssetsState.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n getSelectedAccount: this.#getSelectedAccount.bind(this),\n listAccounts: this.#listAccounts.bind(this),\n snapOwnsAccount: (account: InternalAccount) =>\n snapOwnsAccount(snapId, account),\n });\n\n this.update((draftState) => {\n // @ts-expect-error - TS2589: Type instantiation is excessively deep and\n // possibly infinite.\n draftState.interfaces[id] = {\n snapId,\n content: castDraft(element),\n state: componentState,\n context: context ?? null,\n contentType: contentType ?? null,\n };\n });\n\n return id;\n }\n\n /**\n * Get the data of a given interface id.\n *\n * @param snapId - The snap id requesting the interface data.\n * @param id - The interface id.\n * @returns The interface state.\n */\n getInterface(snapId: SnapId, id: string) {\n this.#validateArgs(snapId, id);\n\n return this.state.interfaces[id];\n }\n\n /**\n * Update the interface with the given content.\n *\n * @param snapId - The snap id requesting the update.\n * @param id - The interface id.\n * @param content - The new content.\n * @param context - An optional interface context object.\n */\n async updateInterface(\n snapId: SnapId,\n id: string,\n content: ComponentOrElement,\n context?: InterfaceContext,\n ) {\n this.#validateArgs(snapId, id);\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n validateInterfaceContext(context);\n\n const oldState = this.state.interfaces[id].state;\n const newState = constructState(oldState, element, {\n getAssetsState: this.#getAssetsState.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n getSelectedAccount: this.#getSelectedAccount.bind(this),\n listAccounts: this.#listAccounts.bind(this),\n snapOwnsAccount: (account: InternalAccount) =>\n snapOwnsAccount(snapId, account),\n });\n\n this.update((draftState) => {\n draftState.interfaces[id].state = newState;\n draftState.interfaces[id].content = castDraft(element);\n if (context) {\n draftState.interfaces[id].context = context;\n }\n });\n }\n\n /**\n * Delete an interface from state.\n *\n * @param id - The interface id.\n */\n deleteInterface(id: string) {\n this.update((draftState) => {\n delete draftState.interfaces[id];\n });\n }\n\n /**\n * Update the interface state.\n *\n * @param id - The interface id.\n * @param state - The new state.\n */\n updateInterfaceState(id: string, state: InterfaceState) {\n this.update((draftState) => {\n draftState.interfaces[id].state = state;\n });\n }\n\n /**\n * Resolve the promise of a given interface approval request.\n * The approval needs to have the same ID as the interface.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async resolveInterface(snapId: SnapId, id: string, value: Json) {\n this.#validateArgs(snapId, id);\n this.#validateApproval(id);\n\n await this.#acceptApprovalRequest(id, value);\n\n this.deleteInterface(id);\n }\n\n /**\n * Utility function to validate the args passed to the other methods.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n */\n #validateArgs(snapId: SnapId, id: string) {\n const existingInterface = this.state.interfaces[id];\n\n assert(\n existingInterface !== undefined,\n `Interface with id '${id}' not found.`,\n );\n assert(\n existingInterface.snapId === snapId,\n `Interface not created by ${snapId}.`,\n );\n }\n\n /**\n * Utility function to validate that the approval request exists.\n *\n * @param id - The interface id.\n */\n #validateApproval(id: string) {\n assert(\n this.#hasApprovalRequest(id),\n `Approval request with id '${id}' not found.`,\n );\n }\n\n /**\n * Check an origin against the phishing list.\n *\n * @param origin - The origin to check.\n * @returns True if the origin is on the phishing list, otherwise false.\n */\n #checkPhishingList(origin: string) {\n return this.messagingSystem.call('PhishingController:testOrigin', origin)\n .result;\n }\n\n /**\n * Check if an approval request exists for a given interface by looking up\n * if the ApprovalController has a request with the given interface ID.\n *\n * @param id - The interface id.\n * @returns True if an approval request exists, otherwise false.\n */\n #hasApprovalRequest(id: string) {\n return this.messagingSystem.call('ApprovalController:hasRequest', {\n id,\n });\n }\n\n /**\n * Accept an approval request for a given interface.\n *\n * @param id - The interface id.\n * @param value - The value to resolve the promise with.\n */\n async #acceptApprovalRequest(id: string, value: Json) {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n value,\n );\n }\n\n /**\n * Get the selected account in the client.\n *\n * @returns The selected account.\n */\n #getSelectedAccount() {\n return this.messagingSystem.call(\n 'AccountsController:getSelectedMultichainAccount',\n );\n }\n\n /**\n * Get a list of accounts for the given chain IDs.\n *\n * @param chainIds - The chain IDs to get the accounts for.\n * @returns The list of accounts.\n */\n #listAccounts(chainIds?: CaipChainId[]) {\n const accounts = this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n\n if (!chainIds || chainIds.length === 0) {\n return accounts;\n }\n\n return accounts.filter((account) =>\n account.scopes.some((scope) => isMatchingChainId(scope, chainIds)),\n );\n }\n\n /**\n * Get an account by its address.\n *\n * @param address - The account address.\n * @returns The account or undefined if not found.\n */\n #getAccountByAddress(address: CaipAccountId) {\n const { address: parsedAddress } = parseCaipAccountId(address);\n\n return this.messagingSystem.call(\n 'AccountsController:getAccountByAddress',\n parsedAddress,\n );\n }\n\n /**\n * Get the MultichainAssetsController state.\n *\n * @returns The MultichainAssetsController state.\n */\n #getAssetsState() {\n return this.messagingSystem.call('MultichainAssetsController:getState');\n }\n\n /**\n * Get a snap by its id.\n *\n * @param id - The snap id.\n * @returns The snap.\n */\n #getSnap(id: string) {\n return this.messagingSystem.call('SnapController:get', id);\n }\n\n /**\n * Utility function to validate the components of an interface.\n * Throws if something is invalid.\n *\n * @param element - The JSX element to verify.\n */\n async #validateContent(element: JSXElement) {\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(element);\n assert(\n size <= MAX_UI_CONTENT_SIZE,\n `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1000000} MB.`,\n );\n\n validateJsxElements(element, {\n isOnPhishingList: this.#checkPhishingList.bind(this),\n getSnap: this.#getSnap.bind(this),\n getAccountByAddress: this.#getAccountByAddress.bind(this),\n });\n }\n\n #onNotificationsListUpdated(notificationsList: Notification[]) {\n const snapNotificationsWithInterface = notificationsList.filter(\n (notification) => {\n return (\n notification.type === 'snap' &&\n hasProperty((notification as SnapNotification).data, 'detailedView')\n );\n },\n );\n\n const interfaceIdSet = new Set(\n snapNotificationsWithInterface.map(\n (notification) =>\n (\n (notification as SnapNotification)\n .data as ExpandedSnapNotificationData\n ).detailedView.interfaceId,\n ),\n );\n\n this.update((state) => {\n Object.entries(state.interfaces).forEach(([id, snapInterface]) => {\n if (\n snapInterface.contentType === ContentType.Notification &&\n !interfaceIdSet.has(id)\n ) {\n delete state.interfaces[id];\n }\n });\n });\n }\n}\n"]}
|
package/dist/interface/utils.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateInterfaceContext = exports.constructState = exports.getAssetSelectorStateValue = exports.getDefaultAsset = exports.assertNameIsUnique = exports.getJsxInterface = exports.isStatefulComponent = void 0;
|
|
3
|
+
exports.validateInterfaceContext = exports.constructState = exports.getAccountSelectorStateValue = exports.getAssetSelectorStateValue = exports.getAccountSelectorDefaultStateValue = exports.getDefaultAsset = exports.formatAccountSelectorStateValue = exports.isMatchingChainId = exports.assertNameIsUnique = exports.getJsxInterface = exports.isStatefulComponent = void 0;
|
|
4
4
|
const snaps_sdk_1 = require("@metamask/snaps-sdk");
|
|
5
5
|
const jsx_1 = require("@metamask/snaps-sdk/jsx");
|
|
6
6
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
@@ -17,6 +17,7 @@ const STATEFUL_COMPONENT_TYPES = [
|
|
|
17
17
|
'Selector',
|
|
18
18
|
'AssetSelector',
|
|
19
19
|
'AddressInput',
|
|
20
|
+
'AccountSelector',
|
|
20
21
|
];
|
|
21
22
|
/**
|
|
22
23
|
* Check if a component is a stateful component.
|
|
@@ -55,6 +56,42 @@ function assertNameIsUnique(state, name) {
|
|
|
55
56
|
(0, snaps_sdk_1.assert)(state[name] === undefined, `Duplicate component names are not allowed, found multiple instances of: "${name}".`);
|
|
56
57
|
}
|
|
57
58
|
exports.assertNameIsUnique = assertNameIsUnique;
|
|
59
|
+
/**
|
|
60
|
+
* Check if the chain ID matches the scope.
|
|
61
|
+
* This function handles the case where a scope represents all EVM compatible chains.
|
|
62
|
+
* In this case, it returns true if the chain ID is an EIP-155 chain ID.
|
|
63
|
+
*
|
|
64
|
+
* @param scope - The scope to check.
|
|
65
|
+
* @param chainIds - The chain IDs to check against.
|
|
66
|
+
* @returns Whether one of the chain ID matches the scope.
|
|
67
|
+
*/
|
|
68
|
+
function isMatchingChainId(scope, chainIds) {
|
|
69
|
+
// if the scope represents all EVM compatible chains, return true if the namespace is EIP-155.
|
|
70
|
+
if (scope === 'eip155:0') {
|
|
71
|
+
return chainIds.some((chainId) => {
|
|
72
|
+
const { namespace } = (0, utils_1.parseCaipChainId)(chainId);
|
|
73
|
+
return namespace === utils_1.KnownCaipNamespace.Eip155;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Otherwise, check if the scope is in the chain IDs.
|
|
77
|
+
return chainIds.includes(scope);
|
|
78
|
+
}
|
|
79
|
+
exports.isMatchingChainId = isMatchingChainId;
|
|
80
|
+
/**
|
|
81
|
+
* Format the state value for an account selector.
|
|
82
|
+
*
|
|
83
|
+
* @param account - The account to format.
|
|
84
|
+
* @param requestedChainIds - The requested chain IDs.
|
|
85
|
+
*
|
|
86
|
+
* @returns The state value for the account selector.
|
|
87
|
+
*/
|
|
88
|
+
function formatAccountSelectorStateValue(account, requestedChainIds) {
|
|
89
|
+
const { id, address, scopes } = account;
|
|
90
|
+
const chainIds = (0, snaps_utils_1.createChainIdList)(scopes, requestedChainIds);
|
|
91
|
+
const addresses = (0, snaps_utils_1.createAccountList)(address, chainIds);
|
|
92
|
+
return { accountId: id, addresses };
|
|
93
|
+
}
|
|
94
|
+
exports.formatAccountSelectorStateValue = formatAccountSelectorStateValue;
|
|
58
95
|
/**
|
|
59
96
|
* Get a default asset for a given address.
|
|
60
97
|
*
|
|
@@ -100,6 +137,42 @@ function getDefaultAsset(addresses, chainIds, { getAccountByAddress, getAssetsSt
|
|
|
100
137
|
};
|
|
101
138
|
}
|
|
102
139
|
exports.getDefaultAsset = getDefaultAsset;
|
|
140
|
+
/**
|
|
141
|
+
* Get the default state value for an account selector.
|
|
142
|
+
*
|
|
143
|
+
* @param element - The account selector element.
|
|
144
|
+
* @param elementDataGetters - Data getters for the element.
|
|
145
|
+
* @param elementDataGetters.getSelectedAccount - A function to get the selected account in the client.
|
|
146
|
+
* @param elementDataGetters.listAccounts - A function to list accounts for the provided chain IDs.
|
|
147
|
+
* @param elementDataGetters.snapOwnsAccount - A function to check if the snap owns the account.
|
|
148
|
+
* @returns The default state for the account selector.
|
|
149
|
+
*/
|
|
150
|
+
function getAccountSelectorDefaultStateValue(element, { getSelectedAccount, listAccounts, snapOwnsAccount }) {
|
|
151
|
+
const { chainIds, hideExternalAccounts } = element.props;
|
|
152
|
+
const selectedAccount = getSelectedAccount();
|
|
153
|
+
// Use the selected account if it matches.
|
|
154
|
+
// The following conditions are checked:
|
|
155
|
+
// - If the selected account has any of the requested chain IDs in its scopes.
|
|
156
|
+
// - If the selected account is owned by the snap and hideExternalAccounts is true.
|
|
157
|
+
if ((!chainIds ||
|
|
158
|
+
chainIds.length === 0 ||
|
|
159
|
+
selectedAccount.scopes.some((scope) => isMatchingChainId(scope, chainIds))) &&
|
|
160
|
+
(!hideExternalAccounts ||
|
|
161
|
+
(hideExternalAccounts && snapOwnsAccount(selectedAccount)))) {
|
|
162
|
+
return formatAccountSelectorStateValue(selectedAccount, chainIds);
|
|
163
|
+
}
|
|
164
|
+
const accounts = listAccounts(chainIds);
|
|
165
|
+
const filteredAccounts = hideExternalAccounts
|
|
166
|
+
? accounts.filter((account) => snapOwnsAccount(account))
|
|
167
|
+
: accounts;
|
|
168
|
+
// The AccountSelector component in the UI will be disabled if there is no account available for the networks provided.
|
|
169
|
+
// In this case, we return null to indicate that there is no default selected account.
|
|
170
|
+
if (filteredAccounts.length === 0) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return formatAccountSelectorStateValue(filteredAccounts[0], chainIds);
|
|
174
|
+
}
|
|
175
|
+
exports.getAccountSelectorDefaultStateValue = getAccountSelectorDefaultStateValue;
|
|
103
176
|
/**
|
|
104
177
|
* Construct default state for a component.
|
|
105
178
|
*
|
|
@@ -125,6 +198,8 @@ function constructComponentSpecificDefaultState(element, elementDataGetters) {
|
|
|
125
198
|
const children = (0, snaps_utils_1.getJsxChildren)(element);
|
|
126
199
|
return children[0]?.props.value;
|
|
127
200
|
}
|
|
201
|
+
case 'AccountSelector':
|
|
202
|
+
return getAccountSelectorDefaultStateValue(element, elementDataGetters);
|
|
128
203
|
case 'Checkbox':
|
|
129
204
|
return false;
|
|
130
205
|
case 'AssetSelector':
|
|
@@ -156,6 +231,30 @@ function getAssetSelectorStateValue(value, getAssetState) {
|
|
|
156
231
|
};
|
|
157
232
|
}
|
|
158
233
|
exports.getAssetSelectorStateValue = getAssetSelectorStateValue;
|
|
234
|
+
/**
|
|
235
|
+
* Get the state value for an account selector.
|
|
236
|
+
*
|
|
237
|
+
* @param element - The account selector element.
|
|
238
|
+
* @param elementDataGetters - Data getters for the element.
|
|
239
|
+
* @param elementDataGetters.getAccountByAddress - A function to get an account by address.
|
|
240
|
+
* @param elementDataGetters.snapOwnsAccount - A function to check if the snap owns the account.
|
|
241
|
+
* @returns The state value for the account selector.
|
|
242
|
+
*/
|
|
243
|
+
function getAccountSelectorStateValue(element, { getAccountByAddress, snapOwnsAccount }) {
|
|
244
|
+
const { value, hideExternalAccounts } = element.props;
|
|
245
|
+
if (!value) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const account = getAccountByAddress(value);
|
|
249
|
+
if (!account) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
if (hideExternalAccounts && !snapOwnsAccount(account)) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
return formatAccountSelectorStateValue(account, element.props.chainIds);
|
|
256
|
+
}
|
|
257
|
+
exports.getAccountSelectorStateValue = getAccountSelectorStateValue;
|
|
159
258
|
/**
|
|
160
259
|
* Get the state value for a stateful component.
|
|
161
260
|
*
|
|
@@ -164,15 +263,14 @@ exports.getAssetSelectorStateValue = getAssetSelectorStateValue;
|
|
|
164
263
|
*
|
|
165
264
|
* @param element - The input element.
|
|
166
265
|
* @param elementDataGetters - Data getters for the element.
|
|
167
|
-
* @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.
|
|
168
266
|
* @returns The state value for a given component.
|
|
169
267
|
*/
|
|
170
|
-
function getComponentStateValue(element,
|
|
268
|
+
function getComponentStateValue(element, elementDataGetters) {
|
|
171
269
|
switch (element.type) {
|
|
172
270
|
case 'Checkbox':
|
|
173
271
|
return element.props.checked;
|
|
174
272
|
case 'AssetSelector':
|
|
175
|
-
return getAssetSelectorStateValue(element.props.value, getAssetsState);
|
|
273
|
+
return getAssetSelectorStateValue(element.props.value, elementDataGetters.getAssetsState);
|
|
176
274
|
case 'AddressInput': {
|
|
177
275
|
if (!element.props.value) {
|
|
178
276
|
return null;
|
|
@@ -181,6 +279,8 @@ function getComponentStateValue(element, { getAssetsState }) {
|
|
|
181
279
|
const { namespace, reference } = (0, utils_1.parseCaipChainId)(element.props.chainId);
|
|
182
280
|
return (0, utils_1.toCaipAccountId)(namespace, reference, element.props.value);
|
|
183
281
|
}
|
|
282
|
+
case 'AccountSelector':
|
|
283
|
+
return getAccountSelectorStateValue(element, elementDataGetters);
|
|
184
284
|
default:
|
|
185
285
|
return element.props.value;
|
|
186
286
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/snaps-sdk';\nimport type {\n FormState,\n InterfaceState,\n ComponentOrElement,\n InterfaceContext,\n State,\n FungibleAssetMetadata,\n AssetSelectorState,\n CaipChainId,\n} from '@metamask/snaps-sdk';\nimport type {\n DropdownElement,\n InputElement,\n JSXElement,\n OptionElement,\n FileInputElement,\n CheckboxElement,\n RadioGroupElement,\n RadioElement,\n SelectorElement,\n SelectorOptionElement,\n AssetSelectorElement,\n AddressInputElement,\n} from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport type { InternalAccount } from '@metamask/snaps-utils';\nimport {\n getJsonSizeUnsafe,\n getJsxChildren,\n getJsxElementFromComponent,\n walkJsx,\n} from '@metamask/snaps-utils';\nimport {\n type CaipAssetType,\n type CaipAccountId,\n parseCaipAccountId,\n parseCaipAssetType,\n toCaipAccountId,\n parseCaipChainId,\n} from '@metamask/utils';\n\n/**\n * A list of stateful component types.\n */\nconst STATEFUL_COMPONENT_TYPES = [\n 'Input',\n 'Dropdown',\n 'RadioGroup',\n 'FileInput',\n 'Checkbox',\n 'Selector',\n 'AssetSelector',\n 'AddressInput',\n] as const;\n\n/**\n * Type for stateful component types.\n */\ntype StatefulComponentType = (typeof STATEFUL_COMPONENT_TYPES)[number];\n\n/**\n * Check if a component is a stateful component.\n *\n * @param component - The component to check.\n * @param component.type - The type of the component.\n *\n * @returns Whether the component is a stateful component.\n */\nexport function isStatefulComponent(component: { type: string }): component is {\n type: StatefulComponentType;\n} {\n return STATEFUL_COMPONENT_TYPES.includes(\n component.type as StatefulComponentType,\n );\n}\n\n/**\n * A function to get the MultichainAssetController state.\n *\n * @returns The MultichainAssetController state.\n */\ntype GetAssetsState = () => {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n};\n\n/**\n * A function to get an account by its address.\n *\n * @param address - The account address.\n * @returns The account or undefined if not found.\n */\ntype GetAccountByAddress = (\n address: CaipAccountId,\n) => InternalAccount | undefined;\n\n/**\n * Data getters for elements.\n * This is used to get data from elements that is not directly accessible from the element itself.\n *\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @param getAccountByAddress - A function to get an account by its address.\n */\ntype ElementDataGetters = {\n getAssetsState: GetAssetsState;\n getAccountByAddress: GetAccountByAddress;\n};\n\n/**\n * Get a JSX element from a component or JSX element. If the component is a\n * JSX element, it is returned as is. Otherwise, the component is converted to\n * a JSX element.\n *\n * @param component - The component to convert.\n * @returns The JSX element.\n */\nexport function getJsxInterface(component: ComponentOrElement): JSXElement {\n if (isJSXElementUnsafe(component)) {\n return component;\n }\n\n return getJsxElementFromComponent(component);\n}\n\n/**\n * Assert that the component name is unique in state.\n *\n * @param state - The interface state to verify against.\n * @param name - The component name to verify.\n */\nexport function assertNameIsUnique(state: InterfaceState, name: string) {\n assert(\n state[name] === undefined,\n `Duplicate component names are not allowed, found multiple instances of: \"${name}\".`,\n );\n}\n\n/**\n * Get a default asset for a given address.\n *\n * @param addresses - The account addresses.\n * @param chainIds - The chain IDs to filter the assets.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAccountByAddress - A function to get an account by its address.\n * @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.\n *\n * @returns The default asset for the account or undefined if not found.\n */\nexport function getDefaultAsset(\n addresses: CaipAccountId[],\n chainIds: CaipChainId[] | undefined,\n { getAccountByAddress, getAssetsState }: ElementDataGetters,\n) {\n const { assetsMetadata, accountsAssets } = getAssetsState();\n\n const parsedAccounts = addresses.map((address) =>\n parseCaipAccountId(address),\n );\n\n const accountChainIds = parsedAccounts.map(({ chainId }) => chainId);\n\n const filteredChainIds =\n chainIds && chainIds.length > 0\n ? accountChainIds.filter((accountChainId) =>\n chainIds.includes(accountChainId),\n )\n : accountChainIds;\n\n const accountId = getAccountByAddress(addresses[0])?.id;\n\n // We should never fail on this assertion as the address is already validated.\n assert(accountId, `Account not found for address: ${addresses[0]}.`);\n\n const accountAssets = accountsAssets[accountId];\n\n // The AssetSelector component in the UI will be disabled if there is no asset available for the account\n // and networks provided. In this case, we return null to indicate that there is no default selected asset.\n if (accountAssets.length === 0) {\n return null;\n }\n\n const nativeAsset = accountAssets.find((asset) => {\n const { chainId, assetNamespace } = parseCaipAssetType(asset);\n\n return filteredChainIds.includes(chainId) && assetNamespace === 'slip44';\n });\n\n if (nativeAsset) {\n return {\n asset: nativeAsset,\n name: assetsMetadata[nativeAsset].name,\n symbol: assetsMetadata[nativeAsset].symbol,\n };\n }\n\n return {\n asset: accountAssets[0],\n name: assetsMetadata[accountAssets[0]].name,\n symbol: assetsMetadata[accountAssets[0]].symbol,\n };\n}\n\n/**\n * Construct default state for a component.\n *\n * This function is meant to be used inside constructInputState to account\n * for component specific defaults and will not override the component value or existing form state.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n *\n * @returns The default state for the specific component, if any.\n */\nfunction constructComponentSpecificDefaultState(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n elementDataGetters: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Dropdown': {\n const children = getJsxChildren(element) as OptionElement[];\n return children[0]?.props.value;\n }\n\n case 'RadioGroup': {\n const children = getJsxChildren(element) as RadioElement[];\n return children[0]?.props.value;\n }\n\n case 'Selector': {\n const children = getJsxChildren(element) as SelectorOptionElement[];\n return children[0]?.props.value;\n }\n\n case 'Checkbox':\n return false;\n\n case 'AssetSelector':\n return getDefaultAsset(\n element.props.addresses,\n element.props.chainIds,\n elementDataGetters,\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get the state value for an asset selector.\n *\n * @param value - The asset selector value.\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @returns The state value for the asset selector or null.\n */\nexport function getAssetSelectorStateValue(\n value: CaipAssetType | undefined,\n getAssetState: GetAssetsState,\n): AssetSelectorState | null {\n if (!value) {\n return null;\n }\n\n const { assetsMetadata } = getAssetState();\n const asset = assetsMetadata[value];\n\n if (!asset) {\n return null;\n }\n\n return {\n asset: value,\n name: asset.name ?? asset.symbol ?? 'Unknown',\n symbol: asset.symbol ?? 'Unknown',\n };\n}\n\n/**\n * Get the state value for a stateful component.\n *\n * Most components store the state value as a `value` prop.\n * This function exists to account for components where that isn't the case.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.\n * @returns The state value for a given component.\n */\nfunction getComponentStateValue(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n { getAssetsState }: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Checkbox':\n return element.props.checked;\n\n case 'AssetSelector':\n return getAssetSelectorStateValue(element.props.value, getAssetsState);\n\n case 'AddressInput': {\n if (!element.props.value) {\n return null;\n }\n\n // Construct CAIP-10 Id\n const { namespace, reference } = parseCaipChainId(element.props.chainId);\n return toCaipAccountId(namespace, reference, element.props.value);\n }\n default:\n return element.props.value;\n }\n}\n\n/**\n * Construct the state for an input field.\n *\n * @param oldState - The previous state.\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @param form - An optional form that the input is enclosed in.\n * @returns The input state.\n */\nfunction constructInputState(\n oldState: InterfaceState,\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | FileInputElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n elementDataGetters: ElementDataGetters,\n form?: string,\n) {\n const oldStateUnwrapped = form ? (oldState[form] as FormState) : oldState;\n const oldInputState = oldStateUnwrapped?.[element.props.name] as State;\n\n if (element.type === 'FileInput') {\n return oldInputState ?? null;\n }\n\n return (\n getComponentStateValue(element, elementDataGetters) ??\n oldInputState ??\n constructComponentSpecificDefaultState(element, elementDataGetters) ??\n null\n );\n}\n\n/**\n * Construct the interface state for a given component tree.\n *\n * @param oldState - The previous state.\n * @param rootComponent - The UI component to construct state from.\n * @param elementDataGetters - Data getters for the elements.\n * @returns The interface state of the passed component.\n */\nexport function constructState(\n oldState: InterfaceState,\n rootComponent: JSXElement,\n elementDataGetters: ElementDataGetters,\n): InterfaceState {\n const newState: InterfaceState = {};\n\n // Stack containing the forms we have visited and at which depth\n const formStack: { name: string; depth: number }[] = [];\n\n walkJsx(rootComponent, (component, depth) => {\n let currentForm = formStack[formStack.length - 1];\n\n // Pop the current form of the stack once we leave its depth.\n if (currentForm && depth <= currentForm.depth) {\n formStack.pop();\n currentForm = formStack[formStack.length - 1];\n }\n\n if (component.type === 'Form') {\n assertNameIsUnique(newState, component.props.name);\n formStack.push({ name: component.props.name, depth });\n newState[component.props.name] = {};\n return;\n }\n\n // Stateful components inside a form\n if (currentForm && isStatefulComponent(component)) {\n const formState = newState[currentForm.name] as FormState;\n assertNameIsUnique(formState, component.props.name);\n formState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n currentForm.name,\n );\n return;\n }\n\n // Stateful components outside a form\n if (isStatefulComponent(component)) {\n assertNameIsUnique(newState, component.props.name);\n newState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n );\n }\n });\n\n return newState;\n}\n\nconst MAX_CONTEXT_SIZE = 5_000_000; // 5 mb\n\n/**\n * Validate a JSON blob to be used as the interface context.\n *\n * @param context - The JSON blob.\n * @throws If the JSON blob is too large.\n */\nexport function validateInterfaceContext(context?: InterfaceContext) {\n if (!context) {\n return;\n }\n\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(context);\n assert(\n size <= MAX_CONTEXT_SIZE,\n `A Snap interface context may not be larger than ${\n MAX_CONTEXT_SIZE / 1000000\n } MB.`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/snaps-sdk';\nimport type {\n FormState,\n InterfaceState,\n ComponentOrElement,\n InterfaceContext,\n State,\n FungibleAssetMetadata,\n AssetSelectorState,\n CaipChainId,\n} from '@metamask/snaps-sdk';\nimport type {\n DropdownElement,\n InputElement,\n JSXElement,\n OptionElement,\n FileInputElement,\n CheckboxElement,\n RadioGroupElement,\n RadioElement,\n SelectorElement,\n SelectorOptionElement,\n AssetSelectorElement,\n AddressInputElement,\n AccountSelectorElement,\n} from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport type { InternalAccount } from '@metamask/snaps-utils';\nimport {\n createAccountList,\n createChainIdList,\n getJsonSizeUnsafe,\n getJsxChildren,\n getJsxElementFromComponent,\n walkJsx,\n} from '@metamask/snaps-utils';\nimport {\n type CaipAssetType,\n type CaipAccountId,\n parseCaipAccountId,\n parseCaipAssetType,\n toCaipAccountId,\n parseCaipChainId,\n KnownCaipNamespace,\n} from '@metamask/utils';\n\n/**\n * A list of stateful component types.\n */\nconst STATEFUL_COMPONENT_TYPES = [\n 'Input',\n 'Dropdown',\n 'RadioGroup',\n 'FileInput',\n 'Checkbox',\n 'Selector',\n 'AssetSelector',\n 'AddressInput',\n 'AccountSelector',\n] as const;\n\n/**\n * Type for stateful component types.\n */\ntype StatefulComponentType = (typeof STATEFUL_COMPONENT_TYPES)[number];\n\n/**\n * Check if a component is a stateful component.\n *\n * @param component - The component to check.\n * @param component.type - The type of the component.\n *\n * @returns Whether the component is a stateful component.\n */\nexport function isStatefulComponent(component: { type: string }): component is {\n type: StatefulComponentType;\n} {\n return STATEFUL_COMPONENT_TYPES.includes(\n component.type as StatefulComponentType,\n );\n}\n\n/**\n * A function to get the MultichainAssetController state.\n *\n * @returns The MultichainAssetController state.\n */\ntype GetAssetsState = () => {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n};\n\n/**\n * A function to get an account by its address.\n *\n * @param address - The account address.\n * @returns The account or undefined if not found.\n */\ntype GetAccountByAddress = (\n address: CaipAccountId,\n) => InternalAccount | undefined;\n\n/**\n * A function to get the selected account in the client.\n *\n * @returns The selected account.\n */\ntype GetSelectedAccount = () => InternalAccount;\n\n/**\n * A function to get accounts for the provided chain IDs.\n */\ntype ListAccounts = (chainIds?: CaipChainId[]) => InternalAccount[];\n\n/**\n * A function to check if the snap owns the account.\n */\ntype SnapOwnsAccount = (account: InternalAccount) => boolean;\n\n/**\n * Data getters for elements.\n * This is used to get data from elements that is not directly accessible from the element itself.\n *\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @param getAccountByAddress - A function to get an account by its address.\n * @param getSelectedAccount - A function to get the selected account in the client.\n * @param listAccounts - A function to list accounts for the provided chain IDs.\n * @param snapOwnsAccount - A function to check if the snap owns the account.\n */\ntype ElementDataGetters = {\n getAssetsState: GetAssetsState;\n getAccountByAddress: GetAccountByAddress;\n getSelectedAccount: GetSelectedAccount;\n listAccounts: ListAccounts;\n snapOwnsAccount: SnapOwnsAccount;\n};\n\n/**\n * Get a JSX element from a component or JSX element. If the component is a\n * JSX element, it is returned as is. Otherwise, the component is converted to\n * a JSX element.\n *\n * @param component - The component to convert.\n * @returns The JSX element.\n */\nexport function getJsxInterface(component: ComponentOrElement): JSXElement {\n if (isJSXElementUnsafe(component)) {\n return component;\n }\n\n return getJsxElementFromComponent(component);\n}\n\n/**\n * Assert that the component name is unique in state.\n *\n * @param state - The interface state to verify against.\n * @param name - The component name to verify.\n */\nexport function assertNameIsUnique(state: InterfaceState, name: string) {\n assert(\n state[name] === undefined,\n `Duplicate component names are not allowed, found multiple instances of: \"${name}\".`,\n );\n}\n\n/**\n * Check if the chain ID matches the scope.\n * This function handles the case where a scope represents all EVM compatible chains.\n * In this case, it returns true if the chain ID is an EIP-155 chain ID.\n *\n * @param scope - The scope to check.\n * @param chainIds - The chain IDs to check against.\n * @returns Whether one of the chain ID matches the scope.\n */\nexport function isMatchingChainId(scope: CaipChainId, chainIds: CaipChainId[]) {\n // if the scope represents all EVM compatible chains, return true if the namespace is EIP-155.\n if (scope === 'eip155:0') {\n return chainIds.some((chainId) => {\n const { namespace } = parseCaipChainId(chainId);\n return namespace === KnownCaipNamespace.Eip155;\n });\n }\n\n // Otherwise, check if the scope is in the chain IDs.\n return chainIds.includes(scope);\n}\n\n/**\n * Format the state value for an account selector.\n *\n * @param account - The account to format.\n * @param requestedChainIds - The requested chain IDs.\n *\n * @returns The state value for the account selector.\n */\nexport function formatAccountSelectorStateValue(\n account: InternalAccount,\n requestedChainIds?: CaipChainId[],\n) {\n const { id, address, scopes } = account;\n\n const chainIds = createChainIdList(scopes, requestedChainIds);\n const addresses = createAccountList(address, chainIds);\n\n return { accountId: id, addresses };\n}\n\n/**\n * Get a default asset for a given address.\n *\n * @param addresses - The account addresses.\n * @param chainIds - The chain IDs to filter the assets.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAccountByAddress - A function to get an account by its address.\n * @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.\n *\n * @returns The default asset for the account or undefined if not found.\n */\nexport function getDefaultAsset(\n addresses: CaipAccountId[],\n chainIds: CaipChainId[] | undefined,\n { getAccountByAddress, getAssetsState }: ElementDataGetters,\n) {\n const { assetsMetadata, accountsAssets } = getAssetsState();\n\n const parsedAccounts = addresses.map((address) =>\n parseCaipAccountId(address),\n );\n\n const accountChainIds = parsedAccounts.map(({ chainId }) => chainId);\n\n const filteredChainIds =\n chainIds && chainIds.length > 0\n ? accountChainIds.filter((accountChainId) =>\n chainIds.includes(accountChainId),\n )\n : accountChainIds;\n\n const accountId = getAccountByAddress(addresses[0])?.id;\n\n // We should never fail on this assertion as the address is already validated.\n assert(accountId, `Account not found for address: ${addresses[0]}.`);\n\n const accountAssets = accountsAssets[accountId];\n\n // The AssetSelector component in the UI will be disabled if there is no asset available for the account\n // and networks provided. In this case, we return null to indicate that there is no default selected asset.\n if (accountAssets.length === 0) {\n return null;\n }\n\n const nativeAsset = accountAssets.find((asset) => {\n const { chainId, assetNamespace } = parseCaipAssetType(asset);\n\n return filteredChainIds.includes(chainId) && assetNamespace === 'slip44';\n });\n\n if (nativeAsset) {\n return {\n asset: nativeAsset,\n name: assetsMetadata[nativeAsset].name,\n symbol: assetsMetadata[nativeAsset].symbol,\n };\n }\n\n return {\n asset: accountAssets[0],\n name: assetsMetadata[accountAssets[0]].name,\n symbol: assetsMetadata[accountAssets[0]].symbol,\n };\n}\n\n/**\n * Get the default state value for an account selector.\n *\n * @param element - The account selector element.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getSelectedAccount - A function to get the selected account in the client.\n * @param elementDataGetters.listAccounts - A function to list accounts for the provided chain IDs.\n * @param elementDataGetters.snapOwnsAccount - A function to check if the snap owns the account.\n * @returns The default state for the account selector.\n */\nexport function getAccountSelectorDefaultStateValue(\n element: AccountSelectorElement,\n { getSelectedAccount, listAccounts, snapOwnsAccount }: ElementDataGetters,\n) {\n const { chainIds, hideExternalAccounts } = element.props;\n\n const selectedAccount = getSelectedAccount();\n\n // Use the selected account if it matches.\n // The following conditions are checked:\n // - If the selected account has any of the requested chain IDs in its scopes.\n // - If the selected account is owned by the snap and hideExternalAccounts is true.\n if (\n (!chainIds ||\n chainIds.length === 0 ||\n selectedAccount.scopes.some((scope) =>\n isMatchingChainId(scope, chainIds),\n )) &&\n (!hideExternalAccounts ||\n (hideExternalAccounts && snapOwnsAccount(selectedAccount)))\n ) {\n return formatAccountSelectorStateValue(selectedAccount, chainIds);\n }\n\n const accounts = listAccounts(chainIds);\n\n const filteredAccounts = hideExternalAccounts\n ? accounts.filter((account) => snapOwnsAccount(account))\n : accounts;\n\n // The AccountSelector component in the UI will be disabled if there is no account available for the networks provided.\n // In this case, we return null to indicate that there is no default selected account.\n if (filteredAccounts.length === 0) {\n return null;\n }\n\n return formatAccountSelectorStateValue(filteredAccounts[0], chainIds);\n}\n\n/**\n * Construct default state for a component.\n *\n * This function is meant to be used inside constructInputState to account\n * for component specific defaults and will not override the component value or existing form state.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n *\n * @returns The default state for the specific component, if any.\n */\nfunction constructComponentSpecificDefaultState(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement\n | AccountSelectorElement,\n elementDataGetters: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Dropdown': {\n const children = getJsxChildren(element) as OptionElement[];\n return children[0]?.props.value;\n }\n\n case 'RadioGroup': {\n const children = getJsxChildren(element) as RadioElement[];\n return children[0]?.props.value;\n }\n\n case 'Selector': {\n const children = getJsxChildren(element) as SelectorOptionElement[];\n return children[0]?.props.value;\n }\n\n case 'AccountSelector':\n return getAccountSelectorDefaultStateValue(element, elementDataGetters);\n\n case 'Checkbox':\n return false;\n\n case 'AssetSelector':\n return getDefaultAsset(\n element.props.addresses,\n element.props.chainIds,\n elementDataGetters,\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get the state value for an asset selector.\n *\n * @param value - The asset selector value.\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @returns The state value for the asset selector or null.\n */\nexport function getAssetSelectorStateValue(\n value: CaipAssetType | undefined,\n getAssetState: GetAssetsState,\n): AssetSelectorState | null {\n if (!value) {\n return null;\n }\n\n const { assetsMetadata } = getAssetState();\n const asset = assetsMetadata[value];\n\n if (!asset) {\n return null;\n }\n\n return {\n asset: value,\n name: asset.name ?? asset.symbol ?? 'Unknown',\n symbol: asset.symbol ?? 'Unknown',\n };\n}\n\n/**\n * Get the state value for an account selector.\n *\n * @param element - The account selector element.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAccountByAddress - A function to get an account by address.\n * @param elementDataGetters.snapOwnsAccount - A function to check if the snap owns the account.\n * @returns The state value for the account selector.\n */\nexport function getAccountSelectorStateValue(\n element: AccountSelectorElement,\n { getAccountByAddress, snapOwnsAccount }: ElementDataGetters,\n) {\n const { value, hideExternalAccounts } = element.props;\n\n if (!value) {\n return null;\n }\n\n const account = getAccountByAddress(value);\n\n if (!account) {\n return null;\n }\n\n if (hideExternalAccounts && !snapOwnsAccount(account)) {\n return null;\n }\n\n return formatAccountSelectorStateValue(account, element.props.chainIds);\n}\n\n/**\n * Get the state value for a stateful component.\n *\n * Most components store the state value as a `value` prop.\n * This function exists to account for components where that isn't the case.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @returns The state value for a given component.\n */\nfunction getComponentStateValue(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement\n | AccountSelectorElement,\n elementDataGetters: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Checkbox':\n return element.props.checked;\n\n case 'AssetSelector':\n return getAssetSelectorStateValue(\n element.props.value,\n elementDataGetters.getAssetsState,\n );\n\n case 'AddressInput': {\n if (!element.props.value) {\n return null;\n }\n\n // Construct CAIP-10 Id\n const { namespace, reference } = parseCaipChainId(element.props.chainId);\n return toCaipAccountId(namespace, reference, element.props.value);\n }\n\n case 'AccountSelector':\n return getAccountSelectorStateValue(element, elementDataGetters);\n\n default:\n return element.props.value;\n }\n}\n\n/**\n * Construct the state for an input field.\n *\n * @param oldState - The previous state.\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @param form - An optional form that the input is enclosed in.\n * @returns The input state.\n */\nfunction constructInputState(\n oldState: InterfaceState,\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | FileInputElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement\n | AccountSelectorElement,\n elementDataGetters: ElementDataGetters,\n form?: string,\n) {\n const oldStateUnwrapped = form ? (oldState[form] as FormState) : oldState;\n const oldInputState = oldStateUnwrapped?.[element.props.name] as State;\n\n if (element.type === 'FileInput') {\n return oldInputState ?? null;\n }\n\n return (\n getComponentStateValue(element, elementDataGetters) ??\n oldInputState ??\n constructComponentSpecificDefaultState(element, elementDataGetters) ??\n null\n );\n}\n\n/**\n * Construct the interface state for a given component tree.\n *\n * @param oldState - The previous state.\n * @param rootComponent - The UI component to construct state from.\n * @param elementDataGetters - Data getters for the elements.\n * @returns The interface state of the passed component.\n */\nexport function constructState(\n oldState: InterfaceState,\n rootComponent: JSXElement,\n elementDataGetters: ElementDataGetters,\n): InterfaceState {\n const newState: InterfaceState = {};\n\n // Stack containing the forms we have visited and at which depth\n const formStack: { name: string; depth: number }[] = [];\n\n walkJsx(rootComponent, (component, depth) => {\n let currentForm = formStack[formStack.length - 1];\n\n // Pop the current form of the stack once we leave its depth.\n if (currentForm && depth <= currentForm.depth) {\n formStack.pop();\n currentForm = formStack[formStack.length - 1];\n }\n\n if (component.type === 'Form') {\n assertNameIsUnique(newState, component.props.name);\n formStack.push({ name: component.props.name, depth });\n newState[component.props.name] = {};\n return;\n }\n\n // Stateful components inside a form\n if (currentForm && isStatefulComponent(component)) {\n const formState = newState[currentForm.name] as FormState;\n assertNameIsUnique(formState, component.props.name);\n formState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n currentForm.name,\n );\n return;\n }\n\n // Stateful components outside a form\n if (isStatefulComponent(component)) {\n assertNameIsUnique(newState, component.props.name);\n newState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n );\n }\n });\n\n return newState;\n}\n\nconst MAX_CONTEXT_SIZE = 5_000_000; // 5 mb\n\n/**\n * Validate a JSON blob to be used as the interface context.\n *\n * @param context - The JSON blob.\n * @throws If the JSON blob is too large.\n */\nexport function validateInterfaceContext(context?: InterfaceContext) {\n if (!context) {\n return;\n }\n\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(context);\n assert(\n size <= MAX_CONTEXT_SIZE,\n `A Snap interface context may not be larger than ${\n MAX_CONTEXT_SIZE / 1000000\n } MB.`,\n );\n}\n"]}
|