{"version":3,"file":"MultichainNetworkController.cjs","sourceRoot":"","sources":["../src/MultichainNetworkController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { isCaipChainId } from '@metamask/utils';\n\nimport {\n  MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n  getDefaultMultichainNetworkControllerState,\n} from './constants';\nimport {\n  MULTICHAIN_NETWORK_CONTROLLER_NAME,\n  type MultichainNetworkControllerState,\n  type MultichainNetworkControllerMessenger,\n  type SupportedCaipChainId,\n} from './types';\nimport {\n  checkIfSupportedCaipChainId,\n  getChainIdForNonEvmAddress,\n} from './utils';\n\n/**\n * The MultichainNetworkController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainNetworkController extends BaseController<\n  typeof MULTICHAIN_NETWORK_CONTROLLER_NAME,\n  MultichainNetworkControllerState,\n  MultichainNetworkControllerMessenger\n> {\n  constructor({\n    messenger,\n    state,\n  }: {\n    messenger: MultichainNetworkControllerMessenger;\n    state?: Omit<\n      Partial<MultichainNetworkControllerState>,\n      'multichainNetworkConfigurationsByChainId'\n    >;\n  }) {\n    super({\n      messenger,\n      name: MULTICHAIN_NETWORK_CONTROLLER_NAME,\n      metadata: MULTICHAIN_NETWORK_CONTROLLER_METADATA,\n      state: {\n        ...getDefaultMultichainNetworkControllerState(),\n        ...state,\n      },\n    });\n\n    this.#subscribeToMessageEvents();\n    this.#registerMessageHandlers();\n  }\n\n  /**\n   * Sets the active EVM network.\n   *\n   * @param id - The client ID of the EVM network to set active.\n   */\n  async #setActiveEvmNetwork(id: NetworkClientId): Promise<void> {\n    // Notify listeners that setActiveNetwork was called\n    this.messagingSystem.publish(\n      'MultichainNetworkController:networkDidChange',\n      id,\n    );\n\n    // Indicate that the non-EVM network is not selected\n    this.update((state) => {\n      state.isEvmSelected = true;\n    });\n\n    // Prevent setting same network\n    const { selectedNetworkClientId } = this.messagingSystem.call(\n      'NetworkController:getState',\n    );\n\n    if (id === selectedNetworkClientId) {\n      // EVM network is already selected, no need to update NetworkController\n      return;\n    }\n\n    // Update evm active network\n    await this.messagingSystem.call('NetworkController:setActiveNetwork', id);\n  }\n\n  /**\n   * Sets the active non-EVM network.\n   *\n   * @param id - The chain ID of the non-EVM network to set active.\n   */\n  #setActiveNonEvmNetwork(id: SupportedCaipChainId): void {\n    if (id === this.state.selectedMultichainNetworkChainId) {\n      if (!this.state.isEvmSelected) {\n        // Same non-EVM network is already selected, no need to update\n        return;\n      }\n\n      // Indicate that the non-EVM network is selected\n      this.update((state) => {\n        state.isEvmSelected = false;\n      });\n\n      // Notify listeners that setActiveNetwork was called\n      this.messagingSystem.publish(\n        'MultichainNetworkController:networkDidChange',\n        id,\n      );\n    }\n\n    // Notify listeners that setActiveNetwork was called\n    this.messagingSystem.publish(\n      'MultichainNetworkController:networkDidChange',\n      id,\n    );\n\n    this.update((state) => {\n      state.selectedMultichainNetworkChainId = id;\n      state.isEvmSelected = false;\n    });\n  }\n\n  /**\n   * Sets the active network.\n   *\n   * @param id - The non-EVM Caip chain ID or EVM client ID of the network to set active.\n   * @returns - A promise that resolves when the network is set active.\n   */\n  async setActiveNetwork(\n    id: SupportedCaipChainId | NetworkClientId,\n  ): Promise<void> {\n    if (isCaipChainId(id)) {\n      const isSupportedCaipChainId = checkIfSupportedCaipChainId(id);\n      if (!isSupportedCaipChainId) {\n        throw new Error(`Unsupported Caip chain ID: ${String(id)}`);\n      }\n      return this.#setActiveNonEvmNetwork(id);\n    }\n\n    return await this.#setActiveEvmNetwork(id);\n  }\n\n  /**\n   * Handles switching between EVM and non-EVM networks when an account is changed\n   *\n   * @param account - The account that was changed\n   */\n  readonly #handleSelectedAccountChange = (account: InternalAccount) => {\n    const { type: accountType, address: accountAddress } = account;\n    const isEvmAccount = isEvmAccountType(accountType);\n\n    // Handle switching to EVM network\n    if (isEvmAccount) {\n      if (this.state.isEvmSelected) {\n        // No need to update if already on evm network\n        return;\n      }\n\n      // Make EVM network active\n      this.update((state) => {\n        state.isEvmSelected = true;\n      });\n      return;\n    }\n\n    // Handle switching to non-EVM network\n    const nonEvmChainId = getChainIdForNonEvmAddress(accountAddress);\n    const isSameNonEvmNetwork =\n      nonEvmChainId === this.state.selectedMultichainNetworkChainId;\n\n    if (isSameNonEvmNetwork) {\n      // No need to update if already on the same non-EVM network\n      this.update((state) => {\n        state.isEvmSelected = false;\n      });\n      return;\n    }\n\n    this.update((state) => {\n      state.selectedMultichainNetworkChainId = nonEvmChainId;\n      state.isEvmSelected = false;\n    });\n  };\n\n  /**\n   * Subscribes to message events.\n   */\n  #subscribeToMessageEvents() {\n    // Handle network switch when account is changed\n    this.messagingSystem.subscribe(\n      'AccountsController:selectedAccountChange',\n      this.#handleSelectedAccountChange,\n    );\n  }\n\n  /**\n   * Registers message handlers.\n   */\n  #registerMessageHandlers() {\n    this.messagingSystem.registerActionHandler(\n      'MultichainNetworkController:setActiveNetwork',\n      this.setActiveNetwork.bind(this),\n    );\n  }\n}\n"]}