@metamask/snaps-controllers 16.1.1 → 17.1.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 CHANGED
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [17.1.0]
11
+
12
+ ### Added
13
+
14
+ - Add support for `DateTimePicker` component ([#3698](https://github.com/MetaMask/snaps/pull/3698))
15
+
16
+ ### Changed
17
+
18
+ - Bump `@metamask/permission-controller` from `12.1.0` to `12.1.1` ([#3746](https://github.com/MetaMask/snaps/pull/3746))
19
+
20
+ ### Fixed
21
+
22
+ - Use `no-cache` for fetching registry ([#3760](https://github.com/MetaMask/snaps/pull/3760))
23
+
24
+ ## [17.0.0]
25
+
26
+ ### Added
27
+
28
+ - **BREAKING:** Ensure user has onboarded before allowing usage of SnapController ([#3731](https://github.com/MetaMask/snaps/pull/3731))
29
+ - This is breaking as it adds a new required constructor argument to `SnapController` called `ensureOnboardingComplete`.
30
+ - **BREAKING:** Support specified `clientVersions` in the registry ([#3737](https://github.com/MetaMask/snaps/pull/3737))
31
+ - This is breaking as it adds a new required constructor argument to `JsonSnapsRegistry` called `clientConfig`.
32
+
10
33
  ## [16.1.1]
11
34
 
12
35
  ### Fixed
@@ -960,7 +983,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
960
983
  - The version of the package no longer needs to match the version of all other
961
984
  MetaMask Snaps packages.
962
985
 
963
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.1.1...HEAD
986
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.1.0...HEAD
987
+ [17.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.0.0...@metamask/snaps-controllers@17.1.0
988
+ [17.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.1.1...@metamask/snaps-controllers@17.0.0
964
989
  [16.1.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.1.0...@metamask/snaps-controllers@16.1.1
965
990
  [16.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.0.0...@metamask/snaps-controllers@16.1.0
966
991
  [16.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@15.0.2...@metamask/snaps-controllers@16.0.0
@@ -18,6 +18,7 @@ const STATEFUL_COMPONENT_TYPES = [
18
18
  'AssetSelector',
19
19
  'AddressInput',
20
20
  'AccountSelector',
21
+ 'DateTimePicker',
21
22
  ];
22
23
  /**
23
24
  * Check if a component is a stateful component.
@@ -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 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"]}
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 DateTimePickerElement,\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 'DateTimePicker',\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 | DateTimePickerElement,\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 | DateTimePickerElement,\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 | DateTimePickerElement,\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"]}
@@ -5,7 +5,7 @@ import { type CaipAssetType, type CaipAccountId } from "@metamask/utils";
5
5
  /**
6
6
  * A list of stateful component types.
7
7
  */
8
- declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput", "AccountSelector"];
8
+ declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput", "AccountSelector", "DateTimePicker"];
9
9
  /**
10
10
  * Type for stateful component types.
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { type CaipAssetType, type CaipAccountId } from "@metamask/utils";
5
5
  /**
6
6
  * A list of stateful component types.
7
7
  */
8
- declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput", "AccountSelector"];
8
+ declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput", "AccountSelector", "DateTimePicker"];
9
9
  /**
10
10
  * Type for stateful component types.
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ const STATEFUL_COMPONENT_TYPES = [
15
15
  'AssetSelector',
16
16
  'AddressInput',
17
17
  'AccountSelector',
18
+ 'DateTimePicker',
18
19
  ];
19
20
  /**
20
21
  * Check if a component is a stateful component.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","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"]}
1
+ {"version":3,"file":"utils.mjs","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 DateTimePickerElement,\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 'DateTimePicker',\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 | DateTimePickerElement,\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 | DateTimePickerElement,\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 | DateTimePickerElement,\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"]}
@@ -83,7 +83,8 @@ class SnapController extends base_controller_1.BaseController {
83
83
  #preinstalledSnaps;
84
84
  #trackEvent;
85
85
  #trackSnapExport;
86
- constructor({ closeAllConnections, messenger, state, dynamicPermissions = ['endowment:caip25', 'wallet_snap'], environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), maxIdleTime = (0, utils_1.inMilliseconds)(30, utils_1.Duration.Second), maxRequestTime = (0, utils_1.inMilliseconds)(60, utils_1.Duration.Second), fetchFunction = globalThis.fetch.bind(undefined), featureFlags = {}, detectSnapLocation: detectSnapLocationFunction = location_1.detectSnapLocation, preinstalledSnaps = null, encryptor, getMnemonicSeed, getFeatureFlags = () => ({}), clientCryptography, trackEvent, }) {
86
+ #ensureOnboardingComplete;
87
+ constructor({ closeAllConnections, messenger, state, dynamicPermissions = ['endowment:caip25', 'wallet_snap'], environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), maxIdleTime = (0, utils_1.inMilliseconds)(30, utils_1.Duration.Second), maxRequestTime = (0, utils_1.inMilliseconds)(60, utils_1.Duration.Second), fetchFunction = globalThis.fetch.bind(undefined), featureFlags = {}, detectSnapLocation: detectSnapLocationFunction = location_1.detectSnapLocation, preinstalledSnaps = null, encryptor, getMnemonicSeed, getFeatureFlags = () => ({}), clientCryptography, trackEvent, ensureOnboardingComplete, }) {
87
88
  super({
88
89
  messenger,
89
90
  metadata: {
@@ -160,6 +161,7 @@ class SnapController extends base_controller_1.BaseController {
160
161
  this.#rollbackSnapshots = new Map();
161
162
  this.#snapsRuntimeData = new Map();
162
163
  this.#trackEvent = trackEvent;
164
+ this.#ensureOnboardingComplete = ensureOnboardingComplete;
163
165
  this.#pollForLastRequestStatus();
164
166
  /* eslint-disable @typescript-eslint/unbound-method */
165
167
  this.messenger.subscribe('ExecutionService:unhandledError', this._onUnhandledSnapError);
@@ -383,7 +385,7 @@ class SnapController extends base_controller_1.BaseController {
383
385
  * Also updates any preinstalled Snaps to the latest allowlisted version.
384
386
  */
385
387
  async updateRegistry() {
386
- this.#assertCanUsePlatform();
388
+ await this.#assertCanUsePlatform();
387
389
  await this.messenger.call('SnapsRegistry:update');
388
390
  const blockedSnaps = await this.messenger.call('SnapsRegistry:get', Object.values(this.state.snaps).reduce((blockListArg, snap) => {
389
391
  blockListArg[snap.id] = {
@@ -489,9 +491,11 @@ class SnapController extends base_controller_1.BaseController {
489
491
  (0, utils_1.assert)(this.#featureFlags.disableSnapInstallation !== true, 'Installing Snaps is currently disabled in this version of MetaMask.');
490
492
  }
491
493
  /**
492
- * Asserts whether the Snaps platform is allowed to run.
494
+ * Waits for onboarding and then asserts whether the Snaps platform is allowed to run.
493
495
  */
494
- #assertCanUsePlatform() {
496
+ async #assertCanUsePlatform() {
497
+ // Ensure the user has onboarded before allowing access to Snaps.
498
+ await this.#ensureOnboardingComplete();
495
499
  const flags = this.#getFeatureFlags();
496
500
  (0, utils_1.assert)(flags.disableSnaps !== true, 'The Snaps platform requires basic functionality to be used. Enable basic functionality in the settings to use the Snaps platform.');
497
501
  }
@@ -558,7 +562,7 @@ class SnapController extends base_controller_1.BaseController {
558
562
  * @param snapId - The id of the Snap to start.
559
563
  */
560
564
  async startSnap(snapId) {
561
- this.#assertCanUsePlatform();
565
+ await this.#assertCanUsePlatform();
562
566
  const snap = this.state.snaps[snapId];
563
567
  if (!snap.enabled) {
564
568
  throw new Error(`Snap "${snapId}" is disabled.`);
@@ -1226,7 +1230,7 @@ class SnapController extends base_controller_1.BaseController {
1226
1230
  * snap couldn't be installed.
1227
1231
  */
1228
1232
  async installSnaps(origin, requestedSnaps) {
1229
- this.#assertCanUsePlatform();
1233
+ await this.#assertCanUsePlatform();
1230
1234
  const result = {};
1231
1235
  const snapIds = Object.keys(requestedSnaps);
1232
1236
  const pendingUpdates = [];
@@ -1411,7 +1415,7 @@ class SnapController extends base_controller_1.BaseController {
1411
1415
  if (!automaticUpdate) {
1412
1416
  this.#assertCanInstallSnaps();
1413
1417
  }
1414
- this.#assertCanUsePlatform();
1418
+ await this.#assertCanUsePlatform();
1415
1419
  const snap = this.getExpect(snapId);
1416
1420
  const { preinstalled, removable, hidden, hideSnapBranding } = snap;
1417
1421
  if (preinstalled && !automaticUpdate) {
@@ -1834,7 +1838,7 @@ class SnapController extends base_controller_1.BaseController {
1834
1838
  * @returns The result of the JSON-RPC request.
1835
1839
  */
1836
1840
  async handleRequest({ snapId, origin, handler: handlerType, request: rawRequest, }) {
1837
- this.#assertCanUsePlatform();
1841
+ await this.#assertCanUsePlatform();
1838
1842
  const snap = this.get(snapId);
1839
1843
  (0, utils_1.assert)(snap, `The Snap "${snapId}" is not installed. Please install it before invoking it.`);
1840
1844
  (0, utils_1.assert)(origin === constants_1.METAMASK_ORIGIN || (0, snaps_utils_1.isValidUrl)(origin), "'origin' must be a valid URL or 'metamask'.");