{"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"]}