@openzeppelin/ui-builder-adapter-evm 1.4.2 → 1.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../adapter-evm-core/src/types/artifacts.ts","../../adapter-evm-core/src/utils/artifacts.ts","../../adapter-evm-core/src/utils/json.ts","../../adapter-evm-core/src/utils/formatting.ts","../../adapter-evm-core/src/utils/validation.ts","../../adapter-evm-core/src/utils/gas.ts","../../adapter-evm-core/src/utils/index.ts","../../adapter-evm-core/src/validation/eoa.ts","../../adapter-evm-core/src/transaction/eoa.ts","../../adapter-evm-core/src/transaction/relayer.ts","../../adapter-evm-core/src/abi/transformer.ts","../../adapter-evm-core/src/abi/etherscan.ts","../../adapter-evm-core/src/configuration/explorer.ts","../../adapter-evm-core/src/abi/etherscan-v2.ts","../../adapter-evm-core/src/abi/sourcify.ts","../../adapter-evm-core/src/abi/loader.ts","../../adapter-evm-core/src/proxy/detection.ts","../../adapter-evm-core/src/configuration/rpc.ts","../../adapter-evm-core/src/types/providers.ts","../../adapter-evm-core/src/abi/types.ts","../../adapter-evm-core/src/abi/comparison.ts","../../adapter-evm-core/src/mapping/constants.ts","../../adapter-evm-core/src/mapping/type-mapper.ts","../../adapter-evm-core/src/mapping/field-generator.ts","../../adapter-evm-core/src/transform/input-parser.ts","../../adapter-evm-core/src/transform/output-formatter.ts","../../adapter-evm-core/src/query/handler.ts","../../adapter-evm-core/src/query/view-checker.ts","../../adapter-evm-core/src/transaction/formatter.ts","../../adapter-evm-core/src/transaction/index.ts","../../adapter-evm-core/src/transaction/sender.ts","../../adapter-evm-core/src/wallet/context/wagmi-context.tsx","../../adapter-evm-core/src/wallet/hooks/useIsWagmiProviderInitialized.ts","../../adapter-evm-core/src/wallet/components/SafeWagmiComponent.tsx","../../adapter-evm-core/src/wallet/components/connect/ConnectButton.tsx","../../adapter-evm-core/src/wallet/components/connect/ConnectorDialog.tsx","../../adapter-evm-core/src/wallet/components/account/AccountDisplay.tsx","../../adapter-evm-core/src/wallet/components/network/NetworkSwitcher.tsx","../../adapter-evm-core/src/wallet/connection.ts","../../adapter-evm-core/src/wallet/wagmi-implementation.ts","../../adapter-evm-core/src/types/index.ts","../../adapter-evm-core/src/configuration/network-services.ts","../../adapter-evm-core/src/wallet/rainbowkit/config-generator.ts","../../adapter-evm-core/src/wallet/rainbowkit/types.ts","../../adapter-evm-core/src/wallet/rainbowkit/utils.ts","../../adapter-evm-core/src/wallet/rainbowkit/components.tsx","../../adapter-evm-core/src/wallet/rainbowkit/componentFactory.ts","../../adapter-evm-core/src/wallet/rainbowkit/config-service.ts","../../adapter-evm-core/src/wallet/uiKitManager.ts","../../adapter-evm-core/src/wallet/rainbowkitAssetManager.ts","../../adapter-evm-core/src/wallet/configResolution.ts","../../adapter-evm-core/src/wallet/utils/filterWalletComponents.ts","../../adapter-evm-core/src/validation/index.ts","../../adapter-evm-core/src/validation/relayer.ts","../../adapter-evm-core/src/validation/execution.ts","../../adapter-evm-core/src/index.ts","../src/adapter.ts","../src/wallet/components/EvmWalletUiRoot.tsx","../src/wallet/utils/walletImplementationManager.ts","../src/networks/mainnet.ts","../src/networks/testnet.ts","../src/networks/index.ts","../src/wallet/implementation/wagmi-implementation.ts","../src/wallet/evmUiKitManager.ts","../src/wallet/hooks/facade-hooks.ts","../src/wallet/hooks/useUiKitConfig.ts","../src/configuration/execution.ts","../src/configuration/network-services.ts","../src/query/adapter-query.ts","../src/transaction/components/EvmRelayerOptions.tsx","../src/transaction/components/AdvancedInfo.tsx","../src/transaction/components/CustomGasParameters.tsx","../src/transaction/components/SpeedSelection.tsx","../src/transaction/components/useEvmRelayerOptions.ts","../src/wallet/utils/connection.ts","../src/wallet/utils/uiKitService.ts","../src/wallet/rainbowkit/components.tsx","../src/wallet/rainbowkit/componentFactory.ts","../src/wallet/utils/wallet-status.ts","../src/wallet/utils.ts","../src/config.ts"],"sourcesContent":["// Re-export the main adapter class\nexport { EvmAdapter } from './adapter';\n\n// Export RainbowKit customization types (re-exported from core via rainbowkit/index.ts)\nexport type {\n AppInfo,\n RainbowKitConnectButtonProps,\n RainbowKitProviderProps,\n RainbowKitKitConfig,\n RainbowKitCustomizations,\n} from './wallet/rainbowkit';\nexport { isRainbowKitCustomizations, extractRainbowKitCustomizations } from './wallet/rainbowkit';\n\n// Export EVM networks\nexport {\n evmNetworks,\n evmMainnetNetworks,\n evmTestnetNetworks,\n // Individual networks\n ethereumMainnet,\n arbitrumMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n baseMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n ethereumSepolia,\n arbitrumSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n baseSepolia,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n // ... other individual network exports\n} from './networks';\n\n// Export adapter configuration\nexport { evmAdapterConfig } from './config';\n\n// Re-export core types for public API compatibility\nexport type {\n TypedEvmNetworkConfig,\n WriteContractParameters,\n EvmContractArtifacts,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nexport {\n isEvmContractArtifacts,\n abiComparisonService,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\n// Export adapter-specific types\nexport type { EvmRelayerTransactionOptions } from '@openzeppelin/ui-builder-adapter-evm-core';\n","/**\n * EVM-specific contract artifacts interface\n * Defines the structure of data needed to load EVM contracts\n */\nimport type { EvmContractDefinitionProviderKey } from './providers';\n\nexport interface EvmContractArtifacts {\n /** The deployed contract address (required) */\n contractAddress: string;\n\n /** Optional manual ABI JSON string (for unverified contracts) */\n contractDefinition?: string;\n\n /** Optional proxy detection configuration */\n __proxyDetectionOptions?: {\n /** Skip automatic proxy detection */\n skipProxyDetection?: boolean;\n };\n\n /** Optional forced provider for this load attempt (session-scoped override) */\n __forcedProvider?: EvmContractDefinitionProviderKey;\n}\n\n/**\n * Type guard to check if an object matches EvmContractArtifacts structure\n */\nexport function isEvmContractArtifacts(obj: unknown): obj is EvmContractArtifacts {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n typeof (obj as Record<string, unknown>).contractAddress === 'string'\n );\n}\n","/**\n * Utility functions for EVM contract artifacts validation and conversion\n */\nimport type { EvmContractArtifacts } from '../types/artifacts';\nimport { isEvmContractArtifacts } from '../types/artifacts';\n\n/**\n * Validates and converts generic source input to EvmContractArtifacts\n *\n * @param source - Generic contract source (string address or artifacts object)\n * @returns Validated EvmContractArtifacts\n * @throws Error if the source is invalid\n */\nexport function validateAndConvertEvmArtifacts(\n source: string | Record<string, unknown>\n): EvmContractArtifacts {\n if (typeof source === 'string') {\n // If source is a string, assume it's a contract address\n return { contractAddress: source };\n }\n\n // Validate that the object has the required structure\n if (!isEvmContractArtifacts(source)) {\n throw new Error(\n 'Invalid contract artifacts provided. Expected an object with contractAddress property.'\n );\n }\n\n return source;\n}\n","/**\n * Custom JSON stringifier that handles BigInt values by converting them to strings.\n * @param value The value to stringify.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON text for readability.\n * @returns A JSON string representing the given value.\n */\nexport function stringifyWithBigInt(value: unknown, space?: number | string): string {\n const replacer = (_key: string, val: unknown) => {\n // Check if the value is a BigInt\n if (typeof val === 'bigint') {\n // Convert BigInt to string\n return val.toString();\n }\n // Return the value unchanged for other types\n return val;\n };\n\n return JSON.stringify(value, replacer, space);\n}\n","/**\n * Format a method name for display (e.g., from camelCase to Title Case).\n */\nexport function formatMethodName(name: string): string {\n if (!name) return '';\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n\n/**\n * Format an input name for display (e.g., from camelCase or snake_case to Title Case).\n * Provides a default name based on type if the original name is empty.\n */\nexport function formatInputName(name: string, type: string): string {\n if (!name || name === '') {\n return `Parameter (${type})`; // Use type if name is missing\n }\n return name\n .replace(/([A-Z])/g, ' $1') // Add space before capitals\n .replace(/_/g, ' ') // Replace underscores with spaces\n .replace(/^./, (str) => str.toUpperCase()) // Capitalize first letter\n .trim();\n}\n","import { isAddress } from 'viem';\n\n/**\n * Validates if a string is a valid EVM address.\n * @param address The address string to validate.\n * @returns True if the address is valid, false otherwise.\n */\nexport function isValidEvmAddress(address: string): boolean {\n return isAddress(address);\n}\n","import { formatGwei, parseGwei } from 'viem';\n\n/**\n * Convert wei values to gwei for display using viem\n */\nexport const weiToGwei = (wei?: number): number | undefined => {\n if (!wei) return undefined;\n return parseFloat(formatGwei(BigInt(wei)));\n};\n\n/**\n * Convert gwei values to wei using viem\n */\nexport const gweiToWei = (gwei?: number): number | undefined => {\n if (!gwei) return undefined;\n return Number(parseGwei(gwei.toString()));\n};\n","/**\n * Utils Module\n *\n * Utility functions for EVM operations including JSON handling,\n * formatting, gas calculations, validation, and artifacts processing.\n *\n * @module utils\n */\n\n// Barrel file for utils module\nexport * from './artifacts';\nexport * from './json';\nexport * from './formatting';\nexport * from './validation';\nexport * from './gas';\n","import type { EoaExecutionConfig } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { isValidEvmAddress } from '../utils/validation';\n\nconst SYSTEM_LOG_TAG = 'EoaValidator';\n\n/**\n * Wallet connection status for EOA validation\n */\nexport interface EvmWalletStatus {\n isConnected: boolean;\n address?: string;\n}\n\n/**\n * Validates an EOA execution configuration.\n *\n * @param config The EOA execution config to validate\n * @param walletStatus Optional wallet connection status for address validation\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateEoaConfig(\n config: EoaExecutionConfig,\n walletStatus?: EvmWalletStatus\n): Promise<true | string> {\n if (!config.allowAny) {\n if (!config.specificAddress) {\n return \"EOA execution selected, but no specific address was provided when 'allowAny' is false.\";\n }\n if (!isValidEvmAddress(config.specificAddress)) {\n return `Invalid specific EOA address format: ${config.specificAddress}`;\n }\n if (walletStatus?.isConnected && walletStatus.address) {\n if (walletStatus.address.toLowerCase() !== config.specificAddress.toLowerCase()) {\n return `Connected wallet address (${walletStatus.address}) does not match the required specific EOA address (${config.specificAddress}). Please connect the correct wallet.`;\n }\n } else if (walletStatus?.isConnected && !walletStatus.address) {\n logger.warn(\n SYSTEM_LOG_TAG,\n 'Wallet is connected but address is unavailable for EOA validation.'\n );\n return 'Connected wallet address is not available for validation against specific EOA.';\n }\n }\n return true;\n}\n\n/**\n * Simple validation of EOA config without wallet status check.\n * Useful for static validation before execution.\n */\nexport function validateEvmEoaConfig(config: EoaExecutionConfig): boolean {\n if (!config.allowAny) {\n if (!config.specificAddress) {\n return false;\n }\n if (!isValidEvmAddress(config.specificAddress)) {\n return false;\n }\n }\n return true;\n}\n","/**\n * EOA Execution Strategy\n *\n * Implements transaction execution for Externally Owned Accounts (EOA).\n * This strategy signs and broadcasts transactions directly from the user's\n * connected wallet, which is the most common way of interacting with a blockchain.\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\nimport type { WalletClient } from 'viem';\n\nimport type {\n EoaExecutionConfig,\n ExecutionConfig,\n TransactionStatusUpdate,\n TxStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WriteContractParameters } from '../types/abi';\nimport { validateEoaConfig } from '../validation/eoa';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\nconst SYSTEM_LOG_TAG = 'EoaExecutionStrategy';\n\n/**\n * Implements the ExecutionStrategy for a standard Externally Owned Account (EOA).\n * This strategy involves signing and broadcasting a transaction directly from the user's\n * connected wallet, which is the most common way of interacting with a blockchain.\n */\nexport class EoaExecutionStrategy implements AdapterExecutionStrategy {\n public async execute(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n // runtimeApiKey is unused in EOA strategy but required by the interface\n _runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const { walletClient, accountStatus } =\n await this.getAuthenticatedWalletClient(walletImplementation);\n\n // Final validation at the point of execution\n const eoaConfig = executionConfig as EoaExecutionConfig;\n const validationResult = await validateEoaConfig(eoaConfig, {\n isConnected: accountStatus.isConnected,\n address: accountStatus.address,\n });\n if (validationResult !== true) {\n throw new Error(validationResult);\n }\n\n logger.info(SYSTEM_LOG_TAG, 'Using EOA execution strategy.');\n try {\n logger.debug(SYSTEM_LOG_TAG, 'Calling walletClient.writeContract with:', {\n account: accountStatus.address,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n\n onStatusChange('pendingSignature', {});\n\n const hash = await walletClient.writeContract({\n account: accountStatus.address!,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n\n logger.info(SYSTEM_LOG_TAG, 'EOA Transaction initiated. Hash:', hash);\n return { txHash: hash };\n } catch (error: unknown) {\n logger.error(SYSTEM_LOG_TAG, 'Error during EOA writeContract call:', error);\n const errorMessage = error instanceof Error ? error.message : 'Unknown EOA transaction error';\n throw new Error(`Transaction failed (EOA): ${errorMessage}`);\n }\n }\n\n private async getAuthenticatedWalletClient(\n walletImplementation: EvmWalletImplementation\n ): Promise<{\n walletClient: WalletClient;\n accountStatus: GetAccountReturnType;\n }> {\n const walletClient = await walletImplementation.getWalletClient();\n if (!walletClient) {\n logger.error(SYSTEM_LOG_TAG, 'Wallet client not available. Is wallet connected?');\n throw new Error('Wallet is not connected or client is unavailable.');\n }\n\n const accountStatus = walletImplementation.getWalletConnectionStatus();\n if (!accountStatus.isConnected || !accountStatus.address) {\n logger.error(SYSTEM_LOG_TAG, 'Account not available. Is wallet connected?');\n throw new Error('Wallet is not connected or account address is unavailable.');\n }\n return { walletClient, accountStatus };\n }\n}\n","/**\n * Relayer Execution Strategy\n *\n * Implements transaction execution through the OpenZeppelin Relayer service.\n * This strategy sends transactions to a relayer for gas sponsorship and broadcasting.\n */\n\nimport { encodeFunctionData, formatEther } from 'viem';\n\nimport {\n Configuration,\n RelayersApi,\n Speed,\n type ApiResponseRelayerResponseData,\n type EvmTransactionRequest,\n type EvmTransactionResponse,\n} from '@openzeppelin/relayer-sdk';\nimport type {\n ExecutionConfig,\n RelayerDetails,\n RelayerDetailsRich,\n RelayerExecutionConfig,\n TransactionStatusUpdate,\n TxStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { EvmCompatibleNetworkConfig } from '../types';\nimport type { WriteContractParameters } from '../types/abi';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\n/**\n * EVM-specific transaction options for the OpenZeppelin Relayer.\n * These options map directly to the EvmTransactionRequest parameters in the SDK.\n */\nexport interface EvmRelayerTransactionOptions {\n // Basic options that most users will want to configure\n speed?: Speed;\n gasLimit?: number;\n\n // Advanced options for fine-grained control\n gasPrice?: number;\n maxFeePerGas?: number;\n maxPriorityFeePerGas?: number;\n\n // Transaction expiration\n validUntil?: string; // ISO 8601 date string\n}\n\n/**\n * Implements the ExecutionStrategy for the OpenZeppelin Relayer.\n * This strategy sends the transaction to the relayer service, which then handles\n * gas payment, signing, and broadcasting. It includes a polling mechanism to wait\n * for the transaction to be mined and return the final hash.\n */\nexport class RelayerExecutionStrategy implements AdapterExecutionStrategy {\n public async execute(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n _walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const relayerConfig = executionConfig as RelayerExecutionConfig;\n\n if (!runtimeApiKey) {\n throw new Error('API Key is required for Relayer execution.');\n }\n\n const { transactionId } = await this.sendTransactionViaRelayer(\n transactionData,\n relayerConfig,\n runtimeApiKey\n );\n\n onStatusChange('pendingRelayer', { transactionId });\n\n const sdkConfig = new Configuration({\n basePath: relayerConfig.serviceUrl,\n accessToken: runtimeApiKey,\n });\n\n const txHash = await this.pollForTransactionHash(\n relayerConfig.relayer.relayerId,\n transactionId,\n sdkConfig\n );\n\n return { txHash };\n }\n\n /**\n * Fetches and filters relayers for a specific EVM network from the OpenZeppelin Relayer service.\n * This function handles pagination to retrieve all available relayers.\n *\n * @param serviceUrl - The base URL of the relayer service.\n * @param accessToken - The session-based API key for authentication.\n * @param networkConfig - EVM-compatible network configuration to filter relayers by (works with any ecosystem).\n * @returns A promise that resolves to an array of compatible relayer details.\n * @throws If the API call fails or returns an unsuccessful response.\n */\n public async getEvmRelayers(\n serviceUrl: string,\n accessToken: string,\n networkConfig: EvmCompatibleNetworkConfig\n ): Promise<RelayerDetails[]> {\n logger.info(\n '[Relayer] Getting relayers with access token',\n accessToken.slice(0, 5).padEnd(accessToken.length, '*')\n );\n const sdkConfig = new Configuration({\n basePath: serviceUrl,\n accessToken,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n let allRelayers: ApiResponseRelayerResponseData[] = [];\n let currentPage = 1;\n let totalItems = 0;\n let hasMore = true;\n\n do {\n const { data } = await relayersApi.listRelayers(currentPage, 100);\n\n if (!data.success || !data.data) {\n throw new Error(`Failed to fetch relayers on page ${currentPage}.`);\n }\n\n allRelayers = [...allRelayers, ...data.data];\n totalItems = data.pagination?.total_items || 0;\n\n if (allRelayers.length >= totalItems) {\n hasMore = false;\n } else {\n currentPage++;\n }\n } while (hasMore);\n\n return allRelayers\n .filter(\n (r: ApiResponseRelayerResponseData) =>\n r.network_type === 'evm' && networkConfig.id.includes(r.network)\n )\n .map((r: ApiResponseRelayerResponseData) => ({\n relayerId: r.id,\n name: r.name,\n address: r.address || '',\n network: r.network,\n paused: r.paused || false,\n }));\n }\n\n /**\n * Fetches comprehensive information about a specific relayer including balance and status.\n * This function combines multiple SDK API calls to provide rich relayer details.\n *\n * @param serviceUrl - The base URL of the relayer service.\n * @param accessToken - The session-based API key for authentication.\n * @param relayerId - The unique identifier of the relayer.\n * @param networkConfig - EVM-compatible network configuration to get the native currency symbol (works with any ecosystem).\n * @returns A promise that resolves to enhanced relayer details including balance and status.\n * @throws If any API call fails or returns an unsuccessful response.\n */\n public async getEvmRelayer(\n serviceUrl: string,\n accessToken: string,\n relayerId: string,\n networkConfig: EvmCompatibleNetworkConfig\n ): Promise<RelayerDetailsRich> {\n logger.info('[Relayer] Getting detailed relayer info', relayerId);\n\n const sdkConfig = new Configuration({\n basePath: serviceUrl,\n accessToken,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n try {\n // Fetch basic relayer details, balance, and status in parallel\n const [relayerResponse, balanceResponse, statusResponse] = await Promise.all([\n relayersApi.getRelayer(relayerId),\n relayersApi.getRelayerBalance(relayerId).catch((err) => {\n logger.warn('[Relayer] Failed to fetch balance', err);\n return null;\n }),\n relayersApi.getRelayerStatus(relayerId).catch((err) => {\n logger.warn('[Relayer] Failed to fetch status', err);\n return null;\n }),\n ]);\n\n if (!relayerResponse.data.success || !relayerResponse.data.data) {\n throw new Error(`Failed to fetch relayer details for ID: ${relayerId}`);\n }\n\n const relayerData = relayerResponse.data.data;\n\n // Build enhanced relayer details object\n const enhancedDetails: RelayerDetailsRich = {\n relayerId: relayerData.id,\n name: relayerData.name,\n address: relayerData.address || '',\n network: relayerData.network,\n paused: relayerData.paused || false,\n systemDisabled: relayerData.system_disabled || false,\n };\n\n // Add balance if available\n if (balanceResponse?.data?.success && balanceResponse.data.data?.balance) {\n try {\n // Format balance from wei to native currency\n const balanceInWei = BigInt(balanceResponse.data.data.balance);\n const balanceInEth = formatEther(balanceInWei);\n const currencySymbol = networkConfig.nativeCurrency.symbol;\n enhancedDetails.balance = `${balanceInEth} ${currencySymbol}`;\n } catch (error) {\n logger.warn('[Relayer] Failed to format balance, using raw value', String(error));\n enhancedDetails.balance = String(balanceResponse.data.data.balance);\n }\n }\n\n // Add status details if available\n if (statusResponse?.data?.success && statusResponse.data.data) {\n const statusData = statusResponse.data.data;\n if (statusData.network_type === 'evm') {\n if (statusData.nonce !== undefined && statusData.nonce !== null) {\n enhancedDetails.nonce = String(statusData.nonce);\n }\n if (statusData.pending_transactions_count !== undefined) {\n enhancedDetails.pendingTransactionsCount = statusData.pending_transactions_count;\n }\n if (statusData.last_confirmed_transaction_timestamp) {\n enhancedDetails.lastConfirmedTransactionTimestamp =\n statusData.last_confirmed_transaction_timestamp;\n }\n }\n }\n\n logger.info('[Relayer] Retrieved enhanced relayer details', JSON.stringify(enhancedDetails));\n return enhancedDetails;\n } catch (error) {\n logger.error(\n '[Relayer] Failed to get relayer details',\n error instanceof Error ? error.message : String(error)\n );\n throw error;\n }\n }\n\n /**\n * Submits a transaction to the relayer service for asynchronous processing.\n * @param transactionData The contract write parameters.\n * @param executionConfig The relayer-specific execution configuration.\n * @param runtimeApiKey The user's session-only API key.\n * @returns A promise that resolves to an object containing the transaction ID assigned by the relayer.\n */\n private async sendTransactionViaRelayer(\n transactionData: WriteContractParameters,\n executionConfig: RelayerExecutionConfig,\n runtimeApiKey: string\n ): Promise<{ transactionId: string }> {\n const data = encodeFunctionData({\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n });\n\n // Type-safe extraction of EVM-specific options\n const evmOptions = executionConfig.transactionOptions as\n | EvmRelayerTransactionOptions\n | undefined;\n\n // Compute value for relayer request. The SDK type is number, but JS Number\n // cannot safely represent large wei amounts. Prefer passing zero when undefined\n // or warn when truncation would occur.\n const valueBigint = transactionData.value ?? 0n;\n let valueNumber: number = 0;\n const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\n if (valueBigint > MAX_SAFE) {\n logger.warn(\n '[Relayer] Value exceeds JS safe integer. Truncating for request.',\n valueBigint.toString()\n );\n valueNumber = Number(MAX_SAFE);\n } else {\n valueNumber = Number(valueBigint);\n }\n\n const relayerTxRequest: EvmTransactionRequest = {\n to: transactionData.address,\n data,\n value: valueNumber,\n // If no explicit gas limit is provided, keep a conservative default but warn.\n gas_limit: (() => {\n if (typeof evmOptions?.gasLimit === 'number') return evmOptions.gasLimit;\n logger.warn(\n '[Relayer]',\n 'No gasLimit provided; using default 210000. Consider setting explicitly.'\n );\n return 210000;\n })(),\n // Note: The OpenZeppelin Relayer API requires exactly one gas pricing strategy to be provided.\n // Valid options are: speed, gas_price, or both max_fee_per_gas + max_priority_fee_per_gas.\n // If none are provided, the API will return a 400 Bad Request error.\n // Only include speed if explicitly set in options\n ...(evmOptions?.speed !== undefined && { speed: evmOptions.speed }),\n // Include optional parameters only if provided\n ...(evmOptions?.gasPrice !== undefined && { gas_price: evmOptions.gasPrice }),\n ...(evmOptions?.maxFeePerGas !== undefined && { max_fee_per_gas: evmOptions.maxFeePerGas }),\n ...(evmOptions?.maxPriorityFeePerGas !== undefined && {\n max_priority_fee_per_gas: evmOptions.maxPriorityFeePerGas,\n }),\n ...(evmOptions?.validUntil !== undefined && { valid_until: evmOptions.validUntil }),\n };\n\n const sdkConfig = new Configuration({\n basePath: executionConfig.serviceUrl,\n accessToken: runtimeApiKey,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n const result = await relayersApi.sendTransaction(\n executionConfig.relayer.relayerId,\n relayerTxRequest\n );\n\n if (!result.data.success || !result.data.data?.id) {\n throw new Error(`Relayer API failed to return a transaction ID. Error: ${result.data.error}`);\n }\n\n return { transactionId: result.data.data.id };\n }\n\n /**\n * Polls the relayer for a transaction's status until it is mined and has a hash, or fails.\n * @param relayerId The ID of the relayer processing the transaction.\n * @param transactionId The ID of the transaction to poll.\n * @param sdkConfig The SDK configuration containing the necessary authentication.\n * @returns A promise that resolves to the final transaction hash.\n * @throws If the transaction fails or polling times out.\n */\n private async pollForTransactionHash(\n relayerId: string,\n transactionId: string,\n sdkConfig: Configuration\n ): Promise<string> {\n const relayersApi = new RelayersApi(sdkConfig);\n const POLLING_INTERVAL = 2000;\n const POLLING_TIMEOUT = 300000; // 5 minutes in milliseconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < POLLING_TIMEOUT) {\n const { data } = await relayersApi.getTransactionById(relayerId, transactionId);\n\n if (!data.success || !data.data) {\n throw new Error(`Failed to get transaction status for ID: ${transactionId}`);\n }\n\n const txResponse = data.data as EvmTransactionResponse;\n\n if (txResponse.status === 'mined' || txResponse.status === 'confirmed') {\n if (!txResponse.hash) {\n throw new Error(\n `Transaction is confirmed but no hash was returned for ID: ${transactionId}`\n );\n }\n return txResponse.hash;\n }\n\n if (\n txResponse.status === 'failed' ||\n txResponse.status === 'canceled' ||\n txResponse.status === 'expired'\n ) {\n throw new Error(\n `Transaction ${txResponse.status}: ${txResponse.status_reason || 'No reason provided.'}`\n );\n }\n\n // Continue polling for 'pending' or 'sent' statuses\n await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL));\n }\n\n throw new Error(`Polling for transaction hash timed out for ID: ${transactionId}`);\n }\n}\n","import type { AbiFunction, AbiParameter, AbiStateMutability } from 'viem';\n\nimport type { ContractFunction, ContractSchema, FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { AbiItem } from '../types/abi';\nimport { formatInputName, formatMethodName } from '../utils';\n\n/**\n * Transforms a standard ABI array (typically from an EVM-compatible chain)\n * into the project's internal `ContractSchema` format.\n * This schema is used by the builder app and renderer to represent contract interactions\n * in a chain-agnostic way (though this specific transformer is for EVM ABIs).\n *\n * @param abi The raw ABI array (e.g., parsed from a JSON ABI file or fetched from Etherscan).\n * It's expected to be an array of `AbiItem` (from viem types or a compatible structure).\n * @param contractName A name to assign to the contract within the schema. This might be derived\n * from a file name, user input, or a default if not otherwise available.\n * @param address Optional address of the deployed contract. If provided, it's included in the schema.\n * @returns A `ContractSchema` object representing the contract's interface.\n */\nexport function transformAbiToSchema(\n abi: readonly AbiItem[],\n contractName: string,\n address?: string\n): ContractSchema {\n logger.info('transformAbiToSchema', `Transforming ABI to ContractSchema for: ${contractName}`);\n const functions: ContractFunction[] = [];\n\n for (const item of abi) {\n // We are only interested in 'function' type items from the ABI\n // to map them to our ContractFunction interface.\n if (item.type === 'function') {\n // After confirming item.type is 'function', we can safely cast it to AbiFunction\n // to access function-specific properties like `stateMutability`, `inputs`, `outputs`.\n const abiFunctionItem = item as AbiFunction;\n functions.push({\n // Generate a unique ID for the function within the schema.\n // This often combines name and input types to handle overloads.\n id: `${abiFunctionItem.name}_${abiFunctionItem.inputs?.map((i) => i.type).join('_') || ''}`,\n name: abiFunctionItem.name || '', // Fallback for unnamed functions (though rare).\n displayName: formatMethodName(abiFunctionItem.name || ''), // Create a more readable name for UI.\n // Recursively map ABI inputs and outputs to our FunctionParameter structure.\n // This ensures that any non-standard properties (like 'internalType') are stripped.\n inputs: mapAbiParametersToSchemaParameters(abiFunctionItem.inputs),\n outputs: mapAbiParametersToSchemaParameters(abiFunctionItem.outputs),\n type: 'function', // Explicitly set, as we filtered for this type.\n stateMutability: abiFunctionItem.stateMutability, // Preserve EVM-specific state mutability.\n // Determine if the function modifies blockchain state based on its `stateMutability`.\n // This is a crucial piece of information for the UI (e.g., to differentiate read vs. write calls).\n modifiesState:\n !abiFunctionItem.stateMutability || // If undefined, assume it modifies state (safer default)\n !['view', 'pure'].includes(abiFunctionItem.stateMutability),\n });\n }\n }\n\n const contractSchema: ContractSchema = {\n ecosystem: 'evm', // This transformer is specific to EVM.\n name: contractName,\n address,\n functions,\n };\n logger.info(\n 'transformAbiToSchema',\n `Transformation complete. Found ${contractSchema.functions.length} functions.`\n );\n return contractSchema;\n}\n\n/**\n * Recursively maps an array of ABI parameters (from viem's `AbiParameter` type or compatible)\n * to an array of `FunctionParameter` objects, which is our internal representation.\n * This function is crucial for stripping any properties not defined in `FunctionParameter`\n * (e.g., `internalType` from the raw ABI) and for handling nested components (structs/tuples).\n *\n * @param abiParams An array of ABI parameter objects. Can be undefined (e.g., if a function has no inputs/outputs).\n * @returns An array of `FunctionParameter` objects, or an empty array if `abiParams` is undefined.\n */\nfunction mapAbiParametersToSchemaParameters(\n abiParams: readonly AbiParameter[] | undefined\n): FunctionParameter[] {\n if (!abiParams) {\n return [];\n }\n return abiParams.map((param): FunctionParameter => {\n // Create the base FunctionParameter object, picking only defined properties.\n const schemaParam: FunctionParameter = {\n name: param.name || '', // Ensure name is a string, fallback if undefined in ABI.\n type: param.type, // The raw type string from the ABI (e.g., 'uint256', 'address', 'tuple').\n displayName: formatInputName(param.name || '', param.type), // Generate a user-friendly name.\n // `description` is not a standard part of an ABI parameter, so it's not mapped here.\n // It can be added later by the user in the builder app UI.\n };\n // Check for nested components (structs/tuples).\n // `param.type.startsWith('tuple')` checks if it's a tuple or tuple array.\n // `'components' in param` is a type guard for discriminated unions.\n // `param.components && param.components.length > 0` ensures components exist and are not empty.\n if (\n param.type.startsWith('tuple') &&\n 'components' in param && // Type guard for discriminated union (AbiParameter)\n param.components &&\n param.components.length > 0\n ) {\n // If components exist, recursively call this function to map them.\n // This ensures that nested structures also conform to `FunctionParameter` and strip extra fields.\n // Cast `param.components` because TypeScript might not fully infer its type after the `in` check within the map.\n schemaParam.components = mapAbiParametersToSchemaParameters(\n param.components as readonly AbiParameter[]\n );\n }\n return schemaParam;\n });\n}\n\n/**\n * Helper function to convert one of our internal `FunctionParameter` objects\n * back into a format compatible with viem's `AbiParameter` type.\n * This is primarily used by `createAbiFunctionItem` when constructing an `AbiFunction`\n * for interactions with viem or other ABI-consuming libraries.\n * It ensures that only properties expected by `AbiParameter` are included.\n *\n * @param param The internal `FunctionParameter` object.\n * @returns An `AbiParameter` object compatible with viem.\n */\nfunction mapSchemaParameterToAbiParameter(param: FunctionParameter): AbiParameter {\n // Handle tuple types specifically, as `AbiParameter` for tuples requires a `components` array.\n if (param.type.startsWith('tuple') && param.components && param.components.length > 0) {\n return {\n name: param.name || undefined, // ABI parameter names can be undefined (e.g., for return values).\n type: param.type as `tuple${string}`, // Cast to satisfy viem's specific tuple type string.\n // Recursively map nested components back to AbiParameter format.\n components: param.components.map(mapSchemaParameterToAbiParameter),\n };\n }\n // For non-tuple types, return a simpler AbiParameter structure.\n return {\n name: param.name || undefined,\n type: param.type,\n // `internalType` is not part of our `FunctionParameter` model, so it's not added back here.\n // Other ABI-specific fields like `indexed` (for events) are also not relevant here as\n // this function is focused on function parameters for `AbiFunction`.\n };\n}\n\n/**\n * Private helper to convert internal `ContractFunction` details (our model)\n * back into a viem `AbiFunction` object.\n * This is useful when interacting with libraries like viem that expect a standard ABI format.\n * Ensures that the generated AbiFunction conforms to viem's type definitions.\n *\n * @param functionDetails The `ContractFunction` object from our internal schema.\n * @returns An `AbiFunction` object.\n */\nexport function createAbiFunctionItem(functionDetails: ContractFunction): AbiFunction {\n return {\n name: functionDetails.name,\n type: 'function',\n inputs: functionDetails.inputs.map(mapSchemaParameterToAbiParameter),\n outputs: functionDetails.outputs?.map(mapSchemaParameterToAbiParameter) || [],\n stateMutability: (functionDetails.stateMutability ?? 'view') as AbiStateMutability,\n };\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveExplorerConfig } from '../configuration/explorer';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { loadAbiFromEtherscanV2, shouldUseV2Api } from './etherscan-v2';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Result type for Etherscan ABI loading that includes the original ABI string\n */\nexport interface EtherscanAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\n/**\n * IMPORTANT: Etherscan V1 API Deprecation Notice\n *\n * Etherscan has announced the deprecation of their V1 API endpoints in favor of the new V2 unified API.\n * The V2 API provides a single endpoint that works across all EVM chains, making it more scalable and\n * easier to maintain.\n *\n * Key differences:\n * - V1: Each chain has its own API endpoint (e.g., api.etherscan.io, api.bscscan.com, etc.)\n * - V2: Single unified endpoint (api.etherscan.io/v2/api) with chainId parameter\n *\n * Migration strategy:\n * - Networks with `supportsEtherscanV2: true` will automatically use V2 API\n * - Legacy networks without V2 support will continue using V1 until they're updated\n * - New networks should always be configured with V2 support\n *\n * The V1 API functions are maintained for backward compatibility but should be considered\n * deprecated and will be removed in a future release.\n */\n\n/**\n * Fetches and parses an ABI from Etherscan-compatible explorers using a contract address and network config.\n * Automatically selects V1 or V2 API based on network support and user configuration.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscan(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n if (shouldUseV2Api(networkConfig)) {\n logger.info('loadAbiFromEtherscan', 'Using V2 API for fetching ABI');\n return loadAbiFromEtherscanV2(address, networkConfig);\n }\n\n // Use V1 API (legacy)\n logger.info('loadAbiFromEtherscan', 'Using V1 API for fetching ABI');\n return loadAbiFromEtherscanV1(address, networkConfig);\n}\n\n/**\n * Fetches and parses an ABI from Etherscan V1 API using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscanV1(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n const explorerConfig = resolveExplorerConfig(networkConfig);\n\n if (!explorerConfig.apiUrl) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `API URL is missing for ${networkConfig.name} explorer.`\n );\n throw new Error(`Explorer API URL for ${networkConfig.name} is not configured.`);\n }\n\n const url = new URL(explorerConfig.apiUrl);\n url.searchParams.append('module', 'contract');\n url.searchParams.append('action', 'getabi');\n url.searchParams.append('address', address);\n\n // Only append API key if provided\n if (explorerConfig.apiKey) {\n url.searchParams.append('apikey', explorerConfig.apiKey);\n }\n\n let response: Response;\n try {\n logger.info(\n 'loadAbiFromEtherscanV1',\n `Fetching ABI from ${explorerConfig.apiUrl} for address: ${address}`\n );\n response = await fetch(url);\n } catch (networkError) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Network error fetching ABI from Explorer API: ${networkError}`\n );\n throw new Error(`Network error fetching ABI: ${(networkError as Error).message}`);\n }\n\n if (!response.ok) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Explorer API request failed with status: ${response.status}`\n );\n throw new Error(`Explorer API request failed: ${response.status} ${response.statusText}`);\n }\n\n let apiResult: { status: string; message: string; result: string };\n try {\n apiResult = await response.json();\n } catch (jsonError) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Failed to parse Explorer API response as JSON: ${jsonError}`\n );\n throw new Error('Invalid JSON response received from Explorer API.');\n }\n\n if (apiResult.status !== '1') {\n logger.warn(\n 'loadAbiFromEtherscanV1',\n `Explorer API error: Status ${apiResult.status}, Message: ${apiResult.message}, Result: ${apiResult.result}`\n );\n if (apiResult.result?.includes('Contract source code not verified')) {\n throw new Error(\n `Contract not verified on ${networkConfig.name} explorer (address: ${address}). ABI not available. You can provide the contract's ABI manually.`\n );\n }\n throw new Error(`Explorer API Error: ${apiResult.result || apiResult.message}`);\n }\n\n // Store the original raw ABI string before parsing\n const originalAbiString = apiResult.result;\n\n let abi: AbiItem[];\n try {\n abi = JSON.parse(originalAbiString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed ABI from Explorer API is not an array.');\n }\n } catch (error) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Failed to parse ABI JSON string from Explorer API result: ${error}`\n );\n throw new Error(`Invalid ABI JSON received from Explorer API: ${(error as Error).message}`);\n }\n\n logger.info(\n 'loadAbiFromEtherscanV1',\n `Successfully parsed ABI for ${networkConfig.name} with ${abi.length} items.`\n );\n // TODO: Fetch contract name?\n const contractName = `Contract_${address.substring(0, 6)}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return {\n schema,\n originalAbi: originalAbiString,\n };\n}\n","import { trimEnd } from 'lodash';\n\nimport { UserExplorerConfig } from '@openzeppelin/ui-types';\nimport { appConfigService, logger, userNetworkServiceConfigService } from '@openzeppelin/ui-utils';\n\nimport { shouldUseV2Api, testEtherscanV2Connection } from '../abi/etherscan-v2';\nimport { EvmCompatibleNetworkConfig } from '../types/network';\nimport { isValidEvmAddress } from '../utils';\n\n/**\n * Resolves the explorer API key from app configuration (without user overrides).\n * This is used by getDefaultServiceConfig to provide defaults for health checks.\n *\n * Priority order:\n * 1. For V2 API networks: Global Etherscan V2 API key\n * 2. Network-specific global service config API key\n * 3. Fallback to explorer API key by identifier\n *\n * @param networkConfig - EVM-compatible network configuration\n * @returns The resolved API key, or undefined if not configured\n */\nexport function resolveExplorerApiKeyFromAppConfig(\n networkConfig: EvmCompatibleNetworkConfig\n): string | undefined {\n const isV2 =\n networkConfig.supportsEtherscanV2 &&\n networkConfig.primaryExplorerApiIdentifier === 'etherscan-v2';\n\n // For V2-compatible networks, check global Etherscan V2 API key first\n if (isV2) {\n const globalV2ApiKey = appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as\n | string\n | undefined;\n if (globalV2ApiKey) {\n return globalV2ApiKey;\n }\n }\n\n // For non-V2 networks or when no V2 key is available, check network-specific configs\n if (networkConfig.primaryExplorerApiIdentifier) {\n const globalServiceConfig = appConfigService.getGlobalServiceConfig(\n networkConfig.primaryExplorerApiIdentifier\n );\n const apiKey =\n (globalServiceConfig?.apiKey as string | undefined) ??\n appConfigService.getExplorerApiKey(networkConfig.primaryExplorerApiIdentifier);\n if (apiKey) {\n return apiKey;\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolves the explorer configuration for a given EVM network.\n * Priority order:\n * 1. User-configured explorer (from UserExplorerConfigService)\n * 2. For V2 API networks: Global Etherscan V2 API key (from AppConfigService global service configs)\n * 3. App-configured explorer API key (from AppConfigService network service configs)\n * 4. Default network explorer (from NetworkConfig)\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem).\n * @returns The resolved explorer configuration.\n */\nexport function resolveExplorerConfig(\n networkConfig: EvmCompatibleNetworkConfig\n): UserExplorerConfig {\n // Precompute app-level keys and defaults for merging\n const isV2 =\n networkConfig.supportsEtherscanV2 &&\n networkConfig.primaryExplorerApiIdentifier === 'etherscan-v2';\n const globalV2ApiKey = isV2\n ? (appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as string | undefined)\n : undefined;\n\n // For non-V2 networks, check globalServiceConfigs first (e.g., routescan), then fall back to explorer API keys\n let appApiKey: string | undefined;\n if (networkConfig.primaryExplorerApiIdentifier) {\n // First check globalServiceConfigs (supports routescan, blockscout, etc.)\n const globalServiceConfig = appConfigService.getGlobalServiceConfig(\n networkConfig.primaryExplorerApiIdentifier\n );\n appApiKey =\n (globalServiceConfig?.apiKey as string | undefined) ??\n appConfigService.getExplorerApiKey(networkConfig.primaryExplorerApiIdentifier);\n }\n\n // 1. Check for user-configured explorer via new generic service\n const rawCfg = userNetworkServiceConfigService.get(networkConfig.id, 'explorer');\n if (rawCfg && typeof rawCfg === 'object') {\n const userCfg = rawCfg as Record<string, unknown>;\n logger.info('ExplorerConfig', `Using user-configured explorer for ${networkConfig.name}`);\n return {\n explorerUrl: (userCfg.explorerUrl as string | undefined) ?? networkConfig.explorerUrl,\n apiUrl: (userCfg.apiUrl as string | undefined) ?? networkConfig.apiUrl,\n apiKey: (userCfg.apiKey as string | undefined) ?? globalV2ApiKey ?? appApiKey,\n name: `${networkConfig.name} Explorer`,\n isCustom: true,\n };\n }\n\n // 2. For V2 API networks using 'etherscan-v2' identifier, check for global Etherscan V2 API key\n if (isV2 && globalV2ApiKey) {\n logger.info('ExplorerConfig', `Using global Etherscan V2 API key for ${networkConfig.name}`);\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n apiKey: globalV2ApiKey,\n name: `${networkConfig.name} Explorer (V2 API)`,\n isCustom: false,\n };\n }\n\n // 3. Check for app-configured API key (V1 style or other identifiers)\n if (appApiKey) {\n logger.info('ExplorerConfig', `Using app-configured API key for ${networkConfig.name}`);\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n apiKey: appApiKey,\n name: `${networkConfig.name} Explorer`,\n isCustom: false,\n };\n }\n\n // 4. Use default network explorer (no API key)\n logger.info(\n 'ExplorerConfig',\n `Using default explorer for ${networkConfig.name} (no API key configured)`\n );\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n name: `${networkConfig.name} Explorer`,\n isCustom: false,\n };\n}\n\n/**\n * Gets a blockchain explorer URL for an EVM address.\n * Uses the resolved explorer configuration.\n *\n * @param address - Contract or wallet address\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function getEvmExplorerAddressUrl(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): string | null {\n if (!isValidEvmAddress(address)) {\n return null;\n }\n\n const explorerConfig = resolveExplorerConfig(networkConfig);\n if (!explorerConfig.explorerUrl) {\n return null;\n }\n\n // Construct the URL using the explorerUrl from the config\n const baseUrl = trimEnd(explorerConfig.explorerUrl, '/');\n return `${baseUrl}/address/${address}`;\n}\n\n/**\n * Gets a blockchain explorer URL for an EVM transaction.\n * Uses the resolved explorer configuration.\n *\n * @param txHash - Transaction hash\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function getEvmExplorerTxUrl(\n txHash: string,\n networkConfig: EvmCompatibleNetworkConfig\n): string | null {\n if (!txHash) {\n return null;\n }\n\n const explorerConfig = resolveExplorerConfig(networkConfig);\n if (!explorerConfig.explorerUrl) {\n return null;\n }\n\n // Construct the URL using the explorerUrl from the config\n const baseUrl = trimEnd(explorerConfig.explorerUrl, '/');\n return `${baseUrl}/tx/${txHash}`;\n}\n\n/**\n * Validates an EVM explorer configuration.\n * Checks URL formats and API key format.\n */\nexport function validateEvmExplorerConfig(explorerConfig: UserExplorerConfig): boolean {\n // Validate URLs if provided\n if (explorerConfig.explorerUrl) {\n try {\n new URL(explorerConfig.explorerUrl);\n } catch {\n return false;\n }\n }\n\n if (explorerConfig.apiUrl) {\n try {\n new URL(explorerConfig.apiUrl);\n } catch {\n return false;\n }\n }\n\n // Basic API key validation (not empty)\n if (explorerConfig.apiKey !== undefined && explorerConfig.apiKey.trim().length === 0) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Tests the connection to an EVM explorer API.\n * Makes a test API call to verify the API key works.\n * Automatically uses V2 API testing for networks that support it.\n *\n * @param explorerConfig - Explorer configuration to test\n * @param networkConfig - Optional EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function testEvmExplorerConnection(\n explorerConfig: UserExplorerConfig,\n networkConfig?: EvmCompatibleNetworkConfig\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n // Check if this network supports V2 API and should use it\n if (networkConfig && shouldUseV2Api(networkConfig)) {\n // Use the V2-specific connection test\n logger.info(\n 'testEvmExplorerConnection',\n `Using V2 API connection test for ${networkConfig.name}`\n );\n return testEtherscanV2Connection(networkConfig, explorerConfig.apiKey);\n }\n\n // V1 API testing path\n // Check if API key is required for this network\n const requiresApiKey =\n networkConfig && 'requiresExplorerApiKey' in networkConfig\n ? networkConfig.requiresExplorerApiKey !== false\n : true;\n\n if (requiresApiKey && !explorerConfig.apiKey) {\n return {\n success: false,\n error: 'API key is required for testing connection to this explorer',\n };\n }\n\n // Use provided API URL or fall back to network config if available\n let apiUrl = explorerConfig.apiUrl;\n if (!apiUrl && networkConfig?.apiUrl) {\n apiUrl = networkConfig.apiUrl;\n }\n\n if (!apiUrl) {\n return {\n success: false,\n error:\n 'API URL is required for testing connection. Please provide an API URL or ensure the network has a default API URL configured.',\n };\n }\n\n const startTime = Date.now();\n\n try {\n // Test with a simple API call - get the latest block number\n const url = new URL(apiUrl);\n url.searchParams.append('module', 'proxy');\n url.searchParams.append('action', 'eth_blockNumber');\n if (explorerConfig.apiKey) {\n url.searchParams.append('apikey', explorerConfig.apiKey);\n }\n\n const response = await fetch(url.toString());\n const latency = Date.now() - startTime;\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n latency,\n };\n }\n\n const data = await response.json();\n\n // Check for API errors in the response\n if (data.status === '0' && data.message) {\n return {\n success: false,\n error: data.message,\n latency,\n };\n }\n\n // Success if we got a valid response\n return {\n success: true,\n latency,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection test failed',\n latency: Date.now() - startTime,\n };\n }\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveExplorerConfig } from '../configuration/explorer';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Result type for Etherscan ABI loading that includes the original ABI string\n */\nexport interface EtherscanAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\n// Etherscan V2 unified API base URL\nconst ETHERSCAN_V2_BASE_URL = 'https://api.etherscan.io/v2/api';\n\n/**\n * Builds a V2 API URL for Etherscan-compatible explorers\n */\nfunction buildV2ApiUrl(\n chainId: number,\n module: string,\n action: string,\n params: Record<string, string>,\n apiKey?: string // Some explorers don't require an API key (routescan.io)\n): string {\n const url = new URL(ETHERSCAN_V2_BASE_URL);\n url.searchParams.append('chainid', chainId.toString());\n url.searchParams.append('module', module);\n url.searchParams.append('action', action);\n\n Object.entries(params).forEach(([key, value]) => {\n url.searchParams.append(key, value);\n });\n\n if (apiKey) {\n url.searchParams.append('apikey', apiKey);\n }\n\n return url.toString();\n}\n\n/**\n * Checks if the network supports V2 API\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function shouldUseV2Api(networkConfig: EvmCompatibleNetworkConfig): boolean {\n if (!networkConfig.supportsEtherscanV2) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Fetches and parses an ABI from Etherscan V2 API using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscanV2(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n const explorerConfig = resolveExplorerConfig(networkConfig);\n\n const url = buildV2ApiUrl(\n networkConfig.chainId,\n 'contract',\n 'getabi',\n { address },\n explorerConfig.apiKey\n );\n\n let response: Response;\n try {\n logger.info(\n 'loadAbiFromEtherscanV2',\n `Fetching ABI from Etherscan V2 API for address: ${address} on chain ${networkConfig.chainId}`\n );\n response = await fetch(url);\n } catch (networkError) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Network error fetching ABI from Explorer V2 API: ${networkError}`\n );\n throw new Error(`Network error fetching ABI: ${(networkError as Error).message}`);\n }\n\n if (!response.ok) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Explorer V2 API request failed with status: ${response.status}`\n );\n throw new Error(`Explorer V2 API request failed: ${response.status} ${response.statusText}`);\n }\n\n let apiResult: { status: string; message: string; result: string };\n try {\n apiResult = await response.json();\n } catch (jsonError) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Failed to parse Explorer V2 API response as JSON: ${jsonError}`\n );\n throw new Error('Invalid JSON response received from Explorer V2 API.');\n }\n\n if (apiResult.status !== '1') {\n logger.warn(\n 'loadAbiFromEtherscanV2',\n `Explorer V2 API error: Status ${apiResult.status}, Message: ${apiResult.message}, Result: ${apiResult.result}`\n );\n\n // Handle specific V2 API error messages\n if (apiResult.message?.includes('NOTOK')) {\n if (apiResult.result?.includes('Invalid API Key')) {\n throw new Error(\n `Invalid API key for Etherscan V2. Please check your API key configuration.`\n );\n }\n if (apiResult.result?.includes('Contract source code not verified')) {\n throw new Error(\n `Contract not verified on ${networkConfig.name} explorer (address: ${address}). ABI not available. You can provide the contract's ABI manually.`\n );\n }\n if (apiResult.result?.includes('Invalid chain')) {\n throw new Error(\n `Chain ID ${networkConfig.chainId} is not supported by Etherscan V2 API. Please check if this chain is available.`\n );\n }\n }\n\n throw new Error(`Explorer V2 API Error: ${apiResult.result || apiResult.message}`);\n }\n\n // Store the original raw ABI string before parsing\n const originalAbiString = apiResult.result;\n\n let abi: AbiItem[];\n try {\n abi = JSON.parse(originalAbiString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed ABI from Explorer V2 API is not an array.');\n }\n } catch (error) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Failed to parse ABI JSON string from Explorer V2 API result: ${error}`\n );\n throw new Error(`Invalid ABI JSON received from Explorer V2 API: ${(error as Error).message}`);\n }\n\n logger.info(\n 'loadAbiFromEtherscanV2',\n `Successfully parsed ABI for ${networkConfig.name} with ${abi.length} items using V2 API.`\n );\n\n // TODO: Fetch contract name?\n const contractName = `Contract_${address.substring(0, 6)}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return {\n schema,\n originalAbi: originalAbiString,\n };\n}\n\n/**\n * Test connection to Etherscan V2 API\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param apiKey - Optional API key for authentication\n */\nexport async function testEtherscanV2Connection(\n networkConfig: EvmCompatibleNetworkConfig,\n apiKey?: string\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n const startTime = Date.now();\n\n const requiresApiKey = networkConfig.requiresExplorerApiKey ?? true;\n\n if (requiresApiKey && !apiKey) {\n return {\n success: false,\n error: 'API key is required for testing connection to this explorer',\n };\n }\n\n try {\n // Test with a simple API call - get the latest block number\n const url = buildV2ApiUrl(networkConfig.chainId, 'proxy', 'eth_blockNumber', {}, apiKey);\n\n const response = await fetch(url);\n const latency = Date.now() - startTime;\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n latency,\n };\n }\n\n const data = await response.json();\n\n // Check for API errors in the response\n if (data.status === '0' && data.message) {\n // Handle specific V2 API error messages\n if (data.result?.includes('Invalid API Key')) {\n return {\n success: false,\n error: 'Invalid API key. Please check your Etherscan API key.',\n latency,\n };\n }\n if (data.result?.includes('Invalid chain')) {\n return {\n success: false,\n error: `Chain ID ${networkConfig.chainId} is not supported by Etherscan V2 API.`,\n latency,\n };\n }\n\n return {\n success: false,\n error: data.result || data.message,\n latency,\n };\n }\n\n // Success if we got a valid response\n return {\n success: true,\n latency,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection test failed',\n latency: Date.now() - startTime,\n };\n }\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { transformAbiToSchema } from './transformer';\n\nexport interface SourcifyAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\nconst SOURCIFY_APP_BASE = 'https://repo.sourcify.dev';\n\nexport function getSourcifyContractAppUrl(chainId: number, address: string): string {\n return `${SOURCIFY_APP_BASE}/${chainId}/${address}`;\n}\n\nconst SOURCIFY_API_BASE = 'https://sourcify.dev/server/v2';\n\ninterface SourcifyApiContractResponse {\n abi?: AbiItem[];\n metadata?: {\n contractName?: string;\n output?: {\n abi?: AbiItem[];\n };\n };\n}\n\nfunction buildSourcifyApiUrl(chainId: number, address: string): string {\n const normalizedAddress = address.toLowerCase();\n const url = new URL(\n `${SOURCIFY_API_BASE}/contract/${chainId}/${normalizedAddress}?fields=abi,metadata`\n );\n return url.toString();\n}\n\n/**\n * Fetches and parses an ABI from Sourcify using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param timeoutMs - Timeout in milliseconds (default: 4000ms)\n */\nexport async function loadAbiFromSourcify(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig,\n timeoutMs = 4000\n): Promise<SourcifyAbiResult> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const url = buildSourcifyApiUrl(networkConfig.chainId, address);\n logger.info('loadAbiFromSourcify', `Fetching contract from ${url}`);\n\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) {\n throw new Error(`Sourcify request failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as SourcifyApiContractResponse;\n const abi = payload.abi ?? payload.metadata?.output?.abi;\n\n if (!abi || !Array.isArray(abi)) {\n throw new Error('Sourcify metadata did not include a valid ABI array');\n }\n\n const normalizedAddress = address.toLowerCase();\n const contractName =\n payload.metadata?.contractName ||\n `Contract_${normalizedAddress.substring(0, 6).toUpperCase()}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return { schema, originalAbi: JSON.stringify(abi) };\n } catch (error) {\n logger.warn('loadAbiFromSourcify', `Failed to fetch ABI from Sourcify: ${String(error)}`);\n throw error as Error;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import { isAddress } from 'viem';\n\nimport type { ContractDefinitionMetadata, ContractSchema, ProxyInfo } from '@openzeppelin/ui-types';\nimport {\n appConfigService,\n logger,\n simpleHash,\n userNetworkServiceConfigService,\n withTimeout,\n} from '@openzeppelin/ui-utils';\n\nimport { getEvmExplorerAddressUrl } from '../configuration/explorer';\nimport { detectProxyFromAbi, getAdminAddress, getImplementationAddress } from '../proxy/detection';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmContractArtifacts } from '../types/artifacts';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport {\n EvmProviderKeys,\n isEvmProviderKey,\n type EvmContractDefinitionProviderKey,\n} from '../types/providers';\nimport { loadAbiFromEtherscan } from './etherscan';\nimport { getSourcifyContractAppUrl, loadAbiFromSourcify } from './sourcify';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Loads and parses an ABI directly from a JSON string.\n */\nasync function loadAbiFromJson(abiJsonString: string): Promise<ContractSchema> {\n let abi: AbiItem[];\n try {\n abi = JSON.parse(abiJsonString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed JSON is not an array.');\n }\n } catch (error) {\n logger.error('loadAbiFromJson', 'Failed to parse source string as JSON ABI:', error);\n throw new Error(`Invalid JSON ABI provided: ${(error as Error).message}`);\n }\n\n logger.info('loadAbiFromJson', `Successfully parsed JSON ABI with ${abi.length} items.`);\n const contractName = 'ContractFromABI'; // Default name for direct ABI\n return transformAbiToSchema(abi, contractName, undefined);\n}\n\n/**\n * Enhanced result type for ABI loading with metadata and proxy information\n */\nexport interface EvmContractLoadResult {\n schema: ContractSchema;\n source: 'fetched' | 'manual';\n contractDefinitionOriginal?: string;\n metadata?: ContractDefinitionMetadata;\n proxyInfo?: ProxyInfo;\n}\n\n/**\n * Options for contract loading behavior\n */\nexport interface ContractLoadOptions {\n /** Skip proxy detection and load the contract ABI as-is */\n skipProxyDetection?: boolean;\n /** Force treating the address as an implementation contract */\n treatAsImplementation?: boolean;\n}\n\nconst PER_PROVIDER_TIMEOUT_MS = 4000;\nconst OVERALL_BUDGET_MS = 10000;\n\n/**\n * Loads contract schema from artifacts provided by the UI, prioritizing manual ABI input.\n * Returns enhanced result with schema source information and automatic proxy detection.\n *\n * @param artifacts - Contract artifacts containing address and optional ABI\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param options - Optional loading options\n */\nexport async function loadEvmContract(\n artifacts: EvmContractArtifacts,\n networkConfig: EvmCompatibleNetworkConfig,\n options: ContractLoadOptions = {}\n): Promise<EvmContractLoadResult> {\n const { contractAddress, contractDefinition, __proxyDetectionOptions } = artifacts;\n\n // Extract proxy detection options from form data if present\n const proxyOptions = __proxyDetectionOptions as { skipProxyDetection?: boolean } | undefined;\n if (proxyOptions?.skipProxyDetection) {\n options.skipProxyDetection = true;\n }\n\n if (!contractAddress || typeof contractAddress !== 'string' || !isAddress(contractAddress)) {\n throw new Error('A valid contract address is required.');\n }\n\n // 1. Prioritize manual contract definition input if provided.\n if (\n contractDefinition &&\n typeof contractDefinition === 'string' &&\n contractDefinition.trim().length > 0\n ) {\n // Try to detect if this looks like JSON\n const trimmed = contractDefinition.trim();\n const hasJsonContent = trimmed.includes('[') && trimmed.includes(']') && trimmed.includes('{');\n\n if (hasJsonContent) {\n logger.info('loadEvmContract', 'Manual contract definition provided. Attempting to parse...');\n try {\n const schema = await loadAbiFromJson(contractDefinition);\n // Attach the address to the schema from the separate address field.\n return {\n schema: { ...schema, address: contractAddress },\n source: 'manual' as const,\n contractDefinitionOriginal: contractDefinition,\n metadata: {\n contractName: schema.name,\n fetchTimestamp: new Date(),\n verificationStatus: 'unknown', // Manual ABI - verification status unknown\n },\n // Note: No proxy detection for manual ABIs - user provides what they want\n };\n } catch (error) {\n logger.error('loadEvmContract', 'Failed to parse manually provided ABI:', error);\n // If manual ABI is provided but invalid, it's a hard error.\n throw new Error(`The provided ABI JSON is invalid: ${(error as Error).message}`);\n }\n }\n }\n\n // Extract optional forced provider (from adapter-specific field or generic 'service')\n const forcedRaw =\n (artifacts as unknown as { __forcedProvider?: string }).__forcedProvider ||\n (artifacts as unknown as { service?: string }).service;\n const forcedProvider: EvmContractDefinitionProviderKey | null = isEvmProviderKey(forcedRaw)\n ? (forcedRaw as EvmContractDefinitionProviderKey)\n : null;\n\n // 2. If no manual ABI, fall back to fetching from provider(s) with proxy detection.\n logger.info(\n 'loadEvmContract',\n `No manual ABI detected. Attempting Etherscan fetch for address: ${contractAddress}...`\n );\n\n return await loadContractWithProxyDetection(\n contractAddress,\n networkConfig,\n options,\n forcedProvider\n );\n}\n\n/**\n * Builds a standard contract result with metadata\n */\nfunction buildContractResult(\n contractAddress: string,\n abiResult: { schema: ContractSchema; originalAbi: string },\n networkConfig: EvmCompatibleNetworkConfig,\n sourceProvider: EvmContractDefinitionProviderKey | null,\n proxyInfo?: ProxyInfo\n): EvmContractLoadResult {\n // Determine provenance URL based on the provider that supplied the ABI\n let fetchedFrom: string | undefined = undefined;\n if (sourceProvider === EvmProviderKeys.Etherscan) {\n fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || undefined;\n } else if (sourceProvider === EvmProviderKeys.Sourcify) {\n fetchedFrom = getSourcifyContractAppUrl(networkConfig.chainId, contractAddress);\n } else {\n // Fallback to resolved explorer URL when provider is unknown\n fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || undefined;\n }\n\n return {\n schema: { ...abiResult.schema, address: contractAddress },\n source: 'fetched',\n contractDefinitionOriginal: abiResult.originalAbi,\n metadata: {\n fetchedFrom,\n contractName: abiResult.schema.name,\n verificationStatus: 'verified',\n fetchTimestamp: new Date(),\n definitionHash: simpleHash(abiResult.originalAbi),\n },\n proxyInfo,\n };\n}\n\n/**\n * Attempts to load implementation ABI for a detected proxy\n */\nasync function loadImplementationAbi(\n _contractAddress: string,\n implementationAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n _proxyType: string\n): Promise<{ schema: ContractSchema; originalAbi: string } | null> {\n try {\n const implementationResult = await loadAbiFromEtherscan(implementationAddress, networkConfig);\n\n logger.info(\n 'loadImplementationAbi',\n `Successfully fetched implementation ABI with ${implementationResult.schema.functions.length} functions`\n );\n\n return implementationResult;\n } catch (implementationError) {\n logger.warn(\n 'loadImplementationAbi',\n `Failed to load implementation ABI: ${implementationError}`\n );\n return null;\n }\n}\n\n/**\n * Handles the proxy detection flow and returns appropriate result\n */\nasync function handleProxyDetection(\n contractAddress: string,\n initialResult: { schema: ContractSchema; originalAbi: string },\n networkConfig: EvmCompatibleNetworkConfig,\n initialProvider: EvmContractDefinitionProviderKey | null\n): Promise<EvmContractLoadResult | null> {\n // Parse the ABI to check for proxy patterns\n const abi: AbiItem[] = JSON.parse(initialResult.originalAbi);\n const proxyDetection = detectProxyFromAbi(abi);\n\n if (!proxyDetection.isProxy) {\n return null; // Not a proxy, let caller handle normal flow\n }\n\n logger.info(\n 'handleProxyDetection',\n `Proxy detected: ${proxyDetection.proxyType} (confidence: ${proxyDetection.confidence})`\n );\n\n const proxyType = proxyDetection.proxyType || 'unknown';\n const implementationAddress = await getImplementationAddress(\n contractAddress,\n networkConfig,\n proxyType\n );\n\n // Attempt to resolve admin address as well for display purposes\n const adminAddress = await getAdminAddress(contractAddress, networkConfig);\n\n if (!implementationAddress) {\n logger.info('handleProxyDetection', 'Proxy detected but implementation address not found');\n\n // Return proxy ABI with proxy info indicating detection failure\n return buildContractResult(contractAddress, initialResult, networkConfig, initialProvider, {\n isProxy: true,\n proxyType,\n proxyAddress: contractAddress,\n detectionMethod: 'automatic',\n });\n }\n\n logger.info('handleProxyDetection', `Found implementation at: ${implementationAddress}`);\n\n // Try to load implementation ABI\n const implementationResult = await loadImplementationAbi(\n contractAddress,\n implementationAddress,\n networkConfig,\n proxyType\n );\n\n const baseProxyInfo = {\n isProxy: true,\n proxyType,\n implementationAddress,\n proxyAddress: contractAddress,\n detectionMethod: 'automatic',\n ...(adminAddress ? { adminAddress } : {}),\n };\n\n if (implementationResult) {\n // Use implementation ABI with proxy metadata\n // Implementation ABI was fetched from Etherscan\n return buildContractResult(\n contractAddress,\n implementationResult,\n networkConfig,\n EvmProviderKeys.Etherscan,\n baseProxyInfo\n );\n } else {\n // Fall back to proxy ABI with proxy info (provenance from initial provider)\n return buildContractResult(\n contractAddress,\n initialResult,\n networkConfig,\n initialProvider,\n baseProxyInfo\n );\n }\n}\n\n/**\n * Loads contract with automatic proxy detection and implementation resolution\n */\nasync function loadContractWithProxyDetection(\n contractAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n options: ContractLoadOptions = {},\n forcedProvider: EvmContractDefinitionProviderKey | null = null\n): Promise<EvmContractLoadResult> {\n try {\n // Determine provider precedence based on forced provider and user config\n let uiDefault: EvmContractDefinitionProviderKey | null = null;\n // 1) New generic per-service config\n const svcCfg = userNetworkServiceConfigService.get(networkConfig.id, 'contract-definitions');\n if (svcCfg && typeof svcCfg === 'object' && 'defaultProvider' in svcCfg) {\n const raw = (svcCfg as Record<string, unknown>).defaultProvider;\n if (isEvmProviderKey(raw)) uiDefault = raw as EvmContractDefinitionProviderKey;\n }\n // App-config default provider (optional)\n const appDefaultRaw = appConfigService.getGlobalServiceParam(\n 'contractdefinition',\n 'defaultProvider'\n );\n const appDefault: EvmContractDefinitionProviderKey | null =\n typeof appDefaultRaw === 'string' && isEvmProviderKey(appDefaultRaw)\n ? (appDefaultRaw as EvmContractDefinitionProviderKey)\n : null;\n\n // Helper function to build provider array from primary provider\n const buildProviderArray = (\n primary: EvmContractDefinitionProviderKey\n ): Array<EvmContractDefinitionProviderKey> => [\n primary,\n primary === EvmProviderKeys.Etherscan ? EvmProviderKeys.Sourcify : EvmProviderKeys.Etherscan,\n ];\n\n const providers: Array<EvmContractDefinitionProviderKey> = forcedProvider\n ? [forcedProvider]\n : uiDefault\n ? buildProviderArray(uiDefault)\n : appDefault\n ? buildProviderArray(appDefault)\n : [EvmProviderKeys.Etherscan, EvmProviderKeys.Sourcify];\n\n const overallDeadline = Date.now() + OVERALL_BUDGET_MS;\n let initialResult: { schema: ContractSchema; originalAbi: string } | null = null;\n let lastError: unknown = null;\n let usedProvider: EvmContractDefinitionProviderKey | null = null;\n for (const provider of providers) {\n try {\n const remainingOverall = Math.max(100, overallDeadline - Date.now());\n const attemptTimeout = Math.min(PER_PROVIDER_TIMEOUT_MS, remainingOverall);\n\n if (provider === EvmProviderKeys.Etherscan) {\n initialResult = await withTimeout(\n loadAbiFromEtherscan(contractAddress, networkConfig),\n attemptTimeout,\n 'etherscan'\n );\n } else if (provider === EvmProviderKeys.Sourcify) {\n initialResult = await withTimeout(\n loadAbiFromSourcify(contractAddress, networkConfig, attemptTimeout),\n attemptTimeout,\n 'sourcify'\n );\n }\n if (initialResult) {\n usedProvider = provider;\n break;\n }\n } catch (err) {\n lastError = err;\n continue;\n }\n }\n if (!initialResult) throw lastError ?? new Error('No provider succeeded');\n\n logger.info(\n 'loadContractWithProxyDetection',\n `Successfully fetched initial ABI for ${contractAddress} with ${initialResult.schema.functions.length} functions`\n );\n\n // Step 2: Handle proxy detection if enabled\n if (!options.skipProxyDetection && !options.treatAsImplementation) {\n const proxyResult = await handleProxyDetection(\n contractAddress,\n initialResult,\n networkConfig,\n usedProvider\n );\n if (proxyResult) {\n return proxyResult;\n }\n }\n\n // Step 3: Not a proxy or proxy detection skipped - return original ABI\n return buildContractResult(contractAddress, initialResult, networkConfig, usedProvider);\n } catch (error) {\n logger.warn('loadContractWithProxyDetection', `Contract loading failed: ${error}`);\n\n // If a forced provider was specified, honor it and do NOT fallback automatically\n if (forcedProvider) {\n throw error;\n }\n\n // Check if this is a \"contract not verified\" error\n const errorMessage = (error as Error).message || '';\n if (errorMessage.includes('Contract not verified')) {\n throw new Error(\n `Contract at ${contractAddress} is not verified on the block explorer. ` +\n `Verification status: unverified. Please provide the contract ABI manually.`\n );\n }\n // Otherwise, rethrow the last error from provider attempts\n throw error;\n }\n}\n\n// ============================================================================\n// Convenience Wrapper Functions\n// ============================================================================\n\n/**\n * Convenience wrapper that loads a contract and returns just the schema.\n * Handles artifact validation, ABI fetching, and proxy detection.\n *\n * @param source - Contract address string or artifacts object\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param options - Optional loading options\n * @returns The contract schema\n *\n * @example\n * ```typescript\n * // Load by address (fetches ABI from explorer)\n * const schema = await loadContractSchema('0x1234...', networkConfig);\n *\n * // Load with manual ABI\n * const schema = await loadContractSchema(\n * { contractAddress: '0x1234...', contractDefinition: '[...]' },\n * networkConfig\n * );\n * ```\n */\nexport async function loadContractSchema(\n source: string | Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig,\n options?: ContractLoadOptions\n): Promise<ContractSchema> {\n const { validateAndConvertEvmArtifacts } = await import('../utils');\n const artifacts = validateAndConvertEvmArtifacts(source);\n const result = await loadEvmContract(artifacts, networkConfig, options);\n return result.schema;\n}\n\n/**\n * Convenience wrapper that loads a contract with full metadata.\n * Returns schema, source information, original ABI, metadata, and proxy info.\n *\n * @param source - Contract address string or artifacts object\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @returns Full contract load result with metadata\n *\n * @example\n * ```typescript\n * const result = await loadContractWithFullMetadata('0x1234...', networkConfig);\n * console.log(result.schema.name); // Contract name\n * console.log(result.source); // 'fetched' | 'manual'\n * console.log(result.metadata?.fetchedFrom); // Explorer URL\n * console.log(result.proxyInfo?.isProxy); // Proxy detection result\n * ```\n */\nexport async function loadContractWithFullMetadata(\n source: string | Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EvmContractLoadResult> {\n const { validateAndConvertEvmArtifacts } = await import('../utils');\n const artifacts = validateAndConvertEvmArtifacts(source);\n return loadEvmContract(artifacts, networkConfig);\n}\n","/**\n * Proxy Contract Detection Utilities\n *\n * Automatically detects proxy contracts and resolves implementation addresses\n * for UUPS, Transparent, Beacon, and other proxy patterns.\n */\nimport { createPublicClient, http, keccak256, parseAbi, toHex } from 'viem';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveRpcUrl } from '../configuration/rpc';\nimport { AbiItem } from '../types/abi';\nimport { EvmCompatibleNetworkConfig } from '../types/network';\n\nexport interface ProxyDetectionResult {\n isProxy: boolean;\n proxyType: 'uups' | 'transparent' | 'beacon' | 'diamond' | 'minimal' | 'unknown' | null;\n confidence: 'high' | 'medium' | 'low';\n indicators: string[];\n}\n\n/**\n * Analyzes an ABI to determine if it belongs to a proxy contract\n */\nexport function detectProxyFromAbi(abi: AbiItem[]): ProxyDetectionResult {\n const functions = abi.filter((item) => item.type === 'function');\n const events = abi.filter((item) => item.type === 'event');\n const errors = abi.filter((item) => item.type === 'error');\n\n const indicators: string[] = [];\n let proxyType: ProxyDetectionResult['proxyType'] = null;\n let confidence: ProxyDetectionResult['confidence'] = 'low';\n\n // Check for UUPS proxy indicators\n const hasUpgradeEvent = events.some((e) => e.name === 'Upgraded');\n const hasImplementationFunction = functions.some((f) => f.name === 'implementation');\n const hasUUPSErrors = errors.some((e) => e.name?.includes('ERC1967'));\n const hasUpgradeToFunction = functions.some(\n (f) => f.name === 'upgradeToAndCall' || f.name === 'upgradeTo'\n );\n\n if (hasUpgradeEvent || hasUUPSErrors) {\n indicators.push('ERC1967 upgrade pattern detected');\n proxyType = 'uups';\n confidence = 'high';\n }\n\n if (hasImplementationFunction) {\n indicators.push('implementation() function found');\n if (proxyType === 'uups') {\n confidence = 'high';\n } else {\n proxyType = 'transparent';\n confidence = 'medium';\n }\n }\n\n if (hasUpgradeToFunction && proxyType === 'uups') {\n indicators.push('UUPS upgrade functions found');\n confidence = 'high';\n }\n\n // Check for Transparent proxy indicators\n const hasAdminFunction = functions.some((f) => f.name === 'admin');\n const hasProxyAdminErrors = errors.some((e) => e.name?.includes('ProxyDenied'));\n const hasChangeAdminFunction = functions.some((f) => f.name === 'changeAdmin');\n\n if (hasAdminFunction || hasProxyAdminErrors || hasChangeAdminFunction) {\n indicators.push('Transparent proxy admin pattern detected');\n if (proxyType === null) {\n proxyType = 'transparent';\n confidence = 'medium';\n }\n }\n\n // Check for Beacon proxy indicators\n const hasBeaconFunction = functions.some((f) => f.name === 'beacon');\n const hasBeaconUpgrade = events.some((e) => e.name === 'BeaconUpgraded');\n\n if (hasBeaconFunction || hasBeaconUpgrade) {\n indicators.push('Beacon proxy pattern detected');\n proxyType = 'beacon';\n confidence = 'high';\n }\n\n // Check for Diamond proxy indicators\n const hasDiamondCut = functions.some((f) => f.name === 'diamondCut');\n const hasFacets = functions.some((f) => f.name === 'facets');\n const hasFacetFunctionSelectors = functions.some((f) => f.name === 'facetFunctionSelectors');\n\n if (hasDiamondCut || (hasFacets && hasFacetFunctionSelectors)) {\n indicators.push('Diamond (EIP-2535) proxy pattern detected');\n proxyType = 'diamond';\n confidence = 'high';\n }\n\n // General proxy indicators\n const hasFallback = abi.some((item) => item.type === 'fallback');\n const hasProxyConstructor = abi.some(\n (item) =>\n item.type === 'constructor' &&\n item.inputs?.some(\n (input: AbiItem) =>\n input.name === 'implementation' || input.name === '_logic' || input.name === '_data'\n )\n );\n\n if (hasFallback) {\n indicators.push('Fallback function present');\n }\n\n if (hasProxyConstructor) {\n indicators.push('Proxy-style constructor detected');\n }\n\n // Minimal proxy (EIP-1167) detection\n const hasMinimalFunctions = functions.length <= 1; // Usually no functions except maybe implementation()\n const hasNoEvents = events.length === 0;\n\n if (hasMinimalFunctions && hasNoEvents && hasFallback && proxyType === null) {\n indicators.push('Minimal proxy pattern detected');\n proxyType = 'minimal';\n confidence = 'medium';\n }\n\n // Final proxy determination\n const isProxy =\n proxyType !== null ||\n (hasFallback && hasMinimalFunctions && (hasProxyConstructor || functions.length === 0));\n\n if (isProxy && proxyType === null) {\n proxyType = 'unknown';\n indicators.push('Generic proxy pattern detected');\n confidence = 'low';\n }\n\n return {\n isProxy,\n proxyType,\n confidence,\n indicators,\n };\n}\n\n/**\n * Attempts to resolve the implementation address for a proxy contract\n *\n * @param proxyAddress - Address of the proxy contract\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param proxyType - Type of proxy (uups, transparent, beacon, diamond, minimal, unknown)\n */\nexport async function getImplementationAddress(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n proxyType: string\n): Promise<string | null> {\n logger.info(\n 'getImplementationAddress',\n `Resolving implementation for ${proxyType} proxy: ${proxyAddress}`\n );\n\n try {\n switch (proxyType) {\n case 'uups':\n case 'transparent': {\n // Try modern EIP-1967 slot first\n const eip1967Impl = await getEIP1967Implementation(proxyAddress, networkConfig);\n if (eip1967Impl) return eip1967Impl;\n\n // Fall back to legacy OZ Unstructured Storage slot used by older proxies\n const legacyImpl = await getLegacyOZImplementation(proxyAddress, networkConfig);\n if (legacyImpl) return legacyImpl;\n\n return null;\n }\n\n case 'beacon':\n return await getBeaconImplementation(proxyAddress, networkConfig);\n\n case 'diamond':\n // Diamond proxies don't have a single implementation\n // Would need to handle facets separately\n logger.info('getImplementationAddress', 'Diamond proxies not fully supported yet');\n return null;\n\n case 'minimal':\n return await getMinimalProxyImplementation(proxyAddress, networkConfig);\n\n default:\n // Try common methods for unknown proxy types\n return await tryCommonImplementationMethods(proxyAddress, networkConfig);\n }\n } catch (error) {\n logger.warn('getImplementationAddress', `Failed to resolve implementation: ${error}`);\n return null;\n }\n}\n\n/**\n * Attempts to resolve the admin address for a proxy contract\n * Tries EIP-1967 admin slot first, then legacy OZ slot\n *\n * @param proxyAddress - Address of the proxy contract\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function getAdminAddress(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const eip1967Admin = await getEIP1967Admin(proxyAddress, networkConfig);\n if (eip1967Admin) return eip1967Admin;\n\n const legacyAdmin = await getLegacyOZAdmin(proxyAddress, networkConfig);\n if (legacyAdmin) return legacyAdmin;\n\n return null;\n } catch (error) {\n logger.warn('getAdminAddress', `Failed to resolve admin: ${error}`);\n return null;\n }\n}\n\n/**\n * Reads implementation address from EIP-1967 storage slot\n */\nasync function getEIP1967Implementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n // EIP-1967 implementation storage slot\n const implementationSlot = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc';\n\n return await readStorageSlot(proxyAddress, implementationSlot, networkConfig);\n}\n\n/**\n * Reads admin address from EIP-1967 admin storage slot\n * Slot: bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\nasync function getEIP1967Admin(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n const adminSlot = '0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103';\n return await readStorageSlot(proxyAddress, adminSlot, networkConfig);\n}\n\n/**\n * Reads admin address from legacy OpenZeppelin Unstructured Storage slot\n * Slot: keccak256(\"org.zeppelinos.proxy.admin\")\n */\nasync function getLegacyOZAdmin(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const slot = keccak256(toHex('org.zeppelinos.proxy.admin'));\n logger.info('getLegacyOZAdmin', `Trying legacy OZ admin slot: ${slot}`);\n return await readStorageSlot(proxyAddress, slot, networkConfig);\n } catch (error) {\n logger.warn('getLegacyOZAdmin', `Failed computing or reading legacy admin slot: ${error}`);\n return null;\n }\n}\n\n/**\n * Reads implementation address from legacy OpenZeppelin Unstructured Storage slot\n * Slot: keccak256(\"org.zeppelinos.proxy.implementation\")\n */\nasync function getLegacyOZImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n // Compute slot deterministically at runtime to avoid hardcoding\n const slot = keccak256(toHex('org.zeppelinos.proxy.implementation'));\n logger.info('getLegacyOZImplementation', `Trying legacy OZ slot: ${slot}`);\n return await readStorageSlot(proxyAddress, slot, networkConfig);\n } catch (error) {\n logger.warn('getLegacyOZImplementation', `Failed computing or reading legacy slot: ${error}`);\n return null;\n }\n}\n\n/**\n * Resolves implementation through beacon proxy pattern\n */\nasync function getBeaconImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n // EIP-1967 beacon storage slot\n const beaconSlot = '0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50';\n\n const beaconAddress = await readStorageSlot(proxyAddress, beaconSlot, networkConfig);\n if (!beaconAddress) {\n return null;\n }\n\n // Call implementation() on the beacon contract\n return await callContractFunction(beaconAddress, 'implementation()', [], networkConfig);\n}\n\n/**\n * Extracts implementation from minimal proxy bytecode\n */\nasync function getMinimalProxyImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n // Get the contract bytecode\n const bytecode = await getContractBytecode(proxyAddress, networkConfig);\n\n if (!bytecode || bytecode.length < 42) {\n return null;\n }\n\n // Minimal proxy (EIP-1167) has a specific bytecode pattern\n // 0x363d3d373d3d3d363d73{implementation}5af43d82803e903d91602b57fd5bf3\n if (\n bytecode.startsWith('0x363d3d373d3d3d363d73') &&\n bytecode.includes('5af43d82803e903d91602b57fd5bf3')\n ) {\n // Extract the 20-byte implementation address\n const implementationHex = bytecode.slice(22, 62); // Skip prefix, take 20 bytes (40 hex chars)\n return '0x' + implementationHex;\n }\n\n return null;\n } catch (error) {\n logger.warn('getMinimalProxyImplementation', `Error reading bytecode: ${error}`);\n return null;\n }\n}\n\n/**\n * Tries common proxy implementation methods\n */\nasync function tryCommonImplementationMethods(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n const commonMethods = [\n 'implementation()',\n 'getImplementation()',\n '_implementation()',\n 'target()',\n ];\n\n for (const method of commonMethods) {\n try {\n const result = await callContractFunction(proxyAddress, method, [], networkConfig);\n if (result && result !== '0x0000000000000000000000000000000000000000') {\n logger.info(\n 'tryCommonImplementationMethods',\n `Found implementation via ${method}: ${result}`\n );\n return result;\n }\n } catch {\n // Continue to next method\n continue;\n }\n }\n\n // Try EIP-1967 storage as last resort\n return await getEIP1967Implementation(proxyAddress, networkConfig);\n}\n\n/**\n * Creates a viem public client for the given network configuration\n */\nfunction createViemClient(networkConfig: EvmCompatibleNetworkConfig) {\n // Honor user/app RPC overrides\n const rpcUrl = resolveRpcUrl(networkConfig);\n return createPublicClient({\n transport: http(rpcUrl),\n });\n}\n\n/**\n * Reads a storage slot from a contract using viem\n */\nasync function readStorageSlot(\n address: string,\n slot: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n const storageValue = await client.getStorageAt({\n address: address as `0x${string}`,\n slot: slot as `0x${string}`,\n });\n\n // Convert from 32-byte storage format to 20-byte address\n if (\n storageValue &&\n storageValue !== '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n logger.info('readStorageSlot', `Found non-zero value at slot ${slot}: ${storageValue}`);\n const implAddress = '0x' + storageValue.slice(-40); // Last 20 bytes\n return implAddress;\n }\n\n return null;\n } catch (error) {\n logger.warn('readStorageSlot', `Failed to read storage slot ${slot}: ${error}`);\n return null;\n }\n}\n\n/**\n * Calls a function on a contract using viem's readContract\n * Supports functions with parameters and proper return value decoding\n */\nasync function callContractFunction(\n address: string,\n signature: string,\n params: unknown[],\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n // Parse the function signature to get proper ABI format\n const abi = parseAbi([signature]);\n const func = abi[0] as { name: string; type: 'function' };\n\n // Use viem's readContract for cleaner, more robust contract calls\n const result = await client.readContract({\n address: address as `0x${string}`,\n abi,\n functionName: func.name,\n args: params as readonly unknown[],\n });\n\n // For proxy functions, we expect an address return value\n const addressResult = result as string;\n if (addressResult && addressResult !== '0x0000000000000000000000000000000000000000') {\n return addressResult;\n }\n\n return null;\n } catch (error) {\n logger.warn('callContractFunction', `Failed to call ${signature}: ${error}`);\n return null;\n }\n}\n\n/**\n * Gets contract bytecode using viem\n */\nasync function getContractBytecode(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n const bytecode = await client.getCode({\n address: address as `0x${string}`,\n });\n\n return bytecode || null;\n } catch (error) {\n logger.warn('getContractBytecode', `Failed to get bytecode: ${error}`);\n return null;\n }\n}\n","import type { UserRpcProviderConfig } from '@openzeppelin/ui-types';\nimport {\n appConfigService,\n isValidUrl,\n logger,\n userNetworkServiceConfigService,\n} from '@openzeppelin/ui-utils';\n\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\n\n/**\n * Builds a complete RPC URL from a user RPC provider configuration.\n * For simplified RPC configuration, this just returns the URL as-is since\n * users are now providing complete RPC URLs including any API keys.\n *\n * @param config The user RPC provider configuration\n * @returns The RPC URL\n */\nexport function buildRpcUrl(config: UserRpcProviderConfig): string {\n return config.url;\n}\n\n/**\n * Extracts the user-configured RPC URL from UserNetworkServiceConfigService.\n *\n * @param networkId - The network ID to get the RPC URL for\n * @returns The RPC URL string if configured, undefined otherwise\n */\nexport function getUserRpcUrl(networkId: string): string | undefined {\n const svcCfg = userNetworkServiceConfigService.get(networkId, 'rpc');\n if (svcCfg && typeof svcCfg === 'object' && 'rpcUrl' in svcCfg) {\n return (svcCfg as Record<string, unknown>).rpcUrl as string;\n }\n return undefined;\n}\n\n/**\n * Resolves the RPC URL for a given EVM network configuration.\n * Priority order:\n * 1. User-provided RPC configuration (from UserRpcConfigService)\n * 2. RPC URL override from AppConfigService\n * 3. Default rpcUrl from the network configuration\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem).\n * @returns The resolved RPC URL string.\n * @throws If no RPC URL can be resolved (neither user config, override, nor default is present and valid).\n */\nexport function resolveRpcUrl(networkConfig: EvmCompatibleNetworkConfig): string {\n const logSystem = 'RpcResolver';\n const networkId = networkConfig.id;\n\n // First priority: Check adapter-led service config (generic)\n const userRpcUrl = getUserRpcUrl(networkId);\n if (userRpcUrl) {\n const userRpcUrlString = String(userRpcUrl);\n if (isValidUrl(userRpcUrlString)) {\n logger.info(logSystem, `Using user-configured RPC URL for network ${networkId}`);\n return userRpcUrlString;\n } else {\n logger.warn(\n logSystem,\n `User-configured RPC URL for ${networkId} is invalid: ${userRpcUrlString}. Falling back.`\n );\n }\n }\n\n // Second priority: Check AppConfigService for an override\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(networkId);\n let rpcUrlFromOverride: string | undefined;\n\n if (typeof rpcOverrideSetting === 'string') {\n rpcUrlFromOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting) {\n // Check if it's a UserRpcProviderConfig\n if ('url' in rpcOverrideSetting && 'isCustom' in rpcOverrideSetting) {\n const userConfig = rpcOverrideSetting as UserRpcProviderConfig;\n rpcUrlFromOverride = buildRpcUrl(userConfig);\n } else if ('http' in rpcOverrideSetting) {\n // It's an RpcEndpointConfig\n rpcUrlFromOverride = rpcOverrideSetting.http;\n }\n }\n\n if (rpcUrlFromOverride) {\n logger.info(\n logSystem,\n `Using overridden RPC URL for network ${networkId}: ${rpcUrlFromOverride}`\n );\n if (isValidUrl(rpcUrlFromOverride)) {\n return rpcUrlFromOverride;\n } else {\n logger.warn(\n logSystem,\n `Overridden RPC URL for ${networkId} is invalid: ${rpcUrlFromOverride}. Falling back.`\n );\n }\n }\n\n // Third priority: Fallback to the rpcUrl in the networkConfig\n if (networkConfig.rpcUrl && isValidUrl(networkConfig.rpcUrl)) {\n logger.debug(\n logSystem,\n `Using default RPC URL for network ${networkId}: ${networkConfig.rpcUrl}`\n );\n return networkConfig.rpcUrl;\n }\n\n logger.error(\n logSystem,\n `No valid RPC URL could be resolved for network ${networkId}. Checked user config, override, and networkConfig.rpcUrl.`\n );\n throw new Error(\n `No valid RPC URL configured for network ${networkConfig.name} (ID: ${networkId}).`\n );\n}\n\n/**\n * Validates an RPC endpoint configuration for EVM networks.\n * @param rpcConfig - The RPC provider configuration to validate\n * @returns True if the configuration is valid, false otherwise\n */\nexport function validateEvmRpcEndpoint(rpcConfig: UserRpcProviderConfig): boolean {\n try {\n // Check if it's a valid URL (our validator already ensures HTTP/HTTPS)\n if (!isValidUrl(rpcConfig.url)) {\n logger.error('validateEvmRpcEndpoint', `Invalid RPC URL format: ${rpcConfig.url}`);\n return false;\n }\n\n // Additional EVM-specific validation could be added here\n // For example, checking if the URL follows known provider patterns\n\n return true;\n } catch (error) {\n logger.error('validateEvmRpcEndpoint', 'Error validating RPC endpoint:', error);\n return false;\n }\n}\n\n/**\n * Tests the connection to an EVM RPC endpoint with a timeout.\n * @param rpcConfig - The RPC provider configuration to test\n * @param timeoutMs - Timeout in milliseconds (default: 5000ms)\n * @returns Connection test results including success status, latency, and any errors\n */\nexport async function testEvmRpcConnection(\n rpcConfig: UserRpcProviderConfig,\n timeoutMs: number = 5000\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n if (!rpcConfig.url) {\n return { success: false, error: 'RPC URL is required' };\n }\n\n // Create an AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const startTime = Date.now();\n\n // Use fetch to make a JSON-RPC call to test the connection\n const response = await fetch(rpcConfig.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_blockNumber',\n params: [],\n id: 1,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return { success: false, error: `HTTP error: ${response.status}` };\n }\n\n const data = await response.json();\n const latency = Date.now() - startTime;\n\n if (data.error) {\n return { success: false, error: data.error.message || 'RPC error' };\n }\n\n return { success: true, latency };\n } catch (error) {\n logger.error('testEvmRpcConnection', 'Connection test failed:', error);\n\n // Check if the error was due to timeout\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n success: false,\n error: `Connection timeout after ${timeoutMs}ms`,\n };\n }\n\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection failed',\n };\n } finally {\n // Clear the timeout\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Gets the current block number from an EVM network.\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @returns Promise resolving to the current block number\n * @throws Error if the RPC call fails\n */\nexport async function getEvmCurrentBlock(\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<number> {\n const rpcUrl = resolveRpcUrl(networkConfig);\n\n try {\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_blockNumber',\n params: [],\n id: 1,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`RPC request failed with status ${response.status}`);\n }\n\n const data = await response.json();\n if (data.error) {\n throw new Error(data.error.message || 'RPC error');\n }\n\n // eth_blockNumber returns a hex string\n if (data.result === undefined || data.result === null) {\n throw new Error('RPC response missing result field');\n }\n const blockNumber = parseInt(data.result, 16);\n if (isNaN(blockNumber)) {\n throw new Error(`Invalid block number returned: ${data.result}`);\n }\n return blockNumber;\n } catch (error) {\n logger.error('getEvmCurrentBlock', 'Failed to get current block:', error);\n throw new Error(\n `Failed to get current block: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n","/**\n * EVM Contract Definition Provider keys and ordering\n * Avoid magic strings by using typed constants and a union type.\n */\n\nexport const EvmProviderKeys = {\n Etherscan: 'etherscan',\n Sourcify: 'sourcify',\n} as const;\n\nexport type EvmContractDefinitionProviderKey =\n (typeof EvmProviderKeys)[keyof typeof EvmProviderKeys];\n\nexport const EVM_PROVIDER_ORDER_DEFAULT: readonly EvmContractDefinitionProviderKey[] = [\n EvmProviderKeys.Etherscan,\n EvmProviderKeys.Sourcify,\n] as const;\n\nexport function isEvmProviderKey(value: unknown): value is EvmContractDefinitionProviderKey {\n return value === EvmProviderKeys.Etherscan || value === EvmProviderKeys.Sourcify;\n}\n","/**\n * EVM-specific ABI types for comparison and validation\n * Uses viem's Abi type as the foundation for type safety\n */\n\nimport type { Abi } from 'viem';\n\n/**\n * Result of comparing two ABIs\n */\nexport interface AbiComparisonResult {\n /** Whether the ABIs are identical after normalization */\n identical: boolean;\n /** List of differences found between the ABIs */\n differences: AbiDifference[];\n /** Overall severity of the changes */\n severity: 'none' | 'minor' | 'major' | 'breaking';\n /** Human-readable summary of the comparison */\n summary: string;\n}\n\n/**\n * Represents a single difference between two ABIs\n */\nexport interface AbiDifference {\n /** Type of change */\n type: 'added' | 'removed' | 'modified';\n /** Which section of the ABI was affected */\n section: 'function' | 'event' | 'constructor' | 'error' | 'fallback' | 'receive';\n /** Name of the affected item (or type if no name) */\n name: string;\n /** Detailed description of the change */\n details: string;\n /** Impact level of this change */\n impact: 'low' | 'medium' | 'high';\n /** Signature before the change (for removed/modified) */\n oldSignature?: string;\n /** Signature after the change (for added/modified) */\n newSignature?: string;\n}\n\n/**\n * Result of validating an ABI structure\n */\nexport interface AbiValidationResult {\n /** Whether the ABI is structurally valid */\n valid: boolean;\n /** List of validation errors found */\n errors: string[];\n /** List of validation warnings */\n warnings: string[];\n /** Normalized ABI if validation passed */\n normalizedAbi?: Abi;\n}\n\n/**\n * Type guard to check if a value is a valid ABI array\n */\nexport function isValidAbiArray(value: unknown): value is Abi {\n return Array.isArray(value) && value.every(isValidAbiItem);\n}\n\n/**\n * Type guard to check if a value is a valid ABI item\n */\nexport function isValidAbiItem(item: unknown): boolean {\n if (typeof item !== 'object' || item === null) {\n return false;\n }\n\n const abiItem = item as Record<string, unknown>;\n\n // Must have a valid type\n if (typeof abiItem.type !== 'string') {\n return false;\n }\n\n const validTypes = ['function', 'event', 'constructor', 'error', 'fallback', 'receive'];\n if (!validTypes.includes(abiItem.type)) {\n return false;\n }\n\n // Functions and events must have a name\n if (\n (abiItem.type === 'function' || abiItem.type === 'event') &&\n typeof abiItem.name !== 'string'\n ) {\n return false;\n }\n\n // Functions, events, and constructors should have inputs array\n if (\n (abiItem.type === 'function' || abiItem.type === 'event' || abiItem.type === 'constructor') &&\n abiItem.inputs !== undefined &&\n !Array.isArray(abiItem.inputs)\n ) {\n return false;\n }\n\n return true;\n}\n","/**\n * ABI comparison service for EVM contracts\n * Provides detailed analysis of differences between ABIs\n */\n\nimport type { Abi } from 'viem';\n\nimport { logger, simpleHash } from '@openzeppelin/ui-utils';\n\nimport type { AbiComparisonResult, AbiDifference, AbiValidationResult } from './types';\nimport { isValidAbiArray } from './types';\n\n/**\n * Service for comparing and validating EVM ABIs\n */\nexport class AbiComparisonService {\n /**\n * Compares two ABIs and returns detailed difference analysis\n */\n public compareAbis(abi1: string, abi2: string): AbiComparisonResult {\n try {\n const validation1 = this.validateAbi(abi1);\n const validation2 = this.validateAbi(abi2);\n\n if (!validation1.valid || !validation2.valid) {\n return {\n identical: false,\n differences: [],\n severity: 'breaking',\n summary: 'One or both ABIs are invalid and cannot be compared',\n };\n }\n\n const normalized1 = this.normalizeAbi(validation1.normalizedAbi!);\n const normalized2 = this.normalizeAbi(validation2.normalizedAbi!);\n\n const hash1 = simpleHash(JSON.stringify(normalized1));\n const hash2 = simpleHash(JSON.stringify(normalized2));\n\n if (hash1 === hash2) {\n return {\n identical: true,\n differences: [],\n severity: 'none',\n summary: 'ABIs are identical',\n };\n }\n\n const differences = this.findDifferences(normalized1, normalized2);\n const severity = this.calculateSeverity(differences);\n\n return {\n identical: false,\n differences,\n severity,\n summary: this.generateSummary(differences),\n };\n } catch (error) {\n logger.error('ABI comparison failed:', (error as Error).message);\n return {\n identical: false,\n differences: [],\n severity: 'breaking',\n summary: `Comparison failed: ${(error as Error).message}`,\n };\n }\n }\n\n /**\n * Validates ABI structure and format\n */\n public validateAbi(abiString: string): AbiValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n try {\n // Parse JSON\n const abi = JSON.parse(abiString);\n\n if (!Array.isArray(abi)) {\n errors.push('ABI must be an array');\n return { valid: false, errors, warnings };\n }\n\n // Empty ABI arrays are not valid contract definitions\n if (abi.length === 0) {\n errors.push(\n 'ABI array cannot be empty - contract must have at least one function, event, or constructor'\n );\n return { valid: false, errors, warnings };\n }\n\n // Validate each ABI item\n for (let i = 0; i < abi.length; i++) {\n const item = abi[i];\n\n if (!item.type) {\n errors.push(`Item ${i}: Missing 'type' field`);\n continue;\n }\n\n if (\n !['function', 'event', 'constructor', 'error', 'fallback', 'receive'].includes(item.type)\n ) {\n errors.push(`Item ${i}: Invalid type '${item.type}'`);\n }\n\n if (item.type === 'function' && !item.name) {\n errors.push(`Item ${i}: Function missing 'name' field`);\n }\n\n if ((item.type === 'function' || item.type === 'event') && !Array.isArray(item.inputs)) {\n errors.push(`Item ${i}: Missing or invalid 'inputs' array`);\n }\n\n if (item.type === 'function' && !Array.isArray(item.outputs)) {\n warnings.push(`Item ${i}: Function missing 'outputs' array`);\n }\n }\n\n // Additional viem-specific validation\n if (errors.length === 0 && !isValidAbiArray(abi)) {\n errors.push('ABI does not conform to expected format');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n normalizedAbi: errors.length === 0 ? (abi as Abi) : undefined,\n };\n } catch (parseError) {\n errors.push(`Invalid JSON: ${(parseError as Error).message}`);\n return { valid: false, errors, warnings };\n }\n }\n\n /**\n * Creates deterministic hash of ABI for quick comparison\n */\n public hashAbi(abiString: string): string {\n try {\n const validation = this.validateAbi(abiString);\n if (!validation.valid || !validation.normalizedAbi) {\n throw new Error('Cannot hash invalid ABI');\n }\n\n const normalized = this.normalizeAbi(validation.normalizedAbi);\n const normalizedString = JSON.stringify(normalized);\n\n return simpleHash(normalizedString);\n } catch (error) {\n logger.error('ABI hashing failed:', (error as Error).message);\n throw new Error(`Failed to hash ABI: ${(error as Error).message}`);\n }\n }\n\n /**\n * Normalizes ABI for consistent comparison\n */\n private normalizeAbi(abi: Abi): Abi {\n return abi\n .map((item) => {\n // Remove ordering-dependent fields and sort inputs/outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalized: any = { ...item };\n\n if (normalized.inputs) {\n normalized.inputs = [...normalized.inputs].sort((a, b) =>\n (a.name || '').localeCompare(b.name || '')\n );\n }\n\n if (normalized.outputs) {\n normalized.outputs = [...normalized.outputs].sort((a, b) =>\n (a.name || '').localeCompare(b.name || '')\n );\n }\n\n return normalized;\n })\n .sort((a, b) => {\n // Sort by type first, then by name\n const typeOrder = {\n constructor: 0,\n fallback: 1,\n receive: 2,\n function: 3,\n event: 4,\n error: 5,\n };\n const aOrder = typeOrder[a.type as keyof typeof typeOrder] ?? 99;\n const bOrder = typeOrder[b.type as keyof typeof typeOrder] ?? 99;\n\n if (aOrder !== bOrder) return aOrder - bOrder;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const aName = (a as any).name || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bName = (b as any).name || '';\n return aName.localeCompare(bName);\n }) as Abi;\n }\n\n /**\n * Finds detailed differences between two normalized ABIs\n */\n private findDifferences(abi1: Abi, abi2: Abi): AbiDifference[] {\n const differences: AbiDifference[] = [];\n\n // Create maps for efficient lookup\n const map1 = this.createAbiMap(abi1);\n const map2 = this.createAbiMap(abi2);\n\n // Find removed items\n for (const [key, item] of map1) {\n if (!map2.has(key)) {\n differences.push({\n type: 'removed',\n section: item.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item as any).name || item.type,\n details: `${item.type} was removed`,\n impact: this.calculateImpact(item.type, 'removed'),\n oldSignature: this.generateSignature(item),\n });\n }\n }\n\n // Find added items\n for (const [key, item] of map2) {\n if (!map1.has(key)) {\n differences.push({\n type: 'added',\n section: item.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item as any).name || item.type,\n details: `${item.type} was added`,\n impact: this.calculateImpact(item.type, 'added'),\n newSignature: this.generateSignature(item),\n });\n }\n }\n\n // Find modified items\n for (const [key, item1] of map1) {\n const item2 = map2.get(key);\n if (item2 && !this.itemsEqual(item1, item2)) {\n differences.push({\n type: 'modified',\n section: item1.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item1 as any).name || item1.type,\n details: `${item1.type} signature changed`,\n impact: this.calculateImpact(item1.type, 'modified'),\n oldSignature: this.generateSignature(item1),\n newSignature: this.generateSignature(item2),\n });\n }\n }\n\n return differences;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private createAbiMap(abi: Abi): Map<string, any> {\n const map = new Map();\n\n for (const item of abi) {\n const key = this.generateItemKey(item);\n map.set(key, item);\n }\n\n return map;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private generateItemKey(item: any): string {\n if (item.type === 'constructor' || item.type === 'fallback' || item.type === 'receive') {\n return item.type;\n }\n\n const name = item.name || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const inputs = item.inputs?.map((input: any) => input.type).join(',') || '';\n return `${item.type}:${name}(${inputs})`;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private generateSignature(item: any): string {\n if (item.type === 'constructor') {\n const inputs =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n item.inputs?.map((input: any) => `${input.type} ${input.name || ''}`).join(', ') || '';\n return `constructor(${inputs})`;\n }\n\n if (item.type === 'fallback' || item.type === 'receive') {\n return item.type + '()';\n }\n\n if (item.type === 'function') {\n const inputs =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n item.inputs?.map((input: any) => `${input.type} ${input.name || ''}`).join(', ') || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const outputs = item.outputs?.map((output: any) => output.type).join(', ') || '';\n const mutability = item.stateMutability ? ` ${item.stateMutability}` : '';\n return `function ${item.name}(${inputs})${mutability}${outputs ? ` returns (${outputs})` : ''}`;\n }\n\n if (item.type === 'event') {\n const inputs =\n item.inputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ?.map((input: any) => {\n const indexed = input.indexed ? ' indexed' : '';\n return `${input.type}${indexed} ${input.name || ''}`;\n })\n .join(', ') || '';\n return `event ${item.name}(${inputs})`;\n }\n\n return JSON.stringify(item);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private itemsEqual(item1: any, item2: any): boolean {\n return JSON.stringify(item1) === JSON.stringify(item2);\n }\n\n private calculateImpact(\n type: string,\n changeType: 'added' | 'removed' | 'modified'\n ): 'low' | 'medium' | 'high' {\n if (type === 'constructor' || type === 'fallback' || type === 'receive') {\n return changeType === 'modified' ? 'high' : 'medium';\n }\n\n if (type === 'function') {\n if (changeType === 'removed') return 'high'; // Breaking: removes functionality\n if (changeType === 'modified') return 'medium'; // Major: changes behavior\n if (changeType === 'added') return 'low'; // Minor: adds functionality\n }\n\n if (type === 'event') {\n return 'low'; // Events don't break existing functionality\n }\n\n if (type === 'error') {\n return 'low'; // Custom errors don't break existing functionality\n }\n\n return 'medium';\n }\n\n private calculateSeverity(differences: AbiDifference[]): 'none' | 'minor' | 'major' | 'breaking' {\n if (differences.length === 0) return 'none';\n\n const hasHighImpact = differences.some((d) => d.impact === 'high');\n const hasMediumImpact = differences.some((d) => d.impact === 'medium');\n const hasRemovedFunctions = differences.some(\n (d) => d.type === 'removed' && d.section === 'function'\n );\n\n if (hasRemovedFunctions || hasHighImpact) return 'breaking';\n if (hasMediumImpact) return 'major';\n return 'minor';\n }\n\n private generateSummary(differences: AbiDifference[]): string {\n const counts = {\n added: differences.filter((d) => d.type === 'added').length,\n removed: differences.filter((d) => d.type === 'removed').length,\n modified: differences.filter((d) => d.type === 'modified').length,\n };\n\n const parts: string[] = [];\n if (counts.added > 0) parts.push(`${counts.added} added`);\n if (counts.removed > 0) parts.push(`${counts.removed} removed`);\n if (counts.modified > 0) parts.push(`${counts.modified} modified`);\n\n const summary = parts.join(', ');\n return `${summary}`;\n }\n}\n\n// Export singleton instance\nexport const abiComparisonService = new AbiComparisonService();\n\n// ============================================================================\n// Convenience Wrapper Functions\n// ============================================================================\n\n/**\n * Compare two contract definitions (ABI strings).\n * Convenience wrapper around abiComparisonService.compareAbis().\n *\n * @param storedSchema - The stored/original ABI JSON string\n * @param freshSchema - The new/fresh ABI JSON string to compare against\n * @returns Comparison result with differences and severity\n *\n * @example\n * ```typescript\n * const result = await compareContractDefinitions(oldAbi, newAbi);\n * if (!result.identical) {\n * console.log(`Changes detected: ${result.summary}`);\n * console.log(`Severity: ${result.severity}`);\n * }\n * ```\n */\nexport async function compareContractDefinitions(\n storedSchema: string,\n freshSchema: string\n): Promise<AbiComparisonResult> {\n return abiComparisonService.compareAbis(storedSchema, freshSchema);\n}\n\n/**\n * Validate a contract definition (ABI string).\n * Convenience wrapper around abiComparisonService.validateAbi().\n *\n * @param definition - The ABI JSON string to validate\n * @returns Validation result with errors and warnings\n *\n * @example\n * ```typescript\n * const result = validateContractDefinition(abiJson);\n * if (!result.valid) {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateContractDefinition(definition: string): AbiValidationResult {\n return abiComparisonService.validateAbi(definition);\n}\n\n/**\n * Hash a contract definition (ABI string) for comparison.\n * Convenience wrapper around abiComparisonService.hashAbi().\n *\n * @param definition - The ABI JSON string to hash\n * @returns Deterministic hash of the normalized ABI\n *\n * @example\n * ```typescript\n * const hash1 = hashContractDefinition(abi1);\n * const hash2 = hashContractDefinition(abi2);\n * if (hash1 === hash2) {\n * console.log('ABIs are identical');\n * }\n * ```\n */\nexport function hashContractDefinition(definition: string): string {\n return abiComparisonService.hashAbi(definition);\n}\n","import type { FieldType, TypeMappingInfo } from '@openzeppelin/ui-types';\n\n/**\n * EVM-specific type mapping to default form field types.\n *\n * Note: Large integer types (uint128, uint256, int128, int256) are mapped to 'bigint'\n * instead of 'number' to avoid JavaScript's Number precision limitations.\n * JavaScript's Number type can only safely represent integers up to 2^53 - 1,\n * but these types can hold much larger values. The BigIntField component stores values\n * as strings and the EVM adapter handles BigInt conversion automatically.\n */\nexport const EVM_TYPE_TO_FIELD_TYPE: Record<string, FieldType> = {\n address: 'blockchain-address',\n string: 'text',\n uint: 'number',\n uint8: 'number',\n uint16: 'number',\n uint32: 'number',\n uint64: 'bigint',\n uint128: 'bigint',\n uint256: 'bigint',\n int: 'number',\n int8: 'number',\n int16: 'number',\n int32: 'number',\n int64: 'bigint',\n int128: 'bigint',\n int256: 'bigint',\n bool: 'checkbox',\n bytes: 'bytes',\n bytes32: 'bytes',\n};\n\n/**\n * EVM dynamic type patterns handled through pattern matching.\n */\nconst EVM_DYNAMIC_PATTERNS: TypeMappingInfo['dynamicPatterns'] = [\n { name: 'array', syntax: 'T[]', mapsTo: 'array', description: 'Dynamic array of primitives' },\n { name: 'fixed-array', syntax: 'T[N]', mapsTo: 'array', description: 'Fixed-size array' },\n {\n name: 'tuple-array',\n syntax: 'tuple[]',\n mapsTo: 'array-object',\n description: 'Array of structs',\n },\n { name: 'tuple', syntax: 'tuple', mapsTo: 'object', description: 'Struct/tuple type' },\n];\n\n/**\n * Returns complete type mapping information for EVM.\n */\nexport function getEvmTypeMappingInfo(): TypeMappingInfo {\n return {\n primitives: { ...EVM_TYPE_TO_FIELD_TYPE },\n dynamicPatterns: EVM_DYNAMIC_PATTERNS,\n };\n}\n","import type { FieldType } from '@openzeppelin/ui-types';\n\nimport { EVM_TYPE_TO_FIELD_TYPE } from './constants';\n\n/**\n * Map a blockchain-specific parameter type to a default form field type.\n * @param parameterType The blockchain parameter type (e.g., 'uint256', 'address', 'tuple')\n * @returns The appropriate default form field type (e.g., 'number', 'blockchain-address', 'object')\n */\nexport function mapEvmParamTypeToFieldType(parameterType: string): FieldType {\n // Check if this is an array of tuples/objects\n if (parameterType.match(/^tuple\\[\\d*\\]$/)) {\n return 'array-object';\n }\n\n // Check if this is an array type (ends with [] or [number])\n if (parameterType.match(/\\[\\d*\\]$/)) {\n return 'array';\n }\n\n // Extract the base type from array types (e.g., uint256[] -> uint256)\n const baseType = parameterType.replace(/\\[\\d*\\]/g, '');\n\n // Handle tuples (structs) - use object for composite types\n if (baseType.startsWith('tuple')) {\n return 'object';\n }\n\n // Handle all bytesN types (bytes1-bytes32) - map to 'bytes' field for proper hex validation\n if (baseType.match(/^bytes\\d+$/)) {\n return 'bytes';\n }\n\n // Map common EVM types to appropriate field types\n return EVM_TYPE_TO_FIELD_TYPE[baseType] || 'text'; // Default to 'text'\n}\n\n/**\n * Get field types compatible with a specific parameter type.\n * @param parameterType The blockchain parameter type.\n * @returns Array of compatible form field types.\n */\nexport function getEvmCompatibleFieldTypes(parameterType: string): FieldType[] {\n // Handle array of objects\n if (parameterType.match(/^tuple\\[\\d*\\]$/)) {\n return ['array-object', 'textarea', 'text'];\n }\n\n // Handle array types - allow array field or fallback to textarea/text\n if (parameterType.match(/\\[\\d*\\]$/)) {\n return ['array', 'textarea', 'text'];\n }\n\n const baseType = parameterType.replace(/\\[\\d*\\]/g, '');\n\n // Handle tuples/objects\n if (baseType.startsWith('tuple')) {\n return ['object', 'textarea', 'text'];\n }\n\n // Define compatibility map for base types\n const compatibilityMap: Record<string, FieldType[]> = {\n address: ['blockchain-address', 'text'],\n uint: ['number', 'amount', 'text'],\n uint8: ['number', 'amount', 'text'],\n uint16: ['number', 'amount', 'text'],\n uint32: ['number', 'amount', 'text'],\n uint64: ['bigint', 'number', 'amount', 'text'],\n uint128: ['bigint', 'number', 'amount', 'text'],\n uint256: ['bigint', 'number', 'amount', 'text'],\n int: ['number', 'text'],\n int8: ['number', 'text'],\n int16: ['number', 'text'],\n int32: ['number', 'text'],\n int64: ['bigint', 'number', 'text'],\n int128: ['bigint', 'number', 'text'],\n int256: ['bigint', 'number', 'text'],\n bool: ['checkbox', 'select', 'radio', 'text'],\n string: ['text', 'textarea', 'email', 'password'],\n bytes: ['bytes', 'textarea', 'text'],\n bytes32: ['bytes', 'textarea', 'text'],\n };\n\n // Handle all bytesN types (bytes1-bytes32) - allow 'bytes' field for proper hex validation\n if (baseType.match(/^bytes\\d+$/)) {\n return ['bytes', 'textarea', 'text'];\n }\n\n return compatibilityMap[baseType] || ['text']; // Default to 'text'\n}\n","import { startCase } from 'lodash';\n\nimport type {\n FieldType,\n FieldValidation,\n FieldValue,\n FormFieldType,\n FunctionParameter,\n} from '@openzeppelin/ui-types';\nimport {\n enhanceNumericValidation,\n getDefaultValueForType,\n type NumericBoundsMap,\n} from '@openzeppelin/ui-utils';\n\nimport { mapEvmParamTypeToFieldType } from './type-mapper';\n\n/**\n * Extracts the byte size from a fixed-size bytes type (e.g., bytes32 -> 32)\n * @param parameterType - The parameter type (e.g., 'bytes32', 'bytes4', 'bytes')\n * @returns The byte size if fixed-size, undefined if dynamic\n */\nfunction extractBytesSize(parameterType: string): number | undefined {\n const match = parameterType.match(/^bytes(\\d+)$/);\n if (match) {\n return Number.parseInt(match[1], 10);\n }\n return undefined;\n}\n\n/**\n * Extracts the inner type from an EVM array type.\n * @param parameterType - The parameter type (e.g., 'uint32[]', 'address[]')\n * @returns The inner type (e.g., 'uint32', 'address') or null if not an array type\n */\nfunction extractArrayElementType(parameterType: string): string | null {\n // Handle array types like uint32[], address[], bytes32[]\n const arrayMatch = parameterType.match(/^(.+)\\[\\d*\\]$/);\n if (arrayMatch) {\n return arrayMatch[1];\n }\n return null;\n}\n\n/**\n * Get default validation rules for a parameter.\n * Field-specific validation is handled by the field components themselves.\n */\nfunction getDefaultValidation(): FieldValidation {\n return { required: true };\n}\n\n/**\n * EVM numeric type bounds.\n * Maps EVM type names to their min/max value constraints.\n * Note: uint64, uint128, uint256, int64, int128, int256 exceed JavaScript's Number.MAX_SAFE_INTEGER\n * and are handled via BigInt fields, so bounds are not applied here.\n */\nconst EVM_NUMERIC_BOUNDS: NumericBoundsMap = {\n uint: { min: 0 },\n uint8: { min: 0, max: 255 },\n uint16: { min: 0, max: 65_535 },\n uint32: { min: 0, max: 4_294_967_295 },\n int: {},\n int8: { min: -128, max: 127 },\n int16: { min: -32_768, max: 32_767 },\n int32: { min: -2_147_483_648, max: 2_147_483_647 },\n};\n\n/**\n * Generate default field configuration for an EVM function parameter.\n */\nexport function generateEvmDefaultField<T extends FieldType = FieldType>(\n parameter: FunctionParameter\n): FormFieldType<T> {\n const fieldType = mapEvmParamTypeToFieldType(parameter.type) as T;\n\n const baseField: FormFieldType<T> = {\n id: `field-${Math.random().toString(36).substring(2, 9)}`,\n name: parameter.name || parameter.type, // Use type if name missing\n label: startCase(parameter.displayName || parameter.name || parameter.type),\n type: fieldType,\n placeholder: `Enter ${parameter.displayName || parameter.name || parameter.type}`,\n helperText: parameter.description || '',\n defaultValue: getDefaultValueForType(fieldType) as FieldValue<T>,\n validation: enhanceNumericValidation(\n getDefaultValidation(),\n parameter.type,\n EVM_NUMERIC_BOUNDS\n ),\n width: 'full',\n };\n\n // Add exactBytes metadata for fixed-size bytes types (bytes1, bytes4, bytes32, etc.)\n const bytesSize = extractBytesSize(parameter.type);\n if (bytesSize !== undefined) {\n baseField.metadata = {\n ...(baseField.metadata ?? {}),\n exactBytes: bytesSize,\n };\n }\n\n // For array types, provide element type information\n if (fieldType === 'array') {\n const elementType = extractArrayElementType(parameter.type);\n if (elementType) {\n const elementFieldType = mapEvmParamTypeToFieldType(elementType);\n\n // Check if element type is a fixed-size bytes type\n const elementBytesSize = extractBytesSize(elementType);\n\n // Add array-specific properties\n const arrayField = {\n ...baseField,\n elementType: elementFieldType,\n elementFieldConfig: {\n type: elementFieldType,\n validation: enhanceNumericValidation(\n getDefaultValidation(),\n elementType,\n EVM_NUMERIC_BOUNDS\n ),\n placeholder: `Enter ${elementType}`,\n // Include exactBytes metadata for fixed-size bytes array elements (e.g., bytes32[])\n ...(elementBytesSize !== undefined && {\n metadata: { exactBytes: elementBytesSize },\n }),\n },\n };\n return arrayField;\n }\n }\n\n // Preserve components for object and array-object types\n if (parameter.components && (fieldType === 'object' || fieldType === 'array-object')) {\n const result = {\n ...baseField,\n components: parameter.components,\n };\n return result;\n }\n\n return baseField;\n}\n","import { getAddress, isAddress } from 'viem';\n\nimport type { FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Recursively parses a raw input value based on its expected ABI type definition.\n *\n * @param param The ABI parameter definition ({ name, type, components?, ... })\n * @param rawValue The raw value obtained from the form input or hardcoded config.\n * @param isRecursive Internal flag to indicate if the call is nested.\n * @returns The parsed and typed value suitable for ABI encoding.\n * @throws {Error} If parsing or type validation fails.\n */\nexport function parseEvmInput(\n param: FunctionParameter,\n rawValue: unknown,\n isRecursive = false\n): unknown {\n const { type, name } = param;\n const baseType = type.replace(/\\[\\d*\\]$/, ''); // Remove array indicators like `[]` or `[2]`\n const isArray = type.endsWith(']');\n\n try {\n // --- Handle Arrays --- //\n if (isArray) {\n // Only expect string at the top level, recursive calls get arrays directly\n let parsedArray: unknown[];\n if (!isRecursive) {\n if (typeof rawValue !== 'string') {\n throw new Error('Array input must be a JSON string representation.');\n }\n try {\n parsedArray = JSON.parse(rawValue);\n } catch (e) {\n throw new Error(`Invalid JSON for array: ${(e as Error).message}`);\n }\n } else {\n // If recursive, rawValue should already be an array\n if (!Array.isArray(rawValue)) {\n throw new Error('Internal error: Expected array in recursive call.');\n }\n parsedArray = rawValue;\n }\n\n if (!Array.isArray(parsedArray)) {\n // Double check after parsing/assignment\n throw new Error('Parsed JSON is not an array.');\n }\n\n // Recursively parse each element\n const itemAbiParam = { ...param, type: baseType }; // Create a dummy param for the base type\n return parsedArray.map((item) => parseEvmInput(itemAbiParam, item, true)); // Pass isRecursive=true\n }\n\n // --- Handle Tuples --- //\n if (baseType === 'tuple') {\n if (!param.components) {\n throw new Error(`ABI definition missing 'components' for tuple parameter '${name}'.`);\n }\n // Only expect string at the top level, recursive calls get objects directly\n let parsedObject: Record<string, unknown>;\n if (!isRecursive) {\n if (typeof rawValue !== 'string') {\n throw new Error('Tuple input must be a JSON string representation of an object.');\n }\n try {\n parsedObject = JSON.parse(rawValue);\n } catch (e) {\n throw new Error(`Invalid JSON for tuple: ${(e as Error).message}`);\n }\n } else {\n // If recursive, rawValue should already be an object\n if (typeof rawValue !== 'object' || rawValue === null || Array.isArray(rawValue)) {\n throw new Error('Internal error: Expected object in recursive tuple call.');\n }\n parsedObject = rawValue as Record<string, unknown>; // Cast needed\n }\n\n if (\n typeof parsedObject !== 'object' ||\n parsedObject === null ||\n Array.isArray(parsedObject)\n ) {\n // Double check\n throw new Error('Parsed JSON is not an object for tuple.');\n }\n\n // Recursively parse each component\n const resultObject: Record<string, unknown> = {};\n for (const component of param.components) {\n if (!(component.name in parsedObject)) {\n throw new Error(`Missing component '${component.name}' in tuple JSON.`);\n }\n resultObject[component.name] = parseEvmInput(\n component,\n parsedObject[component.name],\n true // Pass isRecursive=true\n );\n }\n // Check for extra, unexpected keys in the provided JSON object\n if (Object.keys(parsedObject).length !== param.components.length) {\n const expectedKeys = param.components.map((c) => c.name).join(', ');\n const actualKeys = Object.keys(parsedObject).join(', ');\n throw new Error(\n `Tuple object has incorrect number of keys. Expected ${param.components.length} (${expectedKeys}), but got ${Object.keys(parsedObject).length} (${actualKeys}).`\n );\n }\n return resultObject;\n }\n\n // --- Handle Bytes --- //\n if (baseType.startsWith('bytes')) {\n if (typeof rawValue !== 'string') {\n throw new Error('Bytes input must be a string.');\n }\n if (!/^0x([0-9a-fA-F]{2})*$/.test(rawValue)) {\n throw new Error(\n `Invalid hex string format for ${type}: must start with 0x and contain only hex characters.`\n );\n }\n // Check byte length for fixed-size bytes? (e.g., bytes32)\n const fixedSizeMatch = baseType.match(/^bytes(\\d+)$/);\n if (fixedSizeMatch) {\n const expectedBytes = parseInt(fixedSizeMatch[1], 10);\n const actualBytes = (rawValue.length - 2) / 2;\n if (actualBytes !== expectedBytes) {\n throw new Error(\n `Invalid length for ${type}: expected ${expectedBytes} bytes (${expectedBytes * 2} hex chars), got ${actualBytes} bytes.`\n );\n }\n }\n return rawValue as `0x${string}`; // Already validated, cast to viem type\n }\n\n // --- Handle Simple Types --- //\n if (baseType.startsWith('uint') || baseType.startsWith('int')) {\n if (rawValue === '' || rawValue === null || rawValue === undefined)\n throw new Error('Numeric value cannot be empty.');\n try {\n // Use BigInt for all integer types\n return BigInt(rawValue as string | number | bigint);\n } catch {\n throw new Error(`Invalid numeric value: '${rawValue}'.`);\n }\n } else if (baseType === 'address') {\n if (typeof rawValue !== 'string' || !rawValue)\n throw new Error('Address value must be a non-empty string.');\n if (!isAddress(rawValue)) throw new Error(`Invalid address format: '${rawValue}'.`);\n return getAddress(rawValue); // Return checksummed address\n } else if (baseType === 'bool') {\n if (typeof rawValue === 'boolean') return rawValue;\n if (typeof rawValue === 'string') {\n const lowerVal = rawValue.toLowerCase().trim();\n if (lowerVal === 'true') return true;\n if (lowerVal === 'false') return false;\n }\n // Try simple truthy/falsy conversion as fallback\n return Boolean(rawValue);\n } else if (baseType === 'string') {\n // Ensure it's treated as a string\n return String(rawValue);\n }\n\n // --- Fallback for unknown types --- //\n logger.warn(\n 'parseEvmInput',\n `Unknown EVM parameter type encountered: '${type}'. Using raw value.`\n );\n return rawValue;\n } catch (error) {\n // Add parameter context to the error message\n throw new Error(\n `Failed to parse value for parameter '${name || '(unnamed)'}' (type '${type}'): ${(error as Error).message}`\n );\n }\n}\n","import type { ContractFunction } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { stringifyWithBigInt } from '../utils';\n\n/**\n * Formats the decoded result of an EVM view function call into a user-friendly string.\n *\n * @param decodedValue The decoded value (can be primitive, array, object, BigInt).\n * @param functionDetails The ABI details of the function called.\n * @returns A string representation suitable for display.\n */\nexport function formatEvmFunctionResult(\n decodedValue: unknown,\n functionDetails: ContractFunction\n): string {\n if (!functionDetails.outputs || !Array.isArray(functionDetails.outputs)) {\n logger.warn(\n 'formatEvmFunctionResult',\n `Output ABI definition missing or invalid for function ${functionDetails.name}.`\n );\n return '[Error: Output ABI definition missing]';\n }\n\n try {\n let valueToFormat: unknown;\n // Handle potential array wrapping for single returns from viem\n if (Array.isArray(decodedValue)) {\n if (decodedValue.length === 1) {\n valueToFormat = decodedValue[0]; // Single output, format the inner value\n } else {\n // Multiple outputs, format the whole array as JSON\n valueToFormat = decodedValue;\n }\n } else {\n // Not an array, could be a single value (like from a struct return) or undefined\n valueToFormat = decodedValue;\n }\n\n // Format based on type\n if (typeof valueToFormat === 'bigint') {\n return valueToFormat.toString();\n } else if (\n typeof valueToFormat === 'string' ||\n typeof valueToFormat === 'number' ||\n typeof valueToFormat === 'boolean'\n ) {\n return String(valueToFormat);\n } else if (valueToFormat === null || valueToFormat === undefined) {\n return '(null)'; // Represent null/undefined clearly\n } else {\n // Handles arrays with multiple elements or objects (structs) by stringifying\n return stringifyWithBigInt(valueToFormat, 2); // Pretty print with 2 spaces\n }\n } catch (error) {\n const errorMessage = `Error formatting result for ${functionDetails.name}: ${(error as Error).message}`;\n logger.error('formatEvmFunctionResult', errorMessage, {\n functionName: functionDetails.name,\n decodedValue,\n error,\n });\n return `[${errorMessage}]`;\n }\n}\n","import { createPublicClient, http, isAddress, type Chain } from 'viem';\n\nimport type { ContractSchema, FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createAbiFunctionItem } from '../abi/transformer';\nimport { parseEvmInput } from '../transform/input-parser';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { isEvmViewFunction } from './view-checker';\n\n/**\n * Helper to create a public client with a specific RPC URL\n */\nfunction createPublicClientWithRpc(networkConfig: EvmCompatibleNetworkConfig, rpcUrl: string) {\n let chainForViem: Chain;\n if (networkConfig.viemChain) {\n chainForViem = networkConfig.viemChain;\n } else {\n logger.warn(\n 'createPublicClientWithRpc',\n `Viem chain object (viemChain) not provided in EvmNetworkConfig for ${networkConfig.name} (query). Creating a minimal one.`\n );\n if (!networkConfig.rpcUrl) {\n throw new Error(\n `RPC URL is missing in networkConfig for ${networkConfig.name} and viemChain is not set for query client.`\n );\n }\n chainForViem = {\n id: networkConfig.chainId,\n name: networkConfig.name,\n nativeCurrency: networkConfig.nativeCurrency,\n rpcUrls: {\n default: { http: [networkConfig.rpcUrl] },\n public: { http: [networkConfig.rpcUrl] },\n },\n blockExplorers: networkConfig.explorerUrl\n ? { default: { name: `${networkConfig.name} Explorer`, url: networkConfig.explorerUrl } }\n : undefined,\n };\n }\n\n try {\n const publicClient = createPublicClient({\n chain: chainForViem,\n transport: http(rpcUrl),\n });\n return publicClient;\n } catch (error) {\n logger.error(\n 'createPublicClientWithRpc',\n 'Failed to create network-specific public client for query:',\n error\n );\n throw new Error(\n `Failed to create network-specific public client for query: ${(error as Error).message}`\n );\n }\n}\n\n/**\n * Core logic for querying an EVM view function.\n * This is a stateless version that accepts an RPC URL directly.\n *\n * @param contractAddress - Address of the contract.\n * @param functionId - ID of the function to query.\n * @param params - Raw parameters for the function call.\n * @param schema - Contract schema with function definitions.\n * @param rpcUrl - RPC URL to use for the query.\n * @param networkConfig - Optional EVM-compatible network configuration for chain metadata (works with any ecosystem).\n * @returns The decoded result of the view function call.\n */\nexport async function queryEvmViewFunction(\n contractAddress: string,\n functionId: string,\n params: unknown[],\n schema: ContractSchema,\n rpcUrl: string,\n networkConfig?: EvmCompatibleNetworkConfig\n): Promise<unknown> {\n logger.info(\n 'queryEvmViewFunction',\n `Querying view function: ${functionId} on ${contractAddress}`,\n { params }\n );\n\n try {\n // --- Validate Address --- //\n if (!contractAddress || !isAddress(contractAddress)) {\n throw new Error(`Invalid contract address provided: ${contractAddress}`);\n }\n\n // --- Get Function Details --- //\n const functionDetails = schema.functions.find((fn) => fn.id === functionId);\n if (!functionDetails) {\n throw new Error(`Function with ID ${functionId} not found in contract schema.`);\n }\n if (!isEvmViewFunction(functionDetails)) {\n throw new Error(`Function ${functionDetails.name} is not a view function.`);\n }\n\n // --- Parse Input Parameters --- //\n const expectedInputs: readonly FunctionParameter[] = functionDetails.inputs;\n if (params.length !== expectedInputs.length) {\n throw new Error(\n `Incorrect number of parameters provided for ${functionDetails.name}. Expected ${expectedInputs.length}, got ${params.length}.`\n );\n }\n const args = expectedInputs.map((inputParam: FunctionParameter, index: number) => {\n let rawValue = params[index];\n // If the ABI parameter type is an array and the incoming raw value is an actual array,\n // stringify it to align with parseEvmInput expectations for top-level arrays.\n if (\n typeof inputParam.type === 'string' &&\n inputParam.type.endsWith('[]') &&\n Array.isArray(rawValue)\n ) {\n rawValue = JSON.stringify(rawValue);\n }\n return parseEvmInput(inputParam, rawValue, false);\n });\n logger.debug('queryEvmViewFunction', 'Parsed Args for readContract:', args);\n\n // --- Create Public Client --- //\n // Create a minimal network config if not provided\n const minimalConfig: EvmCompatibleNetworkConfig = networkConfig || {\n id: 'query-network',\n name: 'Query Network',\n ecosystem: 'evm',\n network: 'unknown',\n type: 'mainnet',\n isTestnet: false,\n chainId: 1, // Default to mainnet chain ID\n rpcUrl: rpcUrl,\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n exportConstName: 'queryNetwork',\n };\n\n const publicClient = createPublicClientWithRpc(minimalConfig, rpcUrl);\n\n // --- Construct ABI Item --- //\n const functionAbiItem = createAbiFunctionItem(functionDetails);\n\n logger.debug(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] Calling readContract with ABI:`,\n functionAbiItem,\n 'Args:',\n args\n );\n\n // --- Call readContract --- //\n let decodedResult: unknown;\n try {\n decodedResult = await publicClient.readContract({\n address: contractAddress as `0x${string}`,\n abi: [functionAbiItem],\n functionName: functionDetails.name,\n args: args,\n });\n } catch (readError) {\n logger.error(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] publicClient.readContract specific error:`,\n readError\n );\n throw new Error(\n `Viem readContract failed for ${functionDetails.name}: ${(readError as Error).message}`\n );\n }\n\n logger.debug(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] Raw decoded result:`,\n decodedResult\n );\n\n return decodedResult;\n } catch (error) {\n const errorMessage = `Failed to query view function ${functionId}: ${(error as Error).message}`;\n logger.error('queryEvmViewFunction', errorMessage, {\n contractAddress,\n functionId,\n params,\n error,\n });\n throw new Error(errorMessage);\n }\n}\n","import type { ContractFunction } from '@openzeppelin/ui-types';\n\n/**\n * Determines if a function is a view/pure function (read-only).\n * @param functionDetails The function details from the contract schema.\n * @returns True if the function is read-only, false otherwise.\n */\nexport function isEvmViewFunction(functionDetails: ContractFunction): boolean {\n return functionDetails.stateMutability === 'view' || functionDetails.stateMutability === 'pure';\n}\n","import { isAddress } from 'viem';\n\nimport type { ContractSchema, FormFieldType } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createAbiFunctionItem } from '../abi/transformer';\nimport { parseEvmInput } from '../transform/input-parser';\nimport type { WriteContractParameters } from '../types/abi';\n\n/**\n * Formats transaction data for EVM chains based on parsed inputs.\n *\n * @param contractSchema The contract schema.\n * @param functionId The ID of the function being called.\n * @param submittedInputs The raw data submitted from the form.\n * @param fields The fields of the form schema.\n * @returns The formatted data payload suitable for signAndBroadcast.\n */\nexport function formatEvmTransactionData(\n contractSchema: ContractSchema,\n functionId: string,\n submittedInputs: Record<string, unknown>,\n fields: FormFieldType[]\n): WriteContractParameters {\n logger.info(\n 'formatEvmTransactionData',\n `Formatting EVM transaction data for function: ${functionId}`\n );\n\n // --- Step 1: Determine Argument Order --- //\n const functionDetails = contractSchema.functions.find((fn) => fn.id === functionId);\n if (!functionDetails) {\n throw new Error(`Function definition for ${functionId} not found in provided contract schema.`);\n }\n const expectedArgs = functionDetails.inputs;\n\n // --- Step 2: Iterate and Select Values --- //\n const orderedRawValues: unknown[] = [];\n for (const expectedArg of expectedArgs) {\n const fieldConfig = fields.find((field: FormFieldType) => field.name === expectedArg.name);\n if (!fieldConfig) {\n throw new Error(`Configuration missing for argument: ${expectedArg.name} in provided fields`);\n }\n let value: unknown;\n if (fieldConfig.isHardcoded) {\n value = fieldConfig.hardcodedValue;\n } else if (fieldConfig.isHidden) {\n throw new Error(`Field '${fieldConfig.name}' cannot be hidden without being hardcoded.`);\n } else {\n if (!(fieldConfig.name in submittedInputs)) {\n throw new Error(`Missing submitted input for required field: ${fieldConfig.name}`);\n }\n value = submittedInputs[fieldConfig.name];\n }\n orderedRawValues.push(value);\n }\n\n // --- Step 3: Parse/Transform Values using the imported parser --- //\n const transformedArgs = expectedArgs.map((param, index) => {\n let valueToParse = orderedRawValues[index];\n\n // If the ABI parameter type is an array (e.g., 'tuple[]', 'address[]') and\n // the raw value from the form/runtime is an array (not already a string),\n // stringify it for parseEvmInput which expects JSON at the top-level.\n if (\n typeof param.type === 'string' &&\n param.type.endsWith('[]') &&\n Array.isArray(valueToParse)\n ) {\n valueToParse = JSON.stringify(valueToParse);\n }\n\n return parseEvmInput(param, valueToParse, false);\n });\n\n // --- Step 4 & 5: Prepare Return Object --- //\n const isPayable = functionDetails.stateMutability === 'payable';\n let transactionValue = 0n; // Use BigInt zero\n if (isPayable) {\n logger.warn(\n 'formatEvmTransactionData',\n 'Payable function detected, but sending 0 ETH. Implement value input.'\n );\n // TODO: Read value from submittedInputs or config when payable input is implemented\n }\n\n const functionAbiItem = createAbiFunctionItem(functionDetails);\n\n if (!contractSchema.address || !isAddress(contractSchema.address)) {\n throw new Error('Contract address is missing or invalid in the provided schema.');\n }\n\n const paramsForSignAndBroadcast: WriteContractParameters = {\n address: contractSchema.address,\n abi: [functionAbiItem],\n functionName: functionDetails.name,\n args: transformedArgs,\n value: transactionValue, // Pass BigInt value\n };\n return paramsForSignAndBroadcast;\n}\n","/**\n * Transaction Module\n *\n * Transaction formatting, execution strategies, and transaction sending for EVM contracts.\n * This module structure mirrors the adapter-evm transaction/ directory.\n *\n * @module transaction\n */\n\n// Formatting\nexport { formatEvmTransactionData } from './formatter';\n\n// Execution strategy interface\nexport type { AdapterExecutionStrategy } from './execution-strategy';\n\n// Execution strategies\nexport { EoaExecutionStrategy } from './eoa';\nexport { RelayerExecutionStrategy, type EvmRelayerTransactionOptions } from './relayer';\n\n// Transaction sending and execution\nexport {\n executeEvmTransaction,\n signAndBroadcastEvmTransaction,\n waitForEvmTransactionConfirmation,\n} from './sender';\n\n// Types\nexport type {\n EvmWalletImplementation,\n EvmWalletConnectionStatus,\n EvmWalletConnectionResult,\n EvmWalletDisconnectResult,\n} from './types';\n","/**\n * Transaction Sender\n *\n * Core functions for signing and broadcasting EVM transactions.\n * These functions work with any wallet implementation that implements EvmWalletImplementation.\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\nimport type { TransactionReceipt, WalletClient } from 'viem';\n\nimport type { ExecutionConfig, TransactionStatusUpdate, TxStatus } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WriteContractParameters } from '../types/abi';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\nconst SYSTEM_LOG_TAG = 'evm-core-sender';\n\n// --- Helper Functions ---\n\nasync function _ensureCorrectNetworkOrSwitch(\n walletImplementation: EvmWalletImplementation,\n targetChainId: number\n): Promise<GetAccountReturnType> {\n const initialAccountStatus = walletImplementation.getWalletConnectionStatus();\n if (!initialAccountStatus.isConnected || !initialAccountStatus.chainId) {\n logger.error(\n SYSTEM_LOG_TAG,\n 'Wallet not connected or chainId unavailable before network check.'\n );\n throw new Error('Wallet not connected or chain ID is unavailable.');\n }\n\n if (initialAccountStatus.chainId !== targetChainId) {\n logger.info(\n SYSTEM_LOG_TAG,\n `Wallet on chain ${initialAccountStatus.chainId}, target ${targetChainId}. Switching...`\n );\n try {\n await walletImplementation.switchNetwork(targetChainId);\n const postSwitchAccountStatus = walletImplementation.getWalletConnectionStatus();\n if (postSwitchAccountStatus.chainId !== targetChainId) {\n logger.error(\n SYSTEM_LOG_TAG,\n `Failed to switch to target chain ${targetChainId}. Current: ${postSwitchAccountStatus.chainId}`\n );\n throw new Error(`Failed to switch to the required network (target: ${targetChainId}).`);\n }\n logger.info(SYSTEM_LOG_TAG, `Successfully switched to target chain ${targetChainId}.`);\n return postSwitchAccountStatus;\n } catch (error) {\n logger.error(SYSTEM_LOG_TAG, 'Network switch failed:', error);\n throw error;\n }\n }\n logger.info(SYSTEM_LOG_TAG, 'Wallet already on target chain.');\n return initialAccountStatus;\n}\n\nasync function _getAuthenticatedWalletClient(\n walletImplementation: EvmWalletImplementation\n): Promise<{\n walletClient: WalletClient;\n accountStatus: GetAccountReturnType;\n}> {\n const walletClient = await walletImplementation.getWalletClient();\n if (!walletClient) {\n logger.error(SYSTEM_LOG_TAG, 'Wallet client not available. Is wallet connected?');\n throw new Error('Wallet is not connected or client is unavailable.');\n }\n\n const accountStatus = walletImplementation.getWalletConnectionStatus();\n if (!accountStatus.isConnected || !accountStatus.address) {\n logger.error(SYSTEM_LOG_TAG, 'Account not available. Is wallet connected?');\n throw new Error('Wallet is not connected or account address is unavailable.');\n }\n return { walletClient, accountStatus };\n}\n\nasync function _executeEoaTransaction(\n transactionData: WriteContractParameters,\n walletClient: WalletClient,\n accountStatus: GetAccountReturnType\n): Promise<{ txHash: string }> {\n logger.info(SYSTEM_LOG_TAG, 'Using EOA execution strategy.');\n try {\n logger.debug(SYSTEM_LOG_TAG, 'Calling walletClient.writeContract with:', {\n account: accountStatus.address,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n const hash = await walletClient.writeContract({\n account: accountStatus.address!,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n logger.info(SYSTEM_LOG_TAG, 'EOA Transaction initiated. Hash:', hash);\n return { txHash: hash };\n } catch (error: unknown) {\n logger.error(SYSTEM_LOG_TAG, 'Error during EOA writeContract call:', error);\n const errorMessage = error instanceof Error ? error.message : 'Unknown EOA transaction error';\n throw new Error(`Transaction failed (EOA): ${errorMessage}`);\n }\n}\n\n// --- Main Exported Functions ---\n\n/**\n * Sign and broadcast an EVM transaction using the provided wallet implementation.\n *\n * This function handles:\n * - Network switching (if wallet is on wrong chain)\n * - Transaction signing via the wallet\n * - Transaction broadcasting\n *\n * @param transactionData - The contract write parameters\n * @param walletImplementation - The wallet implementation to use for signing\n * @param targetChainId - The chain ID to execute the transaction on\n * @param executionConfig - Optional execution configuration (for future method support)\n * @returns The transaction hash\n */\nexport async function signAndBroadcastEvmTransaction(\n transactionData: WriteContractParameters,\n walletImplementation: EvmWalletImplementation,\n targetChainId: number,\n executionConfig?: ExecutionConfig\n): Promise<{ txHash: string }> {\n logger.info(SYSTEM_LOG_TAG, 'Sign & Broadcast EVM Tx:', {\n data: transactionData,\n targetChainId,\n execConfig: executionConfig,\n });\n\n const currentMethod = executionConfig?.method || 'eoa';\n\n await _ensureCorrectNetworkOrSwitch(walletImplementation, targetChainId);\n const { walletClient, accountStatus } = await _getAuthenticatedWalletClient(walletImplementation);\n\n switch (currentMethod) {\n case 'eoa':\n return _executeEoaTransaction(transactionData, walletClient, accountStatus);\n\n case 'relayer':\n // Relayer execution is handled by RelayerExecutionStrategy in adapter-evm\n // This function is for direct EOA execution\n logger.warn(SYSTEM_LOG_TAG, 'Relayer method should use RelayerExecutionStrategy directly.');\n throw new Error('Use RelayerExecutionStrategy for relayer execution.');\n\n case 'multisig':\n logger.warn(SYSTEM_LOG_TAG, 'Multisig execution method not yet implemented.');\n throw new Error('Multisig execution method not yet implemented.');\n\n default:\n const exhaustiveCheck: never = currentMethod;\n logger.error(SYSTEM_LOG_TAG, `Unsupported execution method encountered: ${exhaustiveCheck}`);\n throw new Error(`Unsupported execution method: ${exhaustiveCheck}`);\n }\n}\n\n/**\n * Sign and broadcast a transaction using the appropriate execution strategy.\n * This is a high-level router function that selects EOA or Relayer strategy\n * based on the execution configuration.\n *\n * @param transactionData - The contract write parameters\n * @param executionConfig - The execution configuration specifying method (eoa, relayer, multisig)\n * @param walletImplementation - The wallet implementation to use for signing\n * @param onStatusChange - Callback for status updates during transaction lifecycle\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns The transaction hash\n */\nexport async function executeEvmTransaction(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n): Promise<{ txHash: string }> {\n const method = executionConfig.method || 'eoa';\n\n logger.info(SYSTEM_LOG_TAG, 'executeEvmTransaction: Starting transaction execution', { method });\n\n // Import strategies dynamically to avoid circular dependencies\n const { EoaExecutionStrategy } = await import('./eoa');\n const { RelayerExecutionStrategy } = await import('./relayer');\n\n let strategy: AdapterExecutionStrategy;\n\n switch (method) {\n case 'eoa':\n strategy = new EoaExecutionStrategy();\n break;\n\n case 'relayer':\n strategy = new RelayerExecutionStrategy();\n break;\n\n case 'multisig':\n logger.warn(SYSTEM_LOG_TAG, 'Multisig execution not yet implemented');\n throw new Error('Multisig execution is not yet supported.');\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported execution method: ${exhaustiveCheck}`);\n }\n }\n\n return strategy.execute(\n transactionData,\n executionConfig,\n walletImplementation,\n onStatusChange,\n runtimeApiKey\n );\n}\n\n/**\n * Waits for a transaction to be confirmed on the blockchain.\n *\n * @param txHash - The transaction hash to wait for\n * @param walletImplementation - The wallet implementation to get the public client from\n * @returns The transaction status and receipt\n */\nexport async function waitForEvmTransactionConfirmation(\n txHash: string,\n walletImplementation: EvmWalletImplementation\n): Promise<{\n status: 'success' | 'error';\n receipt?: TransactionReceipt;\n error?: Error;\n}> {\n logger.info(SYSTEM_LOG_TAG, `Waiting for tx: ${txHash}`);\n try {\n // Get the public client\n const resolvedPublicClient = await walletImplementation.getPublicClient();\n if (!resolvedPublicClient) {\n throw new Error('Public client not available to wait for transaction.');\n }\n\n // Wait for the transaction receipt\n const receipt = await resolvedPublicClient.waitForTransactionReceipt({\n hash: txHash as `0x${string}`,\n });\n\n logger.info(SYSTEM_LOG_TAG, 'Received receipt:', receipt);\n\n // Check the status field in the receipt\n if (receipt.status === 'success') {\n return { status: 'success', receipt };\n } else {\n logger.error(SYSTEM_LOG_TAG, 'Transaction reverted:', receipt);\n return { status: 'error', receipt, error: new Error('Transaction reverted.') };\n }\n } catch (error) {\n logger.error(SYSTEM_LOG_TAG, 'Error waiting for transaction confirmation:', error);\n return {\n status: 'error',\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n","import { createContext } from 'react';\n\n/**\n * Context to track Wagmi provider initialization status\n * Used by components to safely render when the provider is ready\n */\nexport const WagmiProviderInitializedContext = createContext<boolean>(false);\n","import { useContext } from 'react';\n\nimport { WagmiProviderInitializedContext } from '../context/wagmi-context';\n\n/**\n * Hook to check if WagmiProvider is ready\n * @returns boolean indicating if the provider is initialized\n */\nexport const useIsWagmiProviderInitialized = (): boolean => {\n return useContext(WagmiProviderInitializedContext);\n};\n","import React, { useEffect, useState } from 'react';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { useIsWagmiProviderInitialized } from '../hooks/useIsWagmiProviderInitialized';\n\n/**\n * A wrapper component that safely renders children that use wagmi hooks.\n * It handles errors and provider initialization state to prevent crashes.\n */\nexport const SafeWagmiComponent = ({\n children,\n fallback = null,\n}: {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n}) => {\n const isProviderInitialized = useIsWagmiProviderInitialized();\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n // Reset error state if provider initializes\n if (isProviderInitialized) {\n setHasError(false);\n }\n }, [isProviderInitialized]);\n\n // Setup global error handler for wagmi errors\n useEffect(() => {\n const handleError = (event: ErrorEvent) => {\n // Only handle wagmi-related errors\n if (\n event.error?.message?.includes('useConfig') ||\n event.error?.message?.includes('WagmiProvider')\n ) {\n logger.debug(\n 'SafeWagmiComponent',\n 'Caught wagmi error via window error event:',\n event.error\n );\n setHasError(true);\n event.preventDefault(); // Prevent the error from propagating\n }\n };\n\n window.addEventListener('error', handleError);\n return () => {\n window.removeEventListener('error', handleError);\n };\n }, []);\n\n // If provider isn't ready yet or we had an error, show fallback\n if (!isProviderInitialized || hasError) {\n return <>{fallback}</>;\n }\n\n try {\n return <>{children}</>;\n } catch (error) {\n // Only catch render errors related to wagmi hooks\n if (\n error instanceof Error &&\n (error.message.includes('useConfig') || error.message.includes('WagmiProvider'))\n ) {\n logger.debug('SafeWagmiComponent', 'Caught wagmi error:', error);\n setHasError(true);\n return <>{fallback}</>;\n }\n // Re-throw other errors\n throw error;\n }\n};\n","import { Loader2, Wallet } from 'lucide-react';\nimport React, { useEffect, useState } from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedConnectStatus } from '@openzeppelin/ui-react';\nimport type { BaseComponentProps, WalletComponentSize } from '@openzeppelin/ui-types';\nimport { cn, getWalletButtonSizeProps } from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\nimport { ConnectorDialog } from './ConnectorDialog';\n\n/**\n * A button that allows users to connect their wallet.\n * Opens a dialog to select from available connectors.\n * @param hideWhenConnected - Whether to hide the button when wallet is connected (default: true)\n * @param showInjectedConnector - Whether to show the injected connector in the dialog (default: false)\n */\nexport interface ConnectButtonProps extends BaseComponentProps {\n hideWhenConnected?: boolean;\n showInjectedConnector?: boolean;\n}\n\nexport const CustomConnectButton: React.FC<ConnectButtonProps> = ({\n className,\n size,\n variant,\n fullWidth,\n hideWhenConnected = true,\n showInjectedConnector = false,\n}) => {\n const [dialogOpen, setDialogOpen] = useState(false);\n const sizeProps = getWalletButtonSizeProps(size);\n\n const unavailableButton = (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Button\n disabled={true}\n variant={variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, fullWidth && 'w-full')}\n >\n <Wallet className={cn(sizeProps.iconSize, 'mr-1')} />\n Wallet Unavailable\n </Button>\n </div>\n );\n\n return (\n <SafeWagmiComponent fallback={unavailableButton}>\n <ConnectButtonContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n dialogOpen={dialogOpen}\n setDialogOpen={setDialogOpen}\n hideWhenConnected={hideWhenConnected}\n showInjectedConnector={showInjectedConnector}\n />\n </SafeWagmiComponent>\n );\n};\n\nconst ConnectButtonContent: React.FC<{\n className?: string;\n size?: WalletComponentSize;\n variant?: BaseComponentProps['variant'];\n fullWidth?: boolean;\n dialogOpen: boolean;\n setDialogOpen: (open: boolean) => void;\n hideWhenConnected: boolean;\n showInjectedConnector: boolean;\n}> = ({\n className,\n size,\n variant,\n fullWidth,\n dialogOpen,\n setDialogOpen,\n hideWhenConnected,\n showInjectedConnector,\n}) => {\n const { isConnected } = useDerivedAccountStatus();\n const { isConnecting: isHookConnecting, error: connectError } = useDerivedConnectStatus();\n\n // Local state to indicate the button has been clicked and dialog is open, awaiting user selection\n const [isManuallyInitiated, setIsManuallyInitiated] = useState(false);\n\n const sizeProps = getWalletButtonSizeProps(size);\n\n useEffect(() => {\n if (isConnected && hideWhenConnected) {\n setDialogOpen(false);\n setIsManuallyInitiated(false); // Reset if dialog closes due to connection\n }\n }, [isConnected, hideWhenConnected, setDialogOpen]);\n\n // If dialog is closed, reset manual initiation state\n useEffect(() => {\n if (!dialogOpen) {\n setIsManuallyInitiated(false);\n }\n }, [dialogOpen]);\n\n // If wagmi hook reports it's connecting, we no longer need our manual pending state\n useEffect(() => {\n if (isHookConnecting) {\n setIsManuallyInitiated(false);\n }\n }, [isHookConnecting]);\n\n const handleConnectClick = () => {\n if (!isConnected) {\n setIsManuallyInitiated(true); // User clicked, show pending on button\n setDialogOpen(true);\n }\n };\n\n if (isConnected && hideWhenConnected) {\n return null;\n }\n\n // Button shows loading if either hook reports connecting OR if user just clicked to open dialog\n const showButtonLoading = isHookConnecting || isManuallyInitiated;\n\n return (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Button\n onClick={handleConnectClick}\n disabled={showButtonLoading || isConnected}\n variant={variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, fullWidth && 'w-full')}\n title={isConnected ? 'Connected' : connectError?.message || 'Connect Wallet'}\n >\n {showButtonLoading ? (\n <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1')} />\n ) : (\n <Wallet className={cn(sizeProps.iconSize, 'mr-1')} />\n )}\n {showButtonLoading ? 'Connecting...' : 'Connect Wallet'}\n </Button>\n\n <ConnectorDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n // If dialog is closed manually by user before selection, reset manual initiation\n if (!open) {\n setIsManuallyInitiated(false);\n }\n }}\n showInjectedConnector={showInjectedConnector}\n />\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\n\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedConnectStatus } from '@openzeppelin/ui-react';\nimport type { Connector } from '@openzeppelin/ui-types';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * Dialog component for selecting a wallet connector\n * @param showInjectedConnector - Whether to show the injected connector (default: false)\n */\ninterface ConnectorDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n showInjectedConnector?: boolean;\n}\n\nexport const ConnectorDialog: React.FC<ConnectorDialogProps> = ({\n open,\n onOpenChange,\n showInjectedConnector = false,\n}) => {\n // Prepare fallback dialog content\n const unavailableContent = (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Wallet Connection Unavailable</DialogTitle>\n <DialogDescription>\n The wallet connection system is not properly initialized.\n </DialogDescription>\n </DialogHeader>\n </DialogContent>\n </Dialog>\n );\n\n // Only render wagmi-dependent part when provider is initialized\n return (\n <SafeWagmiComponent fallback={unavailableContent}>\n <ConnectorDialogContent\n open={open}\n onOpenChange={onOpenChange}\n showInjectedConnector={showInjectedConnector}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner content that uses wagmi hooks\nconst ConnectorDialogContent: React.FC<ConnectorDialogProps> = ({\n open,\n onOpenChange,\n showInjectedConnector = false,\n}) => {\n const { connect, connectors, error: connectError, isConnecting } = useDerivedConnectStatus();\n const { isConnected } = useDerivedAccountStatus();\n const [connectingId, setConnectingId] = useState<string | null>(null);\n\n // Track connection attempts for dialog closure\n useEffect(() => {\n // If we're connected and there was a connection attempt, close the dialog\n if (isConnected && connectingId) {\n onOpenChange(false);\n setConnectingId(null);\n }\n }, [isConnected, connectingId, onOpenChange]);\n\n // If connect function itself is not available (e.g., adapter doesn't provide useConnect facade hook)\n if (!connect) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Error</DialogTitle>\n </DialogHeader>\n <p>Wallet connection function is not available.</p>\n </DialogContent>\n </Dialog>\n );\n }\n\n const handleConnectorSelect = (selectedConnector: Connector) => {\n setConnectingId(selectedConnector.id);\n connect({ connector: selectedConnector });\n };\n\n // Filter out the injected connector if showInjectedConnector is false\n const filteredConnectors = connectors.filter((connector: Connector) => {\n const isInjected = connector.id === 'injected';\n return !(isInjected && !showInjectedConnector);\n });\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Connect Wallet</DialogTitle>\n <DialogDescription>\n Select a wallet provider to connect with this application.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"grid gap-4 py-4\">\n {filteredConnectors.length === 0 ? (\n <p className=\"text-center text-muted-foreground\">No wallet connectors available.</p>\n ) : (\n filteredConnectors.map((connector: Connector) => (\n <Button\n key={connector.id}\n onClick={() => handleConnectorSelect(connector)}\n disabled={isConnecting && connectingId === connector.id}\n variant=\"outline\"\n className=\"flex justify-between items-center w-full py-6\"\n >\n <span>{connector.name}</span>\n {isConnecting && connectingId === connector.id && (\n <span className=\"ml-2 text-xs\">Connecting...</span>\n )}\n </Button>\n ))\n )}\n </div>\n\n {connectError && (\n <p className=\"text-sm text-red-500 mt-1\">\n {connectError.message || 'Error connecting wallet'}\n </p>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n","import { LogOut } from 'lucide-react';\nimport React from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedDisconnect } from '@openzeppelin/ui-react';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport { cn, getWalletAccountDisplaySizeProps, truncateMiddle } from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * A component that displays the connected account address and chain ID.\n * Also includes a disconnect button.\n */\nexport const CustomAccountDisplay: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n // Use the SafeWagmiComponent with null fallback\n return (\n <SafeWagmiComponent fallback={null}>\n <AccountDisplayContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner component that uses derived hooks\nconst AccountDisplayContent: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n const { isConnected, address, chainId } = useDerivedAccountStatus();\n const { disconnect } = useDerivedDisconnect();\n\n const sizeProps = getWalletAccountDisplaySizeProps(size);\n\n if (!isConnected || !address || !disconnect) {\n return null;\n }\n\n return (\n <div className={cn('flex items-center gap-2', fullWidth && 'w-full', className)}>\n <div className={cn('flex flex-col', fullWidth && 'flex-1')}>\n <span className={cn(sizeProps.textSize, 'font-medium')}>\n {truncateMiddle(address, 4, 4)}\n </span>\n <span className={cn(sizeProps.subTextSize, 'text-muted-foreground -mt-0.5')}>\n {chainId ? `Chain ID: ${chainId}` : 'Chain ID: N/A'}\n </span>\n </div>\n <Button\n onClick={() => disconnect()}\n variant={variant || 'ghost'}\n size=\"icon\"\n className={cn(sizeProps.iconButtonSize, 'p-0')}\n title=\"Disconnect wallet\"\n >\n <LogOut className={sizeProps.iconSize} />\n </Button>\n </div>\n );\n};\n","import { Loader2 } from 'lucide-react';\nimport type { Chain } from 'viem';\nimport React from 'react';\n\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@openzeppelin/ui-components';\nimport {\n useDerivedAccountStatus,\n useDerivedChainInfo,\n useDerivedSwitchChainStatus,\n} from '@openzeppelin/ui-react';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport {\n cn,\n getWalletNetworkSwitcherSizeProps,\n getWalletNetworkSwitcherVariantClassName,\n} from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * A component that displays the current network and allows switching to other networks.\n * Uses the chainId and switchChain hooks.\n */\nexport const CustomNetworkSwitcher: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n // Use the SafeWagmiComponent with null fallback\n return (\n <SafeWagmiComponent fallback={null}>\n <NetworkSwitcherContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner component that uses wagmi hooks\nconst NetworkSwitcherContent: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n const { isConnected } = useDerivedAccountStatus();\n const { currentChainId, availableChains: unknownChains } = useDerivedChainInfo();\n const { switchChain, isSwitching: isPending, error } = useDerivedSwitchChainStatus();\n\n const sizeProps = getWalletNetworkSwitcherSizeProps(size);\n const variantClassName = getWalletNetworkSwitcherVariantClassName(variant);\n\n // Cast to Chain[] for use within this component\n const typedAvailableChains = unknownChains as Chain[];\n\n if (!isConnected || !switchChain || typedAvailableChains.length === 0) {\n return null;\n }\n\n const handleNetworkChange = (chainId: number) => {\n if (chainId !== currentChainId) {\n switchChain({ chainId });\n }\n };\n\n const currentChain = typedAvailableChains.find((chain) => chain.id === currentChainId);\n const currentChainName = currentChain?.name || 'Network';\n\n return (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Select\n value={currentChainId?.toString() ?? ''}\n onValueChange={(value: string) => handleNetworkChange(Number(value))}\n disabled={isPending || typedAvailableChains.length === 0}\n >\n <SelectTrigger\n className={cn(\n sizeProps.triggerClassName,\n variantClassName,\n fullWidth && 'w-full max-w-none'\n )}\n >\n <SelectValue placeholder=\"Network\">{currentChainName}</SelectValue>\n </SelectTrigger>\n <SelectContent\n position=\"popper\"\n sideOffset={5}\n align=\"start\"\n className=\"w-auto min-w-[160px] max-h-[300px]\"\n >\n {typedAvailableChains.map((chain) => (\n <SelectItem\n key={chain.id}\n value={chain.id.toString()}\n className={sizeProps.itemClassName}\n >\n {chain.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {isPending && (\n <span className=\"text-muted-foreground ml-2\">\n <Loader2 className={cn(sizeProps.loaderSize, 'animate-spin')} />\n </span>\n )}\n\n {error && <span className=\"text-xs text-red-500 ml-2\">!</span>}\n </div>\n );\n};\n","/**\n * Core Wallet Connection Utilities\n *\n * Provides shared wallet connection logic for EVM-compatible adapters.\n * Both adapter-evm and adapter-polkadot can use these core utilities.\n *\n * @module wallet/connection\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { EvmWalletConnectionResult, EvmWalletImplementation } from '../transaction/types';\n\n/**\n * Default wallet connection status when disconnected.\n * Use this constant when the wallet implementation is not ready or available.\n */\nexport const DEFAULT_DISCONNECTED_STATUS: GetAccountReturnType = {\n isConnected: false,\n isConnecting: false,\n isDisconnected: true,\n isReconnecting: false,\n status: 'disconnected',\n address: undefined,\n addresses: undefined,\n chainId: undefined,\n chain: undefined,\n connector: undefined,\n};\n\n/**\n * Core implementation of connect and ensure correct network logic.\n *\n * This function handles the common pattern of:\n * 1. Connect to wallet using the specified connector\n * 2. Check if connected to the target chain\n * 3. If not, attempt to switch networks\n * 4. If switch fails, disconnect and return error\n *\n * @param impl - The wallet implementation to use\n * @param connectorId - The ID of the connector to use\n * @param targetChainId - The desired chain ID to switch to after connection\n * @param logSystem - The log system identifier for logging\n * @returns An object containing connection status, address, and any error\n */\nexport async function connectAndEnsureCorrectNetworkCore(\n impl: EvmWalletImplementation,\n connectorId: string,\n targetChainId: number,\n logSystem: string\n): Promise<EvmWalletConnectionResult> {\n const connectionResult = await impl.connect(connectorId);\n if (!connectionResult.connected || !connectionResult.address || !connectionResult.chainId) {\n return { connected: false, error: connectionResult.error || 'Connection failed' };\n }\n\n if (connectionResult.chainId !== targetChainId) {\n logger.info(\n logSystem,\n `Connected to chain ${connectionResult.chainId}, but target is ${targetChainId}. Attempting switch.`\n );\n try {\n await impl.switchNetwork(targetChainId);\n const postSwitchStatus = impl.getWalletConnectionStatus();\n if (postSwitchStatus.chainId !== targetChainId) {\n const switchError = `Failed to switch to target network ${targetChainId}. Current: ${postSwitchStatus.chainId}`;\n logger.error(logSystem, switchError);\n // Attempt to disconnect to leave a clean state if switch fails\n try {\n await impl.disconnect();\n } catch (e) {\n logger.warn(logSystem, 'Failed to disconnect after network switch failure.', e);\n }\n return { connected: false, error: switchError };\n }\n logger.info(logSystem, `Successfully switched to target chain ${targetChainId}.`);\n return { ...connectionResult, chainId: postSwitchStatus.chainId }; // Return updated chainId\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(logSystem, 'Network switch failed:', errorMessage);\n // Attempt to disconnect to leave a clean state if switch fails\n try {\n await impl.disconnect();\n } catch (e) {\n logger.warn(logSystem, 'Failed to disconnect after network switch failure.', e);\n }\n return { connected: false, error: `Network switch failed: ${errorMessage}` };\n }\n }\n return connectionResult;\n}\n","/**\n * Core Wagmi implementation for EVM wallet connection\n *\n * This file contains the shared implementation of Wagmi and Viem for wallet connection.\n * It's designed to be used by both EVM and Polkadot adapters with full feature parity.\n *\n * Features:\n * - RPC override logic with user configuration support\n * - Dynamic RPC change listener for config invalidation\n * - Chain ID to network ID mapping\n * - Explicit connector setup (injected, metaMask, safe, walletConnect)\n * - Sophisticated config caching with invalidation\n * - UI kit configuration methods for RainbowKit integration\n */\nimport { injected, metaMask, safe, walletConnect } from '@wagmi/connectors';\nimport {\n connect,\n createConfig,\n disconnect,\n getAccount,\n getPublicClient as getWagmiCorePublicClient,\n getWalletClient as getWagmiWalletClient,\n switchChain,\n watchAccount,\n type Config,\n type GetAccountReturnType,\n type CreateConnectorFn as WagmiCreateConnectorFn,\n} from '@wagmi/core';\nimport { http, type Chain, type PublicClient, type WalletClient } from 'viem';\n\nimport type { Connector, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\nimport { getUserRpcUrl } from '../configuration';\nimport type { EvmWalletImplementation } from '../transaction/types';\nimport type { WagmiConfigChains, WagmiWalletConfig, WalletNetworkConfig } from './types';\n\n/**\n * Generates the supported chains from network configurations.\n * Only includes networks that have a viemChain property (ensuring wagmi compatibility).\n */\nfunction getSupportedChainsFromNetworks(\n networkConfigs: WalletNetworkConfig[],\n logSystem: string\n): readonly Chain[] {\n const chains = networkConfigs\n .filter((network) => network.viemChain)\n .map((network) => network.viemChain!)\n .filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index); // Remove duplicates\n\n logger.info(\n logSystem,\n `Generated supported chains from network configurations: ${chains.length} chains`,\n chains.map((c) => ({ id: c.id, name: c.name }))\n );\n\n return chains;\n}\n\n/**\n * Generates the mapping from Viem chain IDs to application network IDs.\n * This mapping is auto-generated from the network configurations.\n */\nfunction getChainIdToNetworkIdMapping(\n networkConfigs: WalletNetworkConfig[],\n logSystem: string\n): Record<number, string> {\n const mapping = networkConfigs\n .filter((network) => network.viemChain)\n .reduce(\n (acc, network) => {\n acc[network.chainId] = network.id;\n return acc;\n },\n {} as Record<number, string>\n );\n\n logger.info(\n logSystem,\n 'Generated chain ID to network ID mapping from network configurations:',\n mapping\n );\n\n return mapping;\n}\n\n/**\n * Type for RainbowKit config retrieval function.\n * This allows adapters to provide their own RainbowKit config service.\n */\nexport type GetWagmiConfigForRainbowKitFn = (\n uiKitConfiguration: UiKitConfiguration,\n chains: WagmiConfigChains,\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n) => Promise<Config | null>;\n\n/**\n * Class responsible for encapsulating Wagmi core logic for wallet interactions.\n * This class should not be used directly by UI components. The adapters\n * expose a standardized interface for wallet operations.\n * It manages Wagmi Config instances and provides methods for wallet actions.\n *\n * Implements EvmWalletImplementation interface for use with shared execution strategies.\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * const walletImpl = new WagmiWalletImplementation({\n * chains: evmChains,\n * networkConfigs: evmNetworks,\n * walletConnectProjectId: 'your-project-id',\n * });\n *\n * // In adapter-polkadot:\n * const walletImpl = new WagmiWalletImplementation({\n * chains: polkadotChains,\n * networkConfigs: polkadotNetworks,\n * });\n * ```\n */\nexport class WagmiWalletImplementation implements EvmWalletImplementation {\n private defaultInstanceConfig: Config | null = null;\n private activeWagmiConfig: Config | null = null;\n private unsubscribe?: ReturnType<typeof watchAccount>;\n private initialized: boolean = false;\n private walletConnectProjectId?: string;\n private rpcConfigUnsubscribe?: () => void;\n\n // Configuration from constructor\n private readonly supportedChains: readonly Chain[];\n private readonly chainIdToNetworkId: Record<number, string>;\n private readonly logSystem: string;\n\n // Optional RainbowKit config function (can be injected by adapters)\n private rainbowKitConfigFn?: GetWagmiConfigForRainbowKitFn;\n\n /**\n * Constructs the WagmiWalletImplementation.\n * Configuration for Wagmi is deferred until actually needed or set externally.\n *\n * @param config - Configuration options for the wallet implementation\n */\n constructor(config: WagmiWalletConfig) {\n this.logSystem = config.logSystem ?? 'WagmiWalletImplementation';\n this.walletConnectProjectId = config.walletConnectProjectId;\n\n // Generate chains and mapping from network configs\n this.supportedChains =\n config.chains.length > 0\n ? config.chains\n : getSupportedChainsFromNetworks(config.networkConfigs, this.logSystem);\n this.chainIdToNetworkId = getChainIdToNetworkIdMapping(config.networkConfigs, this.logSystem);\n\n logger.info(\n this.logSystem,\n 'Constructor called. Initial anticipated kitName:',\n config.initialUiKitConfig?.kitName\n );\n\n this.initialized = true;\n logger.info(\n this.logSystem,\n 'WagmiWalletImplementation instance initialized (Wagmi config creation deferred).'\n );\n\n // Subscribe to RPC configuration changes to invalidate cached config\n this.setupRpcConfigListener();\n }\n\n /**\n * Sets the RainbowKit config retrieval function.\n * This allows adapters to inject their own RainbowKit integration.\n *\n * @param fn - Function to get RainbowKit wagmi config\n */\n public setRainbowKitConfigFn(fn: GetWagmiConfigForRainbowKitFn): void {\n this.rainbowKitConfigFn = fn;\n }\n\n /**\n * Gets the supported chains for this implementation.\n */\n public getSupportedChains(): readonly Chain[] {\n return this.supportedChains;\n }\n\n /**\n * Gets the chain ID to network ID mapping.\n */\n public getChainIdToNetworkIdMapping(): Record<number, string> {\n return this.chainIdToNetworkId;\n }\n\n /**\n * Sets up a listener for RPC configuration changes to invalidate the cached Wagmi config\n * when user changes RPC settings.\n */\n private setupRpcConfigListener(): void {\n // Import dynamically to avoid circular dependencies\n import('@openzeppelin/ui-utils')\n .then(({ userRpcConfigService }) => {\n // Subscribe to all RPC config changes\n this.rpcConfigUnsubscribe = userRpcConfigService.subscribe('*', (event) => {\n if (event.type === 'rpc-config-changed' || event.type === 'rpc-config-cleared') {\n logger.info(\n this.logSystem,\n `RPC config changed for network ${event.networkId}. Invalidating cached Wagmi config.`\n );\n // Invalidate the cached config to force recreation with new RPC settings\n this.defaultInstanceConfig = null;\n }\n });\n })\n .catch((error) => {\n logger.error(this.logSystem, 'Failed to setup RPC config listener:', error);\n });\n }\n\n /**\n * Cleanup method to unsubscribe from RPC config changes\n */\n public cleanup(): void {\n if (this.rpcConfigUnsubscribe) {\n this.rpcConfigUnsubscribe();\n this.rpcConfigUnsubscribe = undefined;\n }\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = undefined;\n }\n }\n\n /**\n * Sets the externally determined, currently active WagmiConfig instance.\n * This is typically called by UiKitManager after it has resolved the appropriate\n * config for the selected UI kit (e.g., RainbowKit's config or a default custom config).\n *\n * @param config - The Wagmi Config object to set as active, or null to clear it.\n */\n public setActiveWagmiConfig(config: Config | null): void {\n logger.info(\n this.logSystem,\n 'setActiveWagmiConfig called with config:',\n config ? 'Valid Config' : 'Null'\n );\n this.activeWagmiConfig = config;\n\n if (this.unsubscribe) {\n logger.warn(\n this.logSystem,\n 'setActiveWagmiConfig: Active WagmiConfig instance has changed. Existing direct watchAccount subscription (via onWalletConnectionChange) may be stale and operating on an old config instance.'\n );\n }\n }\n\n /**\n * Checks if an active wagmi config has been set.\n * Subclasses can use this to determine if the wallet is ready for operations.\n *\n * @returns true if an active wagmi config is set\n */\n protected hasActiveConfig(): boolean {\n return this.activeWagmiConfig !== null;\n }\n\n /**\n * Creates a default WagmiConfig instance on demand.\n * This configuration includes standard connectors (injected, MetaMask, Safe)\n * and WalletConnect if a project ID is available.\n * Used as a fallback or for 'custom' UI kit mode.\n *\n * @returns A Wagmi Config object.\n */\n private createDefaultConfig(): Config {\n const baseConnectors: WagmiCreateConnectorFn[] = [injected(), metaMask(), safe()];\n if (this.walletConnectProjectId?.trim()) {\n baseConnectors.push(walletConnect({ projectId: this.walletConnectProjectId }));\n logger.info(this.logSystem, 'WalletConnect connector added to DEFAULT config.');\n } else {\n logger.warn(\n this.logSystem,\n 'WalletConnect Project ID not provided; WC connector unavailable for DEFAULT config.'\n );\n }\n\n const transportsConfig = this.supportedChains.reduce(\n (acc, chainDefinition) => {\n let rpcUrlToUse: string | undefined = chainDefinition.rpcUrls.default?.http?.[0];\n const appNetworkIdString = this.chainIdToNetworkId[chainDefinition.id];\n\n if (appNetworkIdString) {\n // Prefer user-configured RPC from generic service\n let httpRpcOverride: string | undefined = getUserRpcUrl(appNetworkIdString);\n\n // Fallback to AppConfigService override if no user config\n if (!httpRpcOverride) {\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(appNetworkIdString);\n if (typeof rpcOverrideSetting === 'string') {\n httpRpcOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object') {\n // Handle both RpcEndpointConfig and UserRpcProviderConfig\n if ('http' in rpcOverrideSetting && rpcOverrideSetting.http) {\n httpRpcOverride = rpcOverrideSetting.http;\n } else if ('url' in rpcOverrideSetting && rpcOverrideSetting.url) {\n httpRpcOverride = rpcOverrideSetting.url;\n }\n }\n }\n\n if (httpRpcOverride) {\n logger.info(\n this.logSystem,\n `Using overridden RPC for chain ${chainDefinition.name} (default config): ${httpRpcOverride}`\n );\n rpcUrlToUse = httpRpcOverride;\n }\n }\n\n acc[chainDefinition.id] = http(rpcUrlToUse);\n return acc;\n },\n {} as Record<number, ReturnType<typeof http>>\n );\n\n try {\n const defaultConfig = createConfig({\n chains: this.supportedChains as unknown as WagmiConfigChains,\n connectors: baseConnectors,\n transports: transportsConfig,\n });\n logger.info(this.logSystem, 'Default Wagmi config created successfully on demand.');\n return defaultConfig;\n } catch (error) {\n logger.error(this.logSystem, 'Error creating default Wagmi config on demand:', error);\n return createConfig({\n chains: [this.supportedChains[0]] as unknown as WagmiConfigChains,\n connectors: [injected()],\n transports: { [this.supportedChains[0].id]: http() },\n });\n }\n }\n\n /**\n * Wrapper function to convert AppConfigService RPC overrides to the format expected by RainbowKit.\n *\n * @param networkId - The network ID to get RPC override for\n * @returns RPC configuration in the format expected by RainbowKit\n */\n public getRpcOverrideForRainbowKit(\n networkId: string\n ): string | { http?: string; ws?: string } | undefined {\n // Prefer user-configured RPC from generic service first\n const userRpcUrl = getUserRpcUrl(networkId);\n if (userRpcUrl) {\n return { http: userRpcUrl };\n }\n\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(networkId);\n\n if (typeof rpcOverrideSetting === 'string') {\n return rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting !== null) {\n // Check for UserRpcProviderConfig first\n if ('url' in rpcOverrideSetting && typeof rpcOverrideSetting.url === 'string') {\n // It's a UserRpcProviderConfig - convert url to http\n return {\n http: rpcOverrideSetting.url,\n };\n } else if ('http' in rpcOverrideSetting || 'ws' in rpcOverrideSetting) {\n // It's an RpcEndpointConfig\n const config = rpcOverrideSetting as { http?: string; ws?: string };\n return {\n http: config.http,\n ws: config.ws,\n };\n }\n }\n\n return undefined;\n }\n\n /**\n * Retrieves or creates the WagmiConfig specifically for RainbowKit.\n * This delegates to the injected RainbowKit config function if available.\n *\n * @param currentAdapterUiKitConfig - The fully resolved UI kit configuration for the adapter.\n * @returns A Promise resolving to the RainbowKit-specific Wagmi Config object, or null if creation fails or not RainbowKit.\n */\n public async getConfigForRainbowKit(\n currentAdapterUiKitConfig: UiKitConfiguration\n ): Promise<Config | null> {\n if (!this.initialized) {\n logger.error(\n this.logSystem,\n 'getConfigForRainbowKit called before implementation initialization.'\n );\n return null;\n }\n\n if (currentAdapterUiKitConfig?.kitName !== 'rainbowkit') {\n logger.warn(\n this.logSystem,\n 'getConfigForRainbowKit called, but kitName is not rainbowkit. Returning null.'\n );\n return null;\n }\n\n logger.info(\n this.logSystem,\n 'getConfigForRainbowKit: Kit is RainbowKit. Proceeding to create/get config. CurrentAdapterUiKitConfig:',\n currentAdapterUiKitConfig\n );\n\n // Use injected RainbowKit config function if available\n if (this.rainbowKitConfigFn) {\n const rainbowKitWagmiConfig = await this.rainbowKitConfigFn(\n currentAdapterUiKitConfig,\n this.supportedChains as WagmiConfigChains,\n this.chainIdToNetworkId,\n this.getRpcOverrideForRainbowKit.bind(this)\n );\n\n if (rainbowKitWagmiConfig) {\n logger.info(this.logSystem, 'Returning RainbowKit-specific Wagmi config for provider.');\n return rainbowKitWagmiConfig;\n }\n }\n\n logger.warn(this.logSystem, 'RainbowKit specific Wagmi config creation failed.');\n return null;\n }\n\n /**\n * Determines and returns the WagmiConfig to be used by UiKitManager during its configuration process.\n * If RainbowKit is specified in the passed uiKitConfig, it attempts to get its specific config.\n * Otherwise, it falls back to creating/returning a default instance config.\n *\n * @param uiKitConfig - The fully resolved UiKitConfiguration that the manager is currently processing.\n * @returns A Promise resolving to the determined Wagmi Config object.\n */\n public async getActiveConfigForManager(uiKitConfig: UiKitConfiguration): Promise<Config> {\n if (!this.initialized) {\n logger.error(\n this.logSystem,\n 'getActiveConfigForManager called before initialization! Creating fallback.'\n );\n return createConfig({\n chains: [this.supportedChains[0]] as unknown as WagmiConfigChains,\n transports: { [this.supportedChains[0].id]: http() },\n });\n }\n\n if (uiKitConfig?.kitName === 'rainbowkit') {\n const rkConfig = await this.getConfigForRainbowKit(uiKitConfig);\n if (rkConfig) return rkConfig;\n logger.warn(\n this.logSystem,\n 'getActiveConfigForManager: RainbowKit config failed, falling back to default.'\n );\n }\n\n // Reuse existing default config if available, only create if needed\n // This ensures wallet connection state is preserved across network switches\n // Config is automatically invalidated when RPC settings change via setupRpcConfigListener()\n if (!this.defaultInstanceConfig) {\n this.defaultInstanceConfig = this.createDefaultConfig();\n }\n return this.defaultInstanceConfig;\n }\n\n /**\n * @deprecated Prefer using methods that rely on the externally set `activeWagmiConfig`\n * or methods that determine contextually appropriate config like `getActiveConfigForManager` (for manager use)\n * or ensure `activeWagmiConfig` is set before calling wagmi actions.\n * This method returns the internally cached default config or the active one if set.\n *\n * @returns The current default or active Wagmi Config object.\n */\n public getConfig(): Config {\n logger.warn(\n this.logSystem,\n 'getConfig() is deprecated. Internal calls should use activeWagmiConfig if set, or ensure default is created.'\n );\n if (this.activeWagmiConfig) return this.activeWagmiConfig;\n if (!this.defaultInstanceConfig) {\n this.defaultInstanceConfig = this.createDefaultConfig();\n }\n return this.defaultInstanceConfig!;\n }\n\n /**\n * Gets the current wallet connection status (isConnected, address, chainId, etc.).\n * This is a synchronous operation and uses the `activeWagmiConfig` if set by `UiKitManager`,\n * otherwise falls back to the default instance config (created on demand).\n *\n * @returns The current account status from Wagmi.\n */\n public getWalletConnectionStatus(): GetAccountReturnType {\n logger.debug(this.logSystem, 'getWalletConnectionStatus called.');\n const configToUse =\n this.activeWagmiConfig ||\n this.defaultInstanceConfig ||\n (this.defaultInstanceConfig = this.createDefaultConfig());\n\n if (!configToUse) {\n logger.error(this.logSystem, 'No config available for getWalletConnectionStatus!');\n // Return a valid GetAccountReturnType for a disconnected state\n return {\n isConnected: false,\n isConnecting: false,\n isDisconnected: true,\n isReconnecting: false,\n status: 'disconnected',\n address: undefined,\n addresses: undefined,\n chainId: undefined,\n chain: undefined,\n connector: undefined,\n };\n }\n return getAccount(configToUse);\n }\n\n /**\n * Subscribes to account and connection status changes from Wagmi.\n * The subscription is bound to the `activeWagmiConfig` if available at the time of call,\n * otherwise to the default instance config.\n *\n * @param callback - Function to call when connection status changes.\n * @returns A function to unsubscribe from the changes.\n */\n public onWalletConnectionChange(\n callback: (status: GetAccountReturnType, prevStatus: GetAccountReturnType) => void\n ): () => void {\n if (!this.initialized) {\n logger.warn(this.logSystem, 'onWalletConnectionChange called before initialization. No-op.');\n return () => {};\n }\n if (this.unsubscribe) {\n this.unsubscribe();\n logger.debug(this.logSystem, 'Previous watchAccount unsubscribed.');\n }\n\n const configToUse =\n this.activeWagmiConfig ||\n this.defaultInstanceConfig ||\n (this.defaultInstanceConfig = this.createDefaultConfig());\n\n if (!configToUse) {\n logger.error(\n this.logSystem,\n 'No config available for onWalletConnectionChange! Subscription not set.'\n );\n return () => {};\n }\n\n this.unsubscribe = watchAccount(configToUse, { onChange: callback });\n logger.info(\n this.logSystem,\n 'watchAccount subscription established/re-established using config:',\n configToUse === this.activeWagmiConfig ? 'activeExternal' : 'defaultInstance'\n );\n return this.unsubscribe;\n }\n\n /**\n * Gets the Viem Wallet Client for the currently connected account and chain.\n *\n * @returns A Promise resolving to the Viem WalletClient or null if not connected.\n */\n public async getWalletClient(): Promise<WalletClient | null> {\n if (!this.initialized || !this.activeWagmiConfig) {\n logger.warn(\n this.logSystem,\n 'getWalletClient: Not initialized or no activeWagmiConfig. Returning null.'\n );\n return null;\n }\n\n const accountStatus = getAccount(this.activeWagmiConfig);\n if (!accountStatus.isConnected || !accountStatus.chainId || !accountStatus.address) {\n return null;\n }\n\n return getWagmiWalletClient(this.activeWagmiConfig, {\n chainId: accountStatus.chainId,\n account: accountStatus.address,\n });\n }\n\n /**\n * Gets the Viem Public Client for the currently connected chain.\n *\n * @returns A Promise resolving to the Viem PublicClient or null.\n */\n public async getPublicClient(): Promise<PublicClient | null> {\n if (!this.initialized || !this.activeWagmiConfig) {\n logger.warn(\n this.logSystem,\n 'getPublicClient: Not initialized or no activeWagmiConfig. Returning null.'\n );\n return null;\n }\n\n const accountStatus = getAccount(this.activeWagmiConfig);\n const currentChainId = accountStatus.chainId;\n\n if (!currentChainId) {\n logger.warn(\n this.logSystem,\n 'getPublicClient: No connected chainId available from accountStatus. Returning null.'\n );\n return null;\n }\n\n try {\n const publicClient = getWagmiCorePublicClient(this.activeWagmiConfig, {\n chainId: currentChainId,\n });\n\n if (publicClient) {\n logger.info(\n this.logSystem,\n `getPublicClient: Successfully retrieved public client for chainId ${currentChainId}.`\n );\n return publicClient;\n }\n\n logger.warn(\n this.logSystem,\n `getPublicClient: getWagmiCorePublicClient returned undefined/null for chainId ${currentChainId}.`\n );\n return null;\n } catch (error) {\n logger.error(this.logSystem, 'Error getting public client from wagmi/core:', error);\n return null;\n }\n }\n\n /**\n * Gets the list of available wallet connectors from the active Wagmi config.\n *\n * @returns A Promise resolving to an array of available connectors.\n */\n public async getAvailableConnectors(): Promise<Connector[]> {\n if (!this.initialized || !this.activeWagmiConfig) return [];\n return this.activeWagmiConfig.connectors.map((co) => ({ id: co.uid, name: co.name }));\n }\n\n /**\n * Initiates the connection process for a specific connector.\n *\n * @param connectorId - The ID of the connector to use.\n * @returns A Promise with connection result including address and chainId if successful.\n */\n public async connect(\n connectorId: string\n ): Promise<{ connected: boolean; address?: string; chainId?: number; error?: string }> {\n if (!this.initialized || !this.activeWagmiConfig) {\n throw new Error('Wallet not initialized or no active config');\n }\n\n const connectorToUse = this.activeWagmiConfig.connectors.find(\n (cn) => cn.id === connectorId || cn.uid === connectorId\n );\n\n if (!connectorToUse) {\n throw new Error(`Connector ${connectorId} not found`);\n }\n\n const res = await connect(this.activeWagmiConfig, { connector: connectorToUse });\n return { connected: true, address: res.accounts[0], chainId: res.chainId };\n }\n\n /**\n * Disconnects the currently connected wallet.\n *\n * @returns A Promise with disconnection result.\n */\n public async disconnect(): Promise<{ disconnected: boolean; error?: string }> {\n if (!this.initialized || !this.activeWagmiConfig) {\n return { disconnected: false, error: 'Wallet not initialized or no active config' };\n }\n await disconnect(this.activeWagmiConfig);\n return { disconnected: true };\n }\n\n /**\n * Prompts the user to switch to the specified network.\n *\n * @param chainId - The target chain ID to switch to.\n * @returns A Promise that resolves if the switch is successful, or rejects with an error.\n */\n public async switchNetwork(chainId: number): Promise<void> {\n if (!this.initialized || !this.activeWagmiConfig) {\n throw new Error('Wallet not initialized or no active config');\n }\n await switchChain(this.activeWagmiConfig, { chainId });\n }\n}\n","/**\n * Types Module\n *\n * Internal TypeScript types for EVM core functionality.\n * Re-exports commonly used types from dependencies.\n *\n * @module types\n */\n\n// Contract artifacts types\nexport { type EvmContractArtifacts, isEvmContractArtifacts } from './artifacts';\n\n// Provider types\nexport {\n EvmProviderKeys,\n type EvmContractDefinitionProviderKey,\n EVM_PROVIDER_ORDER_DEFAULT,\n isEvmProviderKey,\n} from './providers';\n\n// Network configuration types\nexport { type EvmCompatibleNetworkConfig, type TypedEvmNetworkConfig } from './network';\n\n// ABI types\nexport { type AbiItem, type WriteContractParameters } from './abi';\n\n// ABI load result type\nexport type EvmAbiLoadResult = {\n abi: unknown[];\n name?: string;\n source?: string;\n};\n\n// Proxy info type\nexport type EvmProxyInfo = {\n isProxy: boolean;\n implementation?: string;\n proxyType?: string;\n};\n\n// Transaction data type\nexport type EvmTransactionData = {\n to: string;\n data: string;\n value?: bigint;\n};\n","/**\n * Network Service Configuration for EVM-compatible networks.\n *\n * Provides validation and connection testing for network services (RPC, Explorer, Contract Definitions).\n * These are ecosystem-agnostic and can be used by any EVM-compatible adapter.\n *\n * @module configuration/network-services\n */\n\nimport type { UserExplorerConfig, UserRpcProviderConfig } from '@openzeppelin/ui-types';\n\nimport { isEvmProviderKey } from '../types';\nimport type { EvmCompatibleNetworkConfig } from '../types';\nimport { testEvmExplorerConnection, validateEvmExplorerConfig } from './explorer';\nimport { testEvmRpcConnection, validateEvmRpcEndpoint } from './rpc';\n\n/**\n * Validates a network service configuration for EVM-compatible networks.\n *\n * @param serviceId - The service identifier ('rpc', 'explorer', or 'contract-definitions')\n * @param values - The form values to validate\n * @returns True if valid, false otherwise\n */\nexport async function validateEvmNetworkServiceConfig(\n serviceId: string,\n values: Record<string, unknown>\n): Promise<boolean> {\n if (serviceId === 'rpc') {\n const cfg = { url: String(values.rpcUrl || ''), isCustom: true } as UserRpcProviderConfig;\n return validateEvmRpcEndpoint(cfg);\n }\n if (serviceId === 'explorer') {\n const cfg = {\n explorerUrl: values.explorerUrl ? String(values.explorerUrl) : undefined,\n apiUrl: values.apiUrl ? String(values.apiUrl) : undefined,\n apiKey: values.apiKey ? String(values.apiKey) : undefined,\n isCustom: true,\n applyToAllNetworks: Boolean(values.applyToAllNetworks),\n } as UserExplorerConfig;\n return validateEvmExplorerConfig(cfg);\n }\n if (serviceId === 'contract-definitions') {\n const raw = values.defaultProvider;\n if (raw === undefined || raw === null || raw === '') return true;\n return isEvmProviderKey(raw);\n }\n return true;\n}\n\n/**\n * Tests a network service connection for EVM-compatible networks.\n *\n * @param serviceId - The service identifier ('rpc', 'explorer', or 'contract-definitions')\n * @param values - The form values containing connection details\n * @param networkConfig - The network configuration (ecosystem-agnostic)\n * @returns Connection test result with success status, latency, and optional error\n */\nexport async function testEvmNetworkServiceConnection(\n serviceId: string,\n values: Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<{ success: boolean; latency?: number; error?: string }> {\n if (serviceId === 'rpc') {\n const cfg = { url: String(values.rpcUrl || ''), isCustom: true } as UserRpcProviderConfig;\n return testEvmRpcConnection(cfg);\n }\n if (serviceId === 'explorer') {\n const cfg = {\n explorerUrl: values.explorerUrl ? String(values.explorerUrl) : undefined,\n apiUrl: values.apiUrl ? String(values.apiUrl) : undefined,\n apiKey: values.apiKey ? String(values.apiKey) : undefined,\n isCustom: true,\n applyToAllNetworks: Boolean(values.applyToAllNetworks),\n } as UserExplorerConfig;\n return testEvmExplorerConnection(cfg, networkConfig);\n }\n return { success: true };\n}\n","/**\n * RainbowKit Configuration Generator\n *\n * Generates the content for a `rainbowkit.config.ts` file for exported projects.\n * Shared by all EVM-compatible adapters (EVM, Polkadot parachains, etc.).\n */\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\n\nexport interface RainbowKitConfigOptions {\n /** Default app name if not provided in config */\n defaultAppName?: string;\n /** Header comment for the generated file */\n headerComment?: string;\n}\n\nconst DEFAULT_OPTIONS: RainbowKitConfigOptions = {\n defaultAppName: 'My RainbowKit App',\n headerComment: `// RainbowKit configuration for your exported application\n// This file is used ONLY in the exported app, not in the builder app preview`,\n};\n\n/**\n * Generates the content for a `rainbowkit.config.ts` file for an exported project.\n * It merges the user-provided configuration with the necessary boilerplate to ensure\n * the config is valid for RainbowKit's `getDefaultConfig`.\n *\n * @param userConfig - The user-provided configuration from the builder app.\n * @param options - Optional customization for the generated file.\n * @returns A string containing the formatted TypeScript code for the config file.\n */\nexport function generateRainbowKitConfigFile(\n userConfig: UiKitConfiguration['kitConfig'],\n options: RainbowKitConfigOptions = {}\n): string {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const config = (userConfig || {}) as Record<string, unknown>;\n const appName = (config.appName as string) || opts.defaultAppName;\n const learnMoreUrl = (config.learnMoreUrl as string) || 'https://openzeppelin.com';\n // We provide a default projectId as it's required by RainbowKit for WalletConnect.\n const projectId = (config.projectId as string) || 'YOUR_PROJECT_ID';\n\n // Build the appInfo part conditionally\n const appInfoLines = [`appName: '${appName}'`];\n if (learnMoreUrl) {\n appInfoLines.push(`learnMoreUrl: '${learnMoreUrl}'`);\n }\n const appInfoContent = appInfoLines.join(',\\n ');\n\n const fileContent = `${opts.headerComment}\n\n// Uncomment imports as needed:\n// import { darkTheme, lightTheme } from '@rainbow-me/rainbowkit';\n\nconst rainbowKitAppConfig = {\n wagmiParams: {\n appName: '${appName}',\n projectId: '${projectId}', // Get yours at https://cloud.walletconnect.com\n \n // Additional options:\n // ssr: true,\n // wallets: [...],\n },\n providerProps: {\n appInfo: {\n ${appInfoContent}\n },\n \n // UI customization - all features work in exported apps:\n // theme: darkTheme(),\n // modalSize: 'compact',\n // showRecentTransactions: true,\n // coolMode: true,\n },\n};\n\nexport default rainbowKitAppConfig;`;\n\n return fileContent;\n}\n\n/**\n * Generates the specific configuration file for RainbowKit during project export.\n *\n * @param uiKitConfig The full UI kit configuration object from the builder.\n * @param options - Optional customization for the generated file.\n * @returns A record containing the file path and its generated content.\n */\nexport function generateRainbowKitExportables(\n uiKitConfig: UiKitConfiguration,\n options: RainbowKitConfigOptions = {}\n): Record<string, string> {\n const filePath = 'src/config/wallet/rainbowkit.config.ts';\n const content =\n uiKitConfig.customCode || generateRainbowKitConfigFile(uiKitConfig.kitConfig, options);\n\n return { [filePath]: content };\n}\n","/**\n * Custom RainbowKit configuration types for enhanced UI control\n */\n/**\n * Re-export RainbowKit's native types for ConnectButton props\n * This ensures we use the exact same types that RainbowKit expects,\n * reducing maintenance burden and letting RainbowKit handle type validation\n */\n// Import RainbowKit's native ConnectButton types\nimport type { ConnectButton, RainbowKitProvider } from '@rainbow-me/rainbowkit';\n\n/**\n * Extract the `AppInfo` type from the RainbowKitProvider's props.\n * This is the canonical way to get the type for the `appInfo` object.\n */\nexport type AppInfo = React.ComponentProps<typeof RainbowKitProvider>['appInfo'];\n\n/**\n * Extract the props type from RainbowKit's ConnectButton component\n * This gives us the exact same types that RainbowKit uses internally\n */\nexport type RainbowKitConnectButtonProps = React.ComponentProps<typeof ConnectButton>;\n\n/**\n * Represents the props expected by the RainbowKitProvider component.\n * It uses a nested `appInfo` object.\n */\nexport interface RainbowKitProviderProps {\n appInfo?: AppInfo;\n [key: string]: unknown;\n}\n\n/**\n * Represents the shape of the `kitConfig` object we use internally when the\n * selected kit is RainbowKit. It has a flat structure for `appName` and `learnMoreUrl`\n * for easier handling in our builder app, and can also contain pre-existing providerProps.\n */\nexport type RainbowKitKitConfig = Partial<AppInfo> & {\n providerProps?: RainbowKitProviderProps;\n [key: string]: unknown;\n};\n\n/**\n * Custom UI configuration that uses RainbowKit's native types\n * This extends our configuration system while leveraging RainbowKit's own type definitions\n */\nexport interface RainbowKitCustomizations {\n /**\n * Configuration for the RainbowKit ConnectButton component\n * Uses RainbowKit's native prop types for type safety and compatibility\n */\n connectButton?: Partial<RainbowKitConnectButtonProps>;\n}\n\n/**\n * Type guard to check if an object contains RainbowKit customizations\n */\nexport function isRainbowKitCustomizations(obj: unknown): obj is RainbowKitCustomizations {\n return typeof obj === 'object' && obj !== null && 'connectButton' in obj;\n}\n\n/**\n * Utility to extract RainbowKit customizations from a kit config\n */\nexport function extractRainbowKitCustomizations(\n kitConfig: Record<string, unknown> | undefined\n): RainbowKitCustomizations | undefined {\n if (!kitConfig || !kitConfig.customizations) {\n return undefined;\n }\n\n const customizations = kitConfig.customizations;\n return isRainbowKitCustomizations(customizations) ? customizations : undefined;\n}\n","import type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * RainbowKit configuration options definition\n */\n\n/**\n * Validates the RainbowKit configuration to ensure required fields are present.\n *\n * @param kitConfig - The RainbowKit configuration object\n * @returns Object containing the validation result and any missing fields or error message\n */\nexport function validateRainbowKitConfig(kitConfig?: UiKitConfiguration['kitConfig']): {\n isValid: boolean;\n missingFields?: string[];\n error?: string;\n} {\n // Detailed log to inspect the received kitConfig\n logger.debug(\n 'validateRainbowKitConfig',\n 'Received kitConfig for validation:',\n JSON.stringify(kitConfig)\n );\n\n if (!kitConfig) {\n logger.warn('validateRainbowKitConfig', 'Validation failed: No kitConfig provided.');\n return { isValid: false, error: 'No kitConfig provided for RainbowKit' };\n }\n\n // kitConfig is the fully resolved configuration object which should contain wagmiParams and providerProps.\n // Access wagmiParams from within kitConfig.\n const wagmiParamsFromKitConfig = (kitConfig as Record<string, unknown>).wagmiParams as\n | Record<string, unknown>\n | undefined;\n\n if (\n !wagmiParamsFromKitConfig ||\n typeof wagmiParamsFromKitConfig !== 'object' ||\n wagmiParamsFromKitConfig === null\n ) {\n logger.warn(\n 'validateRainbowKitConfig',\n 'Validation failed: kitConfig.wagmiParams is missing or invalid.',\n { wagmiParamsFromKitConfig }\n );\n return { isValid: false, error: 'kitConfig.wagmiParams is missing or not a valid object' };\n }\n\n const missingFields: string[] = [];\n if (\n !('appName' in wagmiParamsFromKitConfig) ||\n typeof wagmiParamsFromKitConfig.appName !== 'string'\n ) {\n missingFields.push('wagmiParams.appName');\n }\n if (\n !('projectId' in wagmiParamsFromKitConfig) ||\n typeof wagmiParamsFromKitConfig.projectId !== 'string'\n ) {\n missingFields.push('wagmiParams.projectId');\n }\n\n if (missingFields.length > 0) {\n const errorMsg = `Missing or invalid required fields in wagmiParams: ${missingFields.join(', ')}`;\n logger.warn('validateRainbowKitConfig', 'Validation failed:', errorMsg, { missingFields });\n return {\n isValid: false,\n missingFields,\n error: errorMsg,\n };\n }\n logger.debug('validateRainbowKitConfig', 'Validation successful.');\n return { isValid: true };\n}\n\n/**\n * Extracts and type-guards a RainbowKit configuration from a UiKitConfiguration\n *\n * @param config The UI kit configuration\n * @returns The raw kitConfig Record<string, unknown> or undefined.\n */\nexport function getRawUserNativeConfig(\n config: UiKitConfiguration\n): Record<string, unknown> | undefined {\n if (config.kitName !== 'rainbowkit' || !config.kitConfig) {\n return undefined;\n }\n // kitConfig is already expected to be Record<string, unknown> or undefined by UiKitConfiguration type.\n // We just ensure it's not null and is an object here for safety if it were `any` somewhere up the chain.\n if (typeof config.kitConfig === 'object' && config.kitConfig !== null) {\n return config.kitConfig as Record<string, unknown>;\n }\n logger.warn('rainbowkit/utils', 'kitConfig for RainbowKit is not a valid object.');\n return undefined;\n}\n","import { Loader2 } from 'lucide-react';\nimport React, { useContext, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport { cn, getWalletButtonSizeProps, logger } from '@openzeppelin/ui-utils';\n\nimport { CustomConnectButton } from '../components';\nimport { WagmiProviderInitializedContext } from '../context';\nimport type { UiKitManager } from '../uiKitManager';\nimport { extractRainbowKitCustomizations } from './types';\n\nconst MIN_COMPONENT_LOADING_DISPLAY_MS = 1000; // 1 second artificial delay\n\n/**\n * Props for the RainbowKitConnectButton component created by the factory.\n */\nexport type RainbowKitConnectButtonProps = BaseComponentProps;\n\n/**\n * Creates a RainbowKitConnectButton component that uses the provided UI kit manager.\n * This factory pattern allows adapters to inject their specific UI kit manager instance.\n *\n * @param uiKitManager - The UI kit manager instance to use for state management\n * @returns A React component that renders the RainbowKit ConnectButton\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * import { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { evmUiKitManager } from './evmUiKitManager';\n *\n * export const RainbowKitConnectButton = createRainbowKitConnectButton(evmUiKitManager);\n *\n * // In adapter-polkadot:\n * import { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { polkadotUiKitManager } from './polkadotUiKitManager';\n *\n * export const RainbowKitConnectButton = createRainbowKitConnectButton(polkadotUiKitManager);\n * ```\n */\nexport function createRainbowKitConnectButton(\n uiKitManager: UiKitManager\n): React.FC<RainbowKitConnectButtonProps> {\n const RainbowKitConnectButtonComponent: React.FC<RainbowKitConnectButtonProps> = (props) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [Component, setComponent] = useState<React.ComponentType<any> | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const [isLoadingComponent, setIsLoadingComponent] = useState(true);\n const [showComponentLoadingOverride, setShowComponentLoadingOverride] = useState(false);\n const componentLoadingTimerRef = useRef<NodeJS.Timeout | null>(null);\n const [managerState, setManagerState] = useState(uiKitManager.getState());\n\n const isWagmiProviderReady = useContext(WagmiProviderInitializedContext);\n\n // Subscribe to UI kit manager state changes\n useEffect(() => {\n const unsubscribe = uiKitManager.subscribe(() => {\n setManagerState(uiKitManager.getState());\n });\n return unsubscribe;\n }, []);\n\n useEffect(() => {\n let isMounted = true;\n setIsLoadingComponent(true);\n setShowComponentLoadingOverride(true); // Start showing override immediately\n\n if (componentLoadingTimerRef.current) {\n clearTimeout(componentLoadingTimerRef.current);\n }\n componentLoadingTimerRef.current = setTimeout(() => {\n if (isMounted) {\n setShowComponentLoadingOverride(false);\n }\n componentLoadingTimerRef.current = null;\n }, MIN_COMPONENT_LOADING_DISPLAY_MS);\n\n const loadComponent = async () => {\n try {\n const rainbowKit = await import('@rainbow-me/rainbowkit');\n if (isMounted) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setComponent(() => rainbowKit.ConnectButton as React.ComponentType<any>);\n // Actual component loading is done, but override might still be active\n setIsLoadingComponent(false);\n }\n } catch (err) {\n if (isMounted) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoadingComponent(false); // Finished loading (with an error)\n logger.error(\n 'RainbowKitConnectButton',\n 'Failed to load RainbowKit ConnectButton:',\n err\n );\n }\n }\n };\n\n loadComponent();\n\n return () => {\n isMounted = false;\n if (componentLoadingTimerRef.current) {\n clearTimeout(componentLoadingTimerRef.current);\n }\n };\n }, []); // Effect for dynamic import runs once\n\n const sizeProps = getWalletButtonSizeProps(props.size);\n\n const renderLoadingPlaceholder = (message: string) => (\n <Button\n disabled={true}\n variant={props.variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, props.fullWidth && 'w-full', props.className)}\n >\n <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1.5')} />\n {message}\n </Button>\n );\n\n if (error) {\n logger.warn(\n 'RainbowKitConnectButton',\n 'Error loading RainbowKit ConnectButton. Displaying fallback CustomConnectButton.'\n );\n return <CustomConnectButton {...props} />;\n }\n\n // Show \"Loading Wallet...\" if component is still factually loading OR if the override is active\n if (isLoadingComponent || showComponentLoadingOverride) {\n return renderLoadingPlaceholder('Loading Wallet...');\n }\n // At this point, component import has finished (successfully or not handled by error state)\n // AND the minimum display time for \"Loading Wallet...\" has passed.\n\n // Now check if the provider context is ready\n if (!isWagmiProviderReady) {\n // No separate delay for this message; it appears if context isn't ready after component load delay.\n return renderLoadingPlaceholder('Initializing Provider...');\n }\n\n // Component should be non-null here if no error and not isLoadingComponent\n if (!Component) {\n // This case should ideally not be hit if logic is correct, but as a safeguard:\n logger.warn(\n 'RainbowKitConnectButton',\n 'Component is null after loading phase, falling back.'\n );\n return <CustomConnectButton {...props} />;\n }\n\n // Extract custom configuration from the manager state\n const kitConfig = managerState.currentFullUiKitConfig?.kitConfig;\n const customizations = extractRainbowKitCustomizations(kitConfig);\n const connectButtonConfig = customizations?.connectButton;\n\n // Merge props: base props + custom configuration + any overrides from props\n // This allows the config to set defaults while still allowing prop overrides\n const finalProps = {\n ...connectButtonConfig, // Apply custom configuration from config\n ...props, // Allow props to override configuration\n };\n\n logger.debug('RainbowKitConnectButton', 'Rendering with configuration:', {\n configFromFile: connectButtonConfig,\n finalProps: finalProps,\n });\n\n return <Component {...finalProps} />;\n };\n\n // Set display name for debugging\n RainbowKitConnectButtonComponent.displayName = 'RainbowKitConnectButton';\n\n return RainbowKitConnectButtonComponent;\n}\n","import type { BaseComponentProps, EcosystemWalletComponents } from '@openzeppelin/ui-types';\n\n/**\n * Creates the complete set of RainbowKit wallet components.\n *\n * This factory function accepts a RainbowKitConnectButton component that has been\n * created with an adapter-specific UI kit manager. This allows different adapters\n * to use their own manager instance while sharing the component creation logic.\n *\n * @param RainbowKitConnectButton - The connect button component created via createRainbowKitConnectButton\n * @returns An object containing all RainbowKit wallet components\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * import { createRainbowKitConnectButton, createRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { evmUiKitManager } from './evmUiKitManager';\n *\n * const RainbowKitConnectButton = createRainbowKitConnectButton(evmUiKitManager);\n * const components = createRainbowKitComponents(RainbowKitConnectButton);\n *\n * // In adapter-polkadot:\n * import { createRainbowKitConnectButton, createRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { polkadotUiKitManager } from './polkadotUiKitManager';\n *\n * const RainbowKitConnectButton = createRainbowKitConnectButton(polkadotUiKitManager);\n * const components = createRainbowKitComponents(RainbowKitConnectButton);\n * ```\n */\nexport function createRainbowKitComponents(\n RainbowKitConnectButton: React.ComponentType<BaseComponentProps>\n): EcosystemWalletComponents {\n return {\n ConnectButton: RainbowKitConnectButton,\n // RainbowKit's ConnectButton is comprehensive and typically includes account display\n // So we don't provide separate AccountDisplay or NetworkSwitcher components\n };\n}\n","/**\n * RainbowKit Config Service\n *\n * Creates Wagmi configuration for RainbowKit. This is shared between\n * EVM and Polkadot adapters to avoid code duplication.\n */\nimport { Config, http } from '@wagmi/core';\nimport { type Chain } from 'viem';\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WagmiConfigChains } from '../types';\n\nconst LOG_PREFIX = 'rainbowkit/config-service';\n\n/**\n * Creates a Wagmi configuration for RainbowKit using getDefaultConfig\n *\n * @param userFullNativeConfig The full native configuration object. This object IS the result of merging\n * AppConfigService settings, user's native rainbowkit.config.ts, and programmatic overrides.\n * It is expected to contain a `wagmiParams` object for RainbowKit's getDefaultConfig\n * and potentially a `providerProps` object for RainbowKitProvider.\n * @param chains Array of viem Chain objects - will be safely cast to wagmi's expected chain type\n * @param chainIdToNetworkIdMap Mapping of chain IDs to network IDs for RPC override lookups\n * @param getRpcEndpointOverride Function to get RPC endpoint overrides\n * @returns Wagmi configuration for RainbowKit or null if creation fails\n */\nexport async function createRainbowKitWagmiConfig(\n userFullNativeConfig: Record<string, unknown> | undefined | null, // This is the fully resolved kitConfig\n chains: readonly Chain[],\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcEndpointOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n): Promise<Config | null> {\n try {\n const { getDefaultConfig } = await import('@rainbow-me/rainbowkit');\n if (!getDefaultConfig) {\n logger.error(LOG_PREFIX, 'Failed to import getDefaultConfig from RainbowKit');\n return null;\n }\n\n // userFullNativeConfig *is* the kitConfig here. Its wagmiParams are what we need.\n const wagmiParams = userFullNativeConfig?.wagmiParams as Record<string, unknown> | undefined;\n\n if (!wagmiParams) {\n logger.warn(\n LOG_PREFIX,\n 'Resolved kitConfig does not contain a `wagmiParams` object. Cannot create RainbowKit Wagmi config.'\n );\n return null;\n }\n\n // Ensure essential appName and projectId are present in user's wagmiParams\n if (typeof wagmiParams.appName !== 'string' || !wagmiParams.appName) {\n logger.warn(LOG_PREFIX, 'kitConfig.wagmiParams is missing or has invalid `appName`.');\n return null;\n }\n if (typeof wagmiParams.projectId !== 'string' || !wagmiParams.projectId) {\n logger.warn(LOG_PREFIX, 'kitConfig.wagmiParams is missing or has invalid `projectId`.');\n return null;\n }\n\n // Build transport configuration with RPC overrides as needed.\n // This iterates over the adapter-determined chains and creates a transport\n // for each, applying any RPC overrides specified via AppConfigService.\n const transportsConfig = chains.reduce(\n (acc, chainDefinition) => {\n let rpcUrlToUse: string | undefined = chainDefinition.rpcUrls.default?.http?.[0];\n const appNetworkIdString = chainIdToNetworkIdMap[chainDefinition.id];\n\n if (appNetworkIdString) {\n const rpcOverrideSetting = getRpcEndpointOverride(appNetworkIdString);\n let httpRpcOverride: string | undefined;\n\n // Extract HTTP RPC URL from override setting\n if (typeof rpcOverrideSetting === 'string') {\n httpRpcOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting) {\n // Handle both RpcEndpointConfig and UserRpcProviderConfig\n if ('http' in rpcOverrideSetting && rpcOverrideSetting.http) {\n httpRpcOverride = rpcOverrideSetting.http;\n } else if ('url' in rpcOverrideSetting && rpcOverrideSetting.url) {\n // Handle UserRpcProviderConfig\n httpRpcOverride = rpcOverrideSetting.url as string;\n }\n }\n\n if (httpRpcOverride) {\n logger.info(\n LOG_PREFIX,\n `Using overridden RPC for chain ${chainDefinition.name}: ${httpRpcOverride}`\n );\n rpcUrlToUse = httpRpcOverride;\n }\n }\n\n acc[chainDefinition.id] = http(rpcUrlToUse);\n return acc;\n },\n {} as Record<number, ReturnType<typeof http>>\n );\n\n // Spread all user-provided wagmiParams, then override chains and transports\n const finalConfigOptions = {\n ...wagmiParams, // User's native params (appName, projectId, wallets, ssr, etc.)\n chains: chains as WagmiConfigChains, // Adapter controls this\n transports: transportsConfig, // Adapter controls this\n };\n\n // The `wallets` property from user config is of type `unknown` on our side if accessed directly from wagmiParams.\n // RainbowKit's `getDefaultConfig` expects a specific `WalletList` type for `wallets`.\n // By spreading `wagmiParams`, we pass whatever structure the user provided.\n // We use `eslint-disable-next-line @typescript-eslint/no-explicit-any` here to pass through\n // the user-provided structure directly, relying on RainbowKit to perform its own validation or type checking internally.\n // This aligns with our principle of not mimicking complex third-party types for pass-through configuration.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const config = getDefaultConfig(finalConfigOptions as any);\n\n logger.info(LOG_PREFIX, 'Successfully created RainbowKit Wagmi config object.', config);\n return config;\n } catch (error) {\n logger.error(LOG_PREFIX, 'Error creating RainbowKit Wagmi config:', error);\n return null;\n }\n}\n\n/**\n * Gets the Wagmi configuration for RainbowKit based on the global UI kit settings.\n * This function is intended to be called by WagmiWalletImplementation.\n *\n * @param uiKitConfiguration The UI kit configuration object from UiKitManager (contains the resolved kitConfig).\n * @param chains Array of viem Chain objects to use with RainbowKit\n * @param chainIdToNetworkIdMap Mapping of chain IDs to network IDs for RPC override lookups\n * @param getRpcEndpointOverride Function to get RPC endpoint overrides\n * @returns The wagmi Config object or null if invalid or not RainbowKit\n */\nexport async function getWagmiConfigForRainbowKit(\n uiKitConfiguration: UiKitConfiguration | undefined,\n chains: readonly Chain[],\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcEndpointOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n): Promise<Config | null> {\n if (\n !uiKitConfiguration ||\n uiKitConfiguration.kitName !== 'rainbowkit' ||\n !uiKitConfiguration.kitConfig // kitConfig is the fully resolved config here\n ) {\n logger.debug(\n LOG_PREFIX,\n 'Not configured for RainbowKit or kitConfig (resolved native + programmatic) is missing.'\n );\n return null;\n }\n\n // userFullNativeConfig for createRainbowKitWagmiConfig IS uiKitConfiguration.kitConfig\n const resolvedKitConfig = uiKitConfiguration.kitConfig as Record<string, unknown>;\n\n return createRainbowKitWagmiConfig(\n resolvedKitConfig, // Pass the resolved kitConfig\n chains,\n chainIdToNetworkIdMap,\n getRpcEndpointOverride\n );\n}\n","/**\n * UI Kit Manager Factory\n *\n * Provides a factory function to create UI kit managers for EVM-compatible adapters.\n * This shared implementation handles state management, subscriptions, and configuration\n * for UI kits like RainbowKit.\n *\n * @module wallet/uiKitManager\n */\n\nimport type { Config as WagmiConfig } from '@wagmi/core';\nimport type React from 'react';\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WagmiWalletImplementation } from './wagmi-implementation';\n\n/**\n * State interface for UI Kit Manager.\n * Tracks the current UI kit configuration, wagmi config, and loading states.\n */\nexport interface UiKitManagerState {\n /** The current full UI kit configuration */\n currentFullUiKitConfig: UiKitConfiguration | null;\n /** The active wagmi configuration */\n wagmiConfig: WagmiConfig | null;\n /** The UI kit provider component (e.g., RainbowKitProvider) */\n kitProviderComponent: React.ComponentType<React.PropsWithChildren<unknown>> | null;\n /** Whether the UI kit assets have been loaded */\n isKitAssetsLoaded: boolean;\n /** Whether the manager is currently initializing */\n isInitializing: boolean;\n /** Any error that occurred during configuration */\n error: Error | null;\n}\n\n/**\n * Result type for loading RainbowKit assets.\n */\nexport interface RainbowKitAssetsResult {\n /** The provider component to wrap the app, or null if loading failed */\n ProviderComponent: React.ComponentType<React.PropsWithChildren<unknown>> | null;\n /** Whether CSS was loaded successfully */\n cssLoaded: boolean;\n}\n\n/**\n * Dependencies required by the UI Kit Manager factory.\n */\nexport interface UiKitManagerDependencies {\n /**\n * Function to get the wallet implementation.\n * Can be sync or async to support both EVM (async) and Polkadot (sync) patterns.\n */\n getWalletImplementation: () => WagmiWalletImplementation | Promise<WagmiWalletImplementation>;\n\n /**\n * Function to load RainbowKit assets (provider component and CSS).\n */\n loadRainbowKitAssets: () => Promise<RainbowKitAssetsResult>;\n\n /**\n * Log prefix for identifying the adapter in logs.\n */\n logPrefix: string;\n}\n\n/**\n * Interface for the UI Kit Manager returned by the factory.\n */\nexport interface UiKitManager {\n /** Get the current state */\n getState: () => UiKitManagerState;\n /** Subscribe to state changes */\n subscribe: (listener: () => void) => () => void;\n /** Configure the UI kit with new settings */\n configure: (newFullUiKitConfig: UiKitConfiguration) => Promise<void>;\n}\n\n/**\n * Creates a UI Kit Manager instance with the provided dependencies.\n *\n * @param deps - The dependencies for the UI Kit Manager\n * @returns A UI Kit Manager instance with getState, subscribe, and configure methods\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * const evmUiKitManager = createUiKitManager({\n * getWalletImplementation: getEvmWalletImplementation,\n * loadRainbowKitAssets: async () => {\n * const { ensureRainbowKitAssetsLoaded } = await import('./rainbowkit/rainbowkitAssetManager');\n * return ensureRainbowKitAssetsLoaded();\n * },\n * logPrefix: 'EvmUiKitManager',\n * });\n *\n * // In adapter-polkadot:\n * const polkadotUiKitManager = createUiKitManager({\n * getWalletImplementation: () => getPolkadotWalletImplementation(),\n * loadRainbowKitAssets: async () => {\n * const { ensureRainbowKitAssetsLoaded } = await import('./rainbowkit/rainbowkitAssetManager');\n * return ensureRainbowKitAssetsLoaded();\n * },\n * logPrefix: 'PolkadotUiKitManager',\n * });\n * ```\n */\nexport function createUiKitManager(deps: UiKitManagerDependencies): UiKitManager {\n const { getWalletImplementation, loadRainbowKitAssets, logPrefix } = deps;\n\n const initialState: UiKitManagerState = {\n currentFullUiKitConfig: null,\n wagmiConfig: null,\n kitProviderComponent: null,\n isKitAssetsLoaded: false,\n isInitializing: false,\n error: null,\n };\n\n let state: UiKitManagerState = { ...initialState };\n const listeners: Set<() => void> = new Set();\n\n function notifyListeners(): void {\n listeners.forEach((listener) => {\n try {\n listener();\n } catch (error) {\n logger.error(logPrefix, 'Error in listener:', error);\n }\n });\n }\n\n function subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function getState(): UiKitManagerState {\n return { ...state }; // Return a copy to prevent direct mutation\n }\n\n async function configure(newFullUiKitConfig: UiKitConfiguration): Promise<void> {\n logger.info(`${logPrefix}:configure`, 'Configuring UI kit. New config:', newFullUiKitConfig);\n\n const oldKitName = state.currentFullUiKitConfig?.kitName;\n const newKitName = newFullUiKitConfig.kitName;\n const kitChanged = oldKitName !== newKitName;\n\n state = {\n ...state,\n isInitializing: true,\n error: null,\n currentFullUiKitConfig: newFullUiKitConfig,\n kitProviderComponent: kitChanged ? null : state.kitProviderComponent,\n isKitAssetsLoaded: kitChanged ? false : state.isKitAssetsLoaded,\n };\n notifyListeners();\n\n let newWagmiConfigAttempt: WagmiConfig | null = null;\n const walletImpl = await Promise.resolve(getWalletImplementation());\n\n try {\n if (newKitName === 'rainbowkit') {\n if (kitChanged || !state.kitProviderComponent || !state.isKitAssetsLoaded) {\n logger.info(`${logPrefix}:configure`, 'Ensuring RainbowKit assets are loaded...');\n const rkAssets = await loadRainbowKitAssets();\n state.kitProviderComponent = rkAssets.ProviderComponent;\n state.isKitAssetsLoaded = rkAssets.cssLoaded && !!rkAssets.ProviderComponent;\n if (!state.isKitAssetsLoaded) {\n throw new Error('Failed to load critical RainbowKit assets.');\n }\n }\n newWagmiConfigAttempt = await walletImpl.getConfigForRainbowKit(newFullUiKitConfig);\n logger.info(`${logPrefix}:configure`, 'WagmiConfig for RainbowKit obtained.');\n } else if (newKitName === 'custom' || !newKitName) {\n newWagmiConfigAttempt = await walletImpl.getActiveConfigForManager(newFullUiKitConfig);\n logger.info(`${logPrefix}:configure`, 'ActiveConfig for custom/default obtained.');\n if (kitChanged) {\n state.kitProviderComponent = null;\n state.isKitAssetsLoaded = false;\n }\n } else {\n logger.warn(`${logPrefix}:configure`, `Unsupported kitName: ${newKitName}.`);\n state.kitProviderComponent = null;\n state.isKitAssetsLoaded = false;\n }\n\n state.wagmiConfig = newWagmiConfigAttempt;\n walletImpl.setActiveWagmiConfig(state.wagmiConfig);\n state.error = null;\n if (\n !newWagmiConfigAttempt &&\n newKitName &&\n newKitName !== 'none' &&\n newKitName !== 'custom'\n ) {\n state.error = new Error(`Failed to obtain WagmiConfig for ${newKitName}`);\n logger.error(`${logPrefix}:configure`, state.error.message);\n }\n } catch (err) {\n logger.error(`${logPrefix}:configure`, 'Error during UI kit configuration process:', err);\n state.error = err instanceof Error ? err : new Error(String(err));\n state.wagmiConfig = null;\n walletImpl.setActiveWagmiConfig(null);\n } finally {\n state.isInitializing = false;\n logger.info(\n `${logPrefix}:configure`,\n 'Configuration attempt finished. Final wagmiConfig:',\n state.wagmiConfig ? 'Set' : 'Null',\n 'Kit Provider Component:',\n state.kitProviderComponent ? 'Set' : 'Null',\n 'Kit Assets Loaded:',\n state.isKitAssetsLoaded,\n 'Error state:',\n state.error ? state.error.message : 'None'\n );\n notifyListeners();\n }\n }\n\n return {\n getState,\n subscribe,\n configure,\n };\n}\n","/**\n * RainbowKit Asset Manager\n *\n * Ensures RainbowKit provider component and CSS are loaded dynamically.\n * This module provides shared asset loading functionality for all EVM-compatible adapters.\n *\n * Having the cache in core means RainbowKit assets only load once even if multiple adapters\n * (e.g., both EVM and Polkadot) are used - this is the desired behavior for optimal performance.\n *\n * @module wallet/rainbowkitAssetManager\n */\n\nimport type React from 'react';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { RainbowKitAssetsResult } from './uiKitManager';\n\n// Re-export the type for convenience\nexport type { RainbowKitAssetsResult };\n\n// Module-level cache for loaded assets\nlet loadedAssets: RainbowKitAssetsResult | null = null;\n\n// Promises to ensure assets are loaded only once\nlet providerPromise: Promise<React.ComponentType<React.PropsWithChildren<unknown>> | null> | null =\n null;\nlet cssPromise: Promise<boolean> | null = null;\n\nconst LOG_PREFIX = 'RainbowKitAssetManager';\n\n/**\n * Ensures RainbowKit provider component and CSS are loaded.\n * Loads them dynamically only once and caches the result.\n *\n * @returns A promise resolving to an object containing the ProviderComponent and cssLoaded status.\n */\nexport async function ensureRainbowKitAssetsLoaded(): Promise<RainbowKitAssetsResult> {\n if (loadedAssets) {\n logger.debug(LOG_PREFIX, 'Assets already loaded, returning cached.');\n return loadedAssets;\n }\n\n if (!providerPromise) {\n providerPromise = import('@rainbow-me/rainbowkit')\n .then((module) => {\n const component = module.RainbowKitProvider as React.ComponentType<\n React.PropsWithChildren<unknown>\n >;\n logger.info(LOG_PREFIX, 'RainbowKitProvider module loaded.');\n return component;\n })\n .catch((err) => {\n logger.error(LOG_PREFIX, 'Failed to load RainbowKitProvider module:', err);\n return null; // Resolve with null on error to allow Promise.all to complete\n });\n }\n\n if (!cssPromise) {\n cssPromise = import('@rainbow-me/rainbowkit/styles.css')\n .then(() => {\n logger.info(LOG_PREFIX, 'RainbowKit CSS loaded successfully.');\n return true;\n })\n .catch((err) => {\n logger.error(LOG_PREFIX, 'Failed to load RainbowKit CSS:', err);\n return false; // Resolve with false on error\n });\n }\n\n try {\n const [ProviderComponent, cssLoadedSuccess] = await Promise.all([providerPromise, cssPromise]);\n\n loadedAssets = { ProviderComponent, cssLoaded: cssLoadedSuccess };\n if (!ProviderComponent || !cssLoadedSuccess) {\n logger.warn(LOG_PREFIX, 'One or more RainbowKit assets failed to load.', loadedAssets);\n // Potentially throw here if assets are critical, or let caller decide based on null/false\n }\n return loadedAssets;\n } catch (error) {\n // This catch is for Promise.all failing, though individual catches should handle module errors.\n logger.error(LOG_PREFIX, 'Error in Promise.all for asset loading:', error);\n loadedAssets = { ProviderComponent: null, cssLoaded: false }; // Ensure loadedAssets is set\n return loadedAssets;\n }\n}\n","/**\n * Configuration Resolution Module\n *\n * Provides utilities for resolving and merging UI kit configurations\n * from various sources (native config files, programmatic overrides, app service).\n *\n * @module configResolution\n */\n\nimport type { NativeConfigLoader, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nconst LOG_PREFIX = 'ConfigResolutionService';\n\n/**\n * Resolves and initializes the kit-specific configuration.\n * This function acts as a manager to call the appropriate kit's configuration initializer.\n *\n * @param kitName The name of the UI kit (e.g., 'rainbowkit').\n * @param programmaticKitConfig Optional base/programmatic config passed to the kit initializer.\n * @param loadConfigModule Optional generic callback to load configuration modules by path.\n * @returns A Promise resolving to the final kitConfig (Record<string, unknown>) for the specified kit, or null.\n */\nexport async function resolveAndInitializeKitConfig(\n kitName?: string, // kitName is used to construct the path to the conventional config file\n programmaticKitConfig?: Record<string, unknown>,\n loadConfigModule?: NativeConfigLoader\n): Promise<Record<string, unknown> | null> {\n logger.debug(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `Resolving native config for kit: ${kitName || 'none'}`,\n {\n hasProgrammaticKitConfig: !!programmaticKitConfig,\n hasLoadConfigModule: !!loadConfigModule,\n }\n );\n\n let userNativeConfig: Record<string, unknown> | null = null;\n\n // Only attempt to load a native config if a kitName is provided and a loader function exists.\n // And the kitName is not 'custom' or 'none' as those typically don't have dedicated native config files.\n if (kitName && kitName !== 'custom' && kitName !== 'none' && loadConfigModule) {\n const conventionalConfigPath = `./config/wallet/${kitName}.config.ts`;\n\n try {\n userNativeConfig = await loadConfigModule(conventionalConfigPath);\n } catch (error) {\n logger.warn(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `Call to load native config for ${kitName} from ${conventionalConfigPath} failed. Error:`,\n error\n );\n }\n }\n\n // Merge the loaded user native config with the programmatically passed kitConfig.\n // Programmatic config can override or augment the native file's settings.\n if (userNativeConfig && programmaticKitConfig) {\n const mergedConfig = { ...userNativeConfig, ...programmaticKitConfig };\n return mergedConfig;\n } else if (userNativeConfig) {\n return userNativeConfig;\n } else if (programmaticKitConfig) {\n return programmaticKitConfig;\n }\n\n logger.debug(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `No native or programmatic kitConfig provided for ${kitName || 'none'}. Returning null.`\n );\n return null;\n}\n\n/**\n * Resolves the final, complete UiKitConfiguration by merging various sources.\n *\n * @param programmaticOverrides - Overrides passed directly to the configureUiKit call.\n * @param initialAppServiceKitName - The kitName noted from AppConfigService when the adapter instance was constructed.\n * @param currentAppServiceConfig - The full UiKitConfiguration from AppConfigService, re-fetched at the time of the call.\n * @param options - Options, including the callback to load user's native config file.\n * @returns A Promise resolving to the final UiKitConfiguration.\n */\nexport async function resolveFullUiKitConfiguration(\n programmaticOverrides: Partial<UiKitConfiguration>,\n initialAppServiceKitName: UiKitConfiguration['kitName'],\n currentAppServiceConfig: UiKitConfiguration, // This is the result of loadInitialConfigFromAppService()\n options?: {\n loadUiKitNativeConfig?: NativeConfigLoader;\n }\n): Promise<UiKitConfiguration> {\n logger.debug(`${LOG_PREFIX}:resolveFullUiKitConfiguration`, 'Starting resolution with:', {\n programmaticOverrides,\n initialAppServiceKitName,\n currentAppServiceConfig,\n hasLoadNativeCallback: !!options?.loadUiKitNativeConfig,\n hasCustomCode: !!programmaticOverrides.customCode,\n });\n\n const effectiveKitName: UiKitConfiguration['kitName'] =\n programmaticOverrides.kitName ||\n initialAppServiceKitName ||\n currentAppServiceConfig.kitName ||\n 'custom';\n\n // Resolve from native config file (if loader is provided)\n const resolvedUserNativeAndProgrammaticKitConfig = await resolveAndInitializeKitConfig(\n effectiveKitName,\n programmaticOverrides.kitConfig,\n options?.loadUiKitNativeConfig\n );\n\n const finalFullConfig: UiKitConfiguration = {\n kitName: effectiveKitName,\n kitConfig: {\n ...(currentAppServiceConfig.kitConfig || {}),\n ...(resolvedUserNativeAndProgrammaticKitConfig || {}),\n // customCode is NOT applied to runtime config\n },\n // Pass through customCode for export purposes only\n customCode: programmaticOverrides.customCode,\n };\n\n logger.debug(\n `${LOG_PREFIX}:resolveFullUiKitConfiguration`,\n 'Resolved finalFullConfig:',\n finalFullConfig\n );\n return finalFullConfig;\n}\n","import type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { ECOSYSTEM_WALLET_COMPONENT_KEYS } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Filters a set of wallet components based on an exclusion list.\n *\n * @param allPossibleComponents - An object containing all potential components for a kit.\n * @param exclusions - An array of component keys to exclude.\n * @param kitName - The name of the kit being filtered (for logging purposes).\n * @returns The filtered EcosystemWalletComponents object, or undefined if all components are excluded.\n */\nexport function filterWalletComponents(\n allPossibleComponents: EcosystemWalletComponents,\n exclusions: Array<keyof EcosystemWalletComponents>,\n kitName: string = 'custom' // Default to custom for logging context\n): EcosystemWalletComponents | undefined {\n logger.debug(\n 'filterWalletComponents',\n `Filtering components for kit: ${kitName}. Exclusions: ${exclusions.join(', ')}.`\n );\n if (!allPossibleComponents || Object.keys(allPossibleComponents).length === 0) {\n logger.debug('filterWalletComponents', `No components provided to filter for kit: ${kitName}.`);\n return undefined;\n }\n\n if (exclusions.length === 0) {\n logger.debug(\n 'filterWalletComponents',\n `Providing all components for kit: ${kitName}.`,\n allPossibleComponents\n );\n return allPossibleComponents;\n }\n\n const filteredComponents: Partial<EcosystemWalletComponents> = {};\n let componentCount = 0;\n for (const key in allPossibleComponents) {\n const componentKey = key as keyof EcosystemWalletComponents;\n if (!exclusions.includes(componentKey)) {\n if (allPossibleComponents[componentKey]) {\n // Ensure the component actually exists before adding\n filteredComponents[componentKey] = allPossibleComponents[componentKey];\n componentCount++;\n }\n }\n }\n\n if (componentCount > 0) {\n logger.debug(\n 'filterWalletComponents',\n `Providing filtered components for kit: ${kitName} after exclusions (${exclusions.join(', ')}).`,\n filteredComponents\n );\n return filteredComponents as EcosystemWalletComponents;\n }\n\n logger.debug('filterWalletComponents', `All components were excluded for kit: ${kitName}.`);\n return undefined;\n}\n\n/**\n * Extracts the component exclusion list from a UI kit configuration object.\n *\n * @param kitConfig - The `kitConfig` object from `UiKitConfiguration`.\n * @returns An array of component keys to exclude, or an empty array if none are specified or config is invalid.\n */\nexport function getComponentExclusionsFromConfig(\n kitConfig: UiKitConfiguration['kitConfig']\n): Array<keyof EcosystemWalletComponents> {\n if (kitConfig && typeof kitConfig === 'object' && 'components' in kitConfig) {\n const componentsCfg = kitConfig.components;\n if (\n componentsCfg &&\n typeof componentsCfg === 'object' &&\n 'exclude' in componentsCfg &&\n Array.isArray(componentsCfg.exclude)\n ) {\n // Ensure all elements are valid keys of EcosystemWalletComponents\n // This provides a bit more type safety at runtime if the config comes from an untyped source\n return componentsCfg.exclude.filter(\n (key): key is keyof EcosystemWalletComponents =>\n typeof key === 'string' &&\n (ECOSYSTEM_WALLET_COMPONENT_KEYS as readonly string[]).includes(key)\n ) as Array<keyof EcosystemWalletComponents>;\n }\n }\n return [];\n}\n","/**\n * Validation Module\n *\n * Execution configuration validation for EVM transactions.\n *\n * @module validation\n */\n\nexport { validateEoaConfig, validateEvmEoaConfig, type EvmWalletStatus } from './eoa';\nexport { validateRelayerConfig, validateEvmRelayerConfig } from './relayer';\nexport { validateEvmExecutionConfig } from './execution';\n\n// Re-export address validation from utils for convenience\nexport { isValidEvmAddress } from '../utils/validation';\n","import type { RelayerExecutionConfig } from '@openzeppelin/ui-types';\n\n/**\n * Validates a relayer execution configuration.\n *\n * @param config The relayer execution config to validate\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateRelayerConfig(\n config: RelayerExecutionConfig\n): Promise<true | string> {\n if (!config.serviceUrl) {\n return 'Relayer execution selected, but no service URL was provided.';\n }\n if (!config.relayer?.relayerId) {\n return 'Relayer execution selected, but no relayer was chosen from the list.';\n }\n return true;\n}\n\n/**\n * Simple validation of relayer config.\n * Useful for static validation before execution.\n */\nexport function validateEvmRelayerConfig(config: RelayerExecutionConfig): boolean {\n if (!config.serviceUrl) {\n return false;\n }\n if (!config.relayer?.relayerId) {\n return false;\n }\n return true;\n}\n","/**\n * Execution Configuration Validation\n *\n * Central validation router for EVM execution configurations.\n * Delegates to specific validators based on execution method type.\n */\n\nimport type {\n EoaExecutionConfig,\n ExecutionConfig,\n RelayerExecutionConfig,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { validateEoaConfig, type EvmWalletStatus } from './eoa';\nimport { validateRelayerConfig } from './relayer';\n\nconst SYSTEM_LOG_TAG = 'evm-execution-config';\n\n/**\n * Validates the complete execution configuration object against the\n * requirements and capabilities of EVM-compatible adapters.\n *\n * @param config The execution configuration to validate\n * @param walletStatus The wallet connection status for validation\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateEvmExecutionConfig(\n config: ExecutionConfig,\n walletStatus: EvmWalletStatus\n): Promise<true | string> {\n logger.info(SYSTEM_LOG_TAG, 'Validating EVM execution config:', { config, walletStatus });\n\n switch (config.method) {\n case 'eoa':\n return validateEoaConfig(config as EoaExecutionConfig, walletStatus);\n case 'relayer':\n return validateRelayerConfig(config as RelayerExecutionConfig);\n case 'multisig':\n return 'Multisig execution is not yet supported';\n default: {\n const unknownMethod = (config as ExecutionConfig).method;\n logger.warn(SYSTEM_LOG_TAG, `Unsupported execution method type: ${unknownMethod}`);\n return `Unsupported execution method: ${unknownMethod}`;\n }\n }\n}\n","/**\n * @openzeppelin/ui-builder-adapter-evm-core\n *\n * Core EVM blockchain adapter functionality extracted from adapter-evm.\n * This package provides reusable, stateless modules for EVM-compatible adapters.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// ABI Module - ABI loading, transformation, and comparison\n// ============================================================================\nexport {\n // Transformation\n transformAbiToSchema,\n createAbiFunctionItem,\n // Loading\n loadEvmContract,\n loadAbiFromEtherscan,\n loadAbiFromEtherscanV1,\n loadAbiFromEtherscanV2,\n loadAbiFromSourcify,\n getSourcifyContractAppUrl,\n shouldUseV2Api,\n testEtherscanV2Connection,\n // Convenience wrappers\n loadContractSchema,\n loadContractWithFullMetadata,\n compareContractDefinitions,\n validateContractDefinition,\n hashContractDefinition,\n // Comparison\n AbiComparisonService,\n abiComparisonService,\n // Types\n type EvmContractLoadResult,\n type ContractLoadOptions,\n type EtherscanAbiResult,\n type SourcifyAbiResult,\n type AbiComparisonResult,\n type AbiDifference,\n type AbiValidationResult,\n isValidAbiArray,\n isValidAbiItem,\n} from './abi';\n\n// ============================================================================\n// Mapping Module - Type mapping and form field generation\n// ============================================================================\nexport {\n // Type mapping\n mapEvmParamTypeToFieldType,\n getEvmCompatibleFieldTypes,\n EVM_TYPE_TO_FIELD_TYPE,\n getEvmTypeMappingInfo,\n // Field generation\n generateEvmDefaultField,\n} from './mapping';\n\n// ============================================================================\n// Transform Module - Input parsing and output formatting\n// ============================================================================\nexport { parseEvmInput, formatEvmFunctionResult } from './transform';\n\n// ============================================================================\n// Query Module - View function querying\n// ============================================================================\nexport { queryEvmViewFunction, isEvmViewFunction } from './query';\n\n// ============================================================================\n// Transaction Module - Transaction formatting, execution strategies, and sending\n// ============================================================================\nexport {\n // Formatting\n formatEvmTransactionData,\n // Execution strategy interface\n type AdapterExecutionStrategy,\n // Execution strategies\n EoaExecutionStrategy,\n RelayerExecutionStrategy,\n type EvmRelayerTransactionOptions,\n // Transaction functions\n executeEvmTransaction,\n signAndBroadcastEvmTransaction,\n waitForEvmTransactionConfirmation,\n // Types\n type EvmWalletImplementation,\n type EvmWalletConnectionStatus,\n type EvmWalletConnectionResult,\n type EvmWalletDisconnectResult,\n} from './transaction';\n\n// ============================================================================\n// Wallet Module - Wallet implementation and UI configuration utilities\n// ============================================================================\nexport {\n // Wagmi provider context\n WagmiProviderInitializedContext,\n // Wagmi hooks\n useIsWagmiProviderInitialized,\n // Wagmi components\n SafeWagmiComponent,\n // Wallet UI components\n CustomConnectButton,\n ConnectorDialog,\n CustomAccountDisplay,\n CustomNetworkSwitcher,\n type ConnectButtonProps,\n // Core connection utilities\n connectAndEnsureCorrectNetworkCore,\n DEFAULT_DISCONNECTED_STATUS,\n // Wallet implementation\n WagmiWalletImplementation,\n type GetWagmiConfigForRainbowKitFn,\n // Wallet types\n type WagmiWalletConfig,\n type WagmiConfigChains,\n type WalletNetworkConfig,\n // RainbowKit utilities\n generateRainbowKitConfigFile,\n generateRainbowKitExportables,\n type RainbowKitConfigOptions,\n // RainbowKit types\n type AppInfo,\n type RainbowKitConnectButtonProps,\n type RainbowKitProviderProps,\n type RainbowKitKitConfig,\n type RainbowKitCustomizations,\n isRainbowKitCustomizations,\n extractRainbowKitCustomizations,\n // RainbowKit utility functions\n validateRainbowKitConfig,\n getRawUserNativeConfig,\n // RainbowKit component factories\n createRainbowKitConnectButton,\n createRainbowKitComponents,\n // RainbowKit config service\n createRainbowKitWagmiConfig,\n getWagmiConfigForRainbowKit,\n // UI Kit Manager factory\n createUiKitManager,\n type UiKitManagerState,\n type UiKitManagerDependencies,\n type UiKitManager,\n type RainbowKitAssetsResult,\n // RainbowKit Asset Manager\n ensureRainbowKitAssetsLoaded,\n // Configuration Resolution\n resolveAndInitializeKitConfig,\n resolveFullUiKitConfiguration,\n // Wallet component filtering utilities\n filterWalletComponents,\n getComponentExclusionsFromConfig,\n} from './wallet';\n\n// ============================================================================\n// Configuration Module - RPC and Explorer configuration\n// ============================================================================\nexport {\n // RPC\n buildRpcUrl,\n getUserRpcUrl,\n resolveRpcUrl,\n validateEvmRpcEndpoint,\n testEvmRpcConnection,\n getEvmCurrentBlock,\n // Explorer\n resolveExplorerConfig,\n resolveExplorerApiKeyFromAppConfig,\n getEvmExplorerAddressUrl,\n getEvmExplorerTxUrl,\n validateEvmExplorerConfig,\n testEvmExplorerConnection,\n // Network service configuration\n validateEvmNetworkServiceConfig,\n testEvmNetworkServiceConnection,\n} from './configuration';\n\n// ============================================================================\n// Proxy Module - Proxy detection and implementation resolution\n// ============================================================================\nexport {\n detectProxyFromAbi,\n getImplementationAddress,\n getAdminAddress,\n type ProxyDetectionResult,\n} from './proxy';\n\n// ============================================================================\n// Validation Module - Execution configuration validation\n// ============================================================================\nexport {\n validateEoaConfig,\n validateEvmEoaConfig,\n validateRelayerConfig,\n validateEvmRelayerConfig,\n validateEvmExecutionConfig,\n isValidEvmAddress,\n type EvmWalletStatus,\n} from './validation';\n\n// ============================================================================\n// Utils Module - Utility functions\n// ============================================================================\nexport {\n // JSON utilities\n stringifyWithBigInt,\n // Formatting\n formatMethodName,\n formatInputName,\n // Gas utilities\n weiToGwei,\n gweiToWei,\n // Artifacts\n validateAndConvertEvmArtifacts,\n} from './utils';\n\n// ============================================================================\n// Types Module - TypeScript type definitions\n// ============================================================================\nexport {\n // Contract artifacts\n type EvmContractArtifacts,\n isEvmContractArtifacts,\n // Provider types\n EvmProviderKeys,\n type EvmContractDefinitionProviderKey,\n EVM_PROVIDER_ORDER_DEFAULT,\n isEvmProviderKey,\n // Network and ABI types\n type EvmCompatibleNetworkConfig,\n type TypedEvmNetworkConfig,\n type AbiItem,\n type WriteContractParameters,\n // Result types\n type EvmAbiLoadResult,\n type EvmProxyInfo,\n type EvmTransactionData,\n} from './types';\n","import { type TransactionReceipt } from 'viem';\nimport React from 'react';\n\n// Core module imports - reusable EVM logic\nimport {\n compareContractDefinitions as coreCompareContractDefinitions,\n hashContractDefinition as coreHashContractDefinition,\n validateContractDefinition as coreValidateContractDefinition,\n EvmProviderKeys,\n executeEvmTransaction,\n formatEvmFunctionResult,\n formatEvmTransactionData,\n generateEvmDefaultField,\n generateRainbowKitConfigFile,\n generateRainbowKitExportables,\n getEvmCompatibleFieldTypes,\n getEvmCurrentBlock,\n getEvmExplorerAddressUrl,\n getEvmExplorerTxUrl,\n getEvmTypeMappingInfo,\n isEvmViewFunction,\n isValidEvmAddress,\n loadContractSchema,\n loadContractWithFullMetadata,\n mapEvmParamTypeToFieldType,\n RelayerExecutionStrategy,\n resolveFullUiKitConfiguration,\n testEvmExplorerConnection,\n testEvmNetworkServiceConnection,\n testEvmRpcConnection,\n validateEvmExecutionConfig,\n validateEvmExplorerConfig,\n validateEvmNetworkServiceConfig,\n validateEvmRpcEndpoint,\n waitForEvmTransactionConfirmation,\n type EvmContractDefinitionProviderKey,\n type TypedEvmNetworkConfig,\n type WriteContractParameters,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type {\n AvailableUiKit,\n Connector,\n ContractAdapter,\n ContractFunction,\n ContractSchema,\n EcosystemReactUiProviderProps,\n EcosystemSpecificReactHooks,\n EcosystemWalletComponents,\n ExecutionConfig,\n ExecutionMethodDetail,\n FieldType,\n FormFieldType,\n FunctionParameter,\n NativeConfigLoader,\n NetworkConfig,\n NetworkServiceForm,\n ProxyInfo,\n RelayerDetails,\n RelayerDetailsRich,\n TransactionStatusUpdate,\n TxStatus,\n TypeMappingInfo,\n UiKitConfiguration,\n UserExplorerConfig,\n UserRpcProviderConfig,\n WalletConnectionStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { EvmWalletUiRoot } from './wallet/components/EvmWalletUiRoot';\nimport { evmUiKitManager } from './wallet/evmUiKitManager';\nimport { evmFacadeHooks } from './wallet/hooks/facade-hooks';\nimport { loadInitialConfigFromAppService } from './wallet/hooks/useUiKitConfig';\n\n// Adapter-specific imports - EVM adapter orchestration\nimport {\n getEvmDefaultServiceConfig,\n getEvmNetworkServiceForms,\n getEvmSupportedExecutionMethods,\n} from './configuration';\n// Adapter-specific query with RPC resolution\nimport { queryEvmViewFunction } from './query';\nimport { EvmRelayerOptions } from './transaction';\nimport {\n connectAndEnsureCorrectNetwork,\n convertWagmiToEvmStatus,\n disconnectEvmWallet,\n evmSupportsWalletConnection,\n EvmWalletConnectionStatus,\n getEvmAvailableConnectors,\n getEvmWalletConnectionStatus,\n getEvmWalletImplementation,\n getInitializedEvmWalletImplementation,\n getResolvedWalletComponents,\n} from './wallet';\n\n/**\n * Type guard to check if a network config is a TypedEvmNetworkConfig\n * @param config The network configuration to check\n * @returns True if the config is for EVM\n */\nconst isTypedEvmNetworkConfig = (config: NetworkConfig): config is TypedEvmNetworkConfig =>\n config.ecosystem === 'evm';\n\n/**\n * EVM-specific adapter implementation\n */\nexport class EvmAdapter implements ContractAdapter {\n readonly networkConfig: TypedEvmNetworkConfig;\n readonly initialAppServiceKitName: UiKitConfiguration['kitName'];\n\n constructor(networkConfig: TypedEvmNetworkConfig) {\n if (!isTypedEvmNetworkConfig(networkConfig)) {\n throw new Error('EvmAdapter requires a valid EVM network configuration.');\n }\n this.networkConfig = networkConfig;\n logger.info(\n 'EvmAdapter',\n `Adapter initialized for network: ${networkConfig.name} (ID: ${networkConfig.id})`\n );\n\n // Determine the initial kitName from AppConfigService at the time of adapter construction.\n // This provides a baseline kitName preference from the application's static/global configuration.\n // It defaults to 'custom' if no specific kitName is found in AppConfigService.\n // This value is stored on the instance to inform the first call to configureUiKit if no programmatic overrides are given.\n const initialGlobalConfig = loadInitialConfigFromAppService();\n this.initialAppServiceKitName =\n (initialGlobalConfig.kitName as UiKitConfiguration['kitName']) || 'custom';\n\n logger.info(\n 'EvmAdapter:constructor',\n 'Initial kitName from AppConfigService noted:',\n this.initialAppServiceKitName\n );\n // The actual EvmUiKitManager.configure call (which drives UI setup) is deferred.\n // It's typically triggered by WalletStateProvider after this adapter instance is fully initialized and provided to it,\n // ensuring that loadConfigModule (for user native configs) is available.\n }\n\n /**\n * @inheritdoc\n */\n public getNetworkServiceForms(): NetworkServiceForm[] {\n return getEvmNetworkServiceForms(this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async validateNetworkServiceConfig(\n serviceId: string,\n values: Record<string, unknown>\n ): Promise<boolean> {\n return validateEvmNetworkServiceConfig(serviceId, values);\n }\n\n /**\n * @inheritdoc\n */\n public async testNetworkServiceConnection(\n serviceId: string,\n values: Record<string, unknown>\n ): Promise<{ success: boolean; latency?: number; error?: string }> {\n return testEvmNetworkServiceConnection(serviceId, values, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public getDefaultServiceConfig(serviceId: string): Record<string, unknown> | null {\n return getEvmDefaultServiceConfig(this.networkConfig, serviceId);\n }\n\n /**\n * @inheritdoc\n */\n public async loadContract(source: string | Record<string, unknown>): Promise<ContractSchema> {\n return loadContractSchema(source, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async loadContractWithMetadata(source: string | Record<string, unknown>): Promise<{\n schema: ContractSchema;\n source: 'fetched' | 'manual';\n contractDefinitionOriginal?: string;\n metadata?: {\n fetchedFrom?: string;\n contractName?: string;\n verificationStatus?: 'verified' | 'unverified' | 'unknown';\n fetchTimestamp?: Date;\n definitionHash?: string;\n };\n proxyInfo?: ProxyInfo;\n }> {\n // Delegate to core convenience function\n // Errors (including unverified contract errors) are handled by the core function\n return loadContractWithFullMetadata(source, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n mapParameterTypeToFieldType(parameterType: string): FieldType {\n return mapEvmParamTypeToFieldType(parameterType);\n }\n\n /**\n * @inheritdoc\n */\n getCompatibleFieldTypes(parameterType: string): FieldType[] {\n return getEvmCompatibleFieldTypes(parameterType);\n }\n\n /**\n * @inheritdoc\n */\n generateDefaultField<T extends FieldType = FieldType>(\n parameter: FunctionParameter\n ): FormFieldType<T> {\n return generateEvmDefaultField(parameter);\n }\n\n /**\n * @inheritdoc\n */\n public formatTransactionData(\n contractSchema: ContractSchema,\n functionId: string,\n submittedInputs: Record<string, unknown>,\n fields: FormFieldType[]\n ): WriteContractParameters {\n return formatEvmTransactionData(contractSchema, functionId, submittedInputs, fields);\n }\n\n /**\n * @inheritdoc\n */\n public async signAndBroadcast(\n transactionData: unknown,\n executionConfig: ExecutionConfig,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const walletImplementation = await getEvmWalletImplementation();\n return executeEvmTransaction(\n transactionData as WriteContractParameters,\n executionConfig,\n walletImplementation,\n onStatusChange,\n runtimeApiKey\n );\n }\n\n /**\n * @inheritdoc\n */\n public async getRelayers(serviceUrl: string, accessToken: string): Promise<RelayerDetails[]> {\n const relayerStrategy = new RelayerExecutionStrategy();\n return relayerStrategy.getEvmRelayers(serviceUrl, accessToken, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async getRelayer(\n serviceUrl: string,\n accessToken: string,\n relayerId: string\n ): Promise<RelayerDetailsRich> {\n const relayerStrategy = new RelayerExecutionStrategy();\n return relayerStrategy.getEvmRelayer(serviceUrl, accessToken, relayerId, this.networkConfig);\n }\n\n /**\n * Returns a React component for configuring EVM-specific relayer transaction options.\n * @returns The EVM relayer options component\n */\n public getRelayerOptionsComponent():\n | React.ComponentType<{\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n }>\n | undefined {\n return EvmRelayerOptions;\n }\n\n /**\n * @inheritdoc\n */\n public getWritableFunctions(contractSchema: ContractSchema): ContractSchema['functions'] {\n return contractSchema.functions.filter((fn) => fn.modifiesState);\n }\n\n /**\n * @inheritdoc\n */\n isValidAddress(address: string, _addressType?: string): boolean {\n // TODO: Could support ENS names as a different addressType (e.g., 'ens')\n // Viem provides normalize() and isAddress() functions that could validate ENS names\n // Example: addressType === 'ens' ? isValidEnsName(address) : isValidEvmAddress(address)\n\n // Currently, EVM treats all addresses uniformly (hex format)\n // The addressType parameter is ignored for backward compatibility with other chains\n return isValidEvmAddress(address);\n }\n\n /**\n * @inheritdoc\n */\n public async getSupportedExecutionMethods(): Promise<ExecutionMethodDetail[]> {\n return getEvmSupportedExecutionMethods();\n }\n\n /**\n * @inheritdoc\n */\n public async validateExecutionConfig(config: ExecutionConfig): Promise<true | string> {\n const walletStatus = this.getWalletConnectionStatus();\n return validateEvmExecutionConfig(config, walletStatus);\n }\n\n /**\n * @inheritdoc\n */\n isViewFunction(functionDetails: ContractFunction): boolean {\n return isEvmViewFunction(functionDetails);\n }\n\n /**\n * @inheritdoc\n */\n public filterAutoQueryableFunctions(functions: ContractFunction[]): ContractFunction[] {\n // Exclude admin/upgrade management getters that often revert or require permissions\n const skipNames = new Set([\n 'admin',\n 'implementation',\n 'getImplementation',\n '_implementation',\n 'proxyAdmin',\n 'changeAdmin',\n 'upgradeTo',\n 'upgradeToAndCall',\n ]);\n return functions.filter((f) => !skipNames.has(f.name));\n }\n\n /**\n * @inheritdoc\n */\n async queryViewFunction(\n contractAddress: string,\n functionId: string,\n params: unknown[] = [],\n contractSchema?: ContractSchema\n ): Promise<unknown> {\n const walletImplementation = await getEvmWalletImplementation();\n return queryEvmViewFunction(\n contractAddress,\n functionId,\n this.networkConfig,\n params,\n contractSchema,\n walletImplementation,\n (src: string) => this.loadContract({ contractAddress: src })\n );\n }\n\n /**\n * @inheritdoc\n */\n formatFunctionResult(decodedValue: unknown, functionDetails: ContractFunction): string {\n return formatEvmFunctionResult(decodedValue, functionDetails);\n }\n\n /**\n * @inheritdoc\n */\n public supportsWalletConnection(): boolean {\n return evmSupportsWalletConnection();\n }\n\n /**\n * @inheritdoc\n */\n public async getAvailableConnectors(): Promise<Connector[]> {\n return getEvmAvailableConnectors();\n }\n\n /**\n * @inheritdoc\n */\n public async connectWallet(\n connectorId: string\n ): Promise<{ connected: boolean; address?: string; error?: string }> {\n const result = await connectAndEnsureCorrectNetwork(connectorId, this.networkConfig.chainId);\n\n if (result.connected && result.address) {\n return { connected: true, address: result.address };\n } else {\n return {\n connected: false,\n error: result.error || 'Connection failed for an unknown reason.',\n };\n }\n }\n\n /**\n * @inheritdoc\n */\n public async disconnectWallet(): Promise<{ disconnected: boolean; error?: string }> {\n return disconnectEvmWallet();\n }\n\n /**\n * @inheritdoc\n */\n public getWalletConnectionStatus(): EvmWalletConnectionStatus {\n const status = getEvmWalletConnectionStatus();\n return convertWagmiToEvmStatus(status);\n }\n\n /**\n * @inheritdoc\n */\n public onWalletConnectionChange(\n callback: (\n currentStatus: WalletConnectionStatus,\n previousStatus: WalletConnectionStatus\n ) => void\n ): () => void {\n const walletImplementation = getInitializedEvmWalletImplementation();\n if (!walletImplementation) {\n logger.warn(\n 'EvmAdapter:onWalletConnectionChange',\n 'Wallet implementation not ready. Subscription may not work.'\n );\n return () => {};\n }\n return walletImplementation.onWalletConnectionChange(\n (currentWagmiStatus, previousWagmiStatus) => {\n // Convert wagmi's GetAccountReturnType to the rich adapter interface\n // This preserves all the enhanced UX capabilities from wagmi\n const current = convertWagmiToEvmStatus(currentWagmiStatus);\n const previous = convertWagmiToEvmStatus(previousWagmiStatus);\n\n callback(current, previous);\n }\n );\n }\n\n /**\n * @inheritdoc\n */\n getExplorerUrl(address: string): string | null {\n return getEvmExplorerAddressUrl(address, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n getExplorerTxUrl?(txHash: string): string | null {\n if (getEvmExplorerTxUrl) {\n return getEvmExplorerTxUrl(txHash, this.networkConfig);\n }\n return null;\n }\n\n /**\n * @inheritdoc\n */\n async getCurrentBlock(): Promise<number> {\n return getEvmCurrentBlock(this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n async waitForTransactionConfirmation(txHash: string): Promise<{\n status: 'success' | 'error';\n receipt?: TransactionReceipt;\n error?: Error;\n }> {\n const walletImplementation = await getEvmWalletImplementation();\n return waitForEvmTransactionConfirmation(txHash, walletImplementation);\n }\n\n /**\n * @inheritdoc\n */\n public async configureUiKit(\n programmaticOverrides: Partial<UiKitConfiguration> = {},\n options?: {\n loadUiKitNativeConfig?: NativeConfigLoader;\n }\n ): Promise<void> {\n const currentAppServiceConfig = loadInitialConfigFromAppService();\n\n // Delegate the entire configuration resolution to the service function.\n const finalFullConfig = await resolveFullUiKitConfiguration(\n programmaticOverrides,\n this.initialAppServiceKitName,\n currentAppServiceConfig,\n options\n );\n\n // Delegate the application of this configuration to the central EvmUiKitManager.\n await evmUiKitManager.configure(finalFullConfig);\n logger.info(\n 'EvmAdapter:configureUiKit',\n 'EvmUiKitManager configuration requested with final config:',\n finalFullConfig\n );\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemReactUiContextProvider():\n | React.ComponentType<EcosystemReactUiProviderProps>\n | undefined {\n // EvmWalletUiRoot is now the stable provider that subscribes to evmUiKitManager\n logger.info('EvmAdapter:getEcosystemReactUiContextProvider', 'Returning EvmWalletUiRoot.');\n return EvmWalletUiRoot;\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemReactHooks(): EcosystemSpecificReactHooks | undefined {\n // Always provide hooks for EVM adapter regardless of UI kit\n return evmFacadeHooks;\n }\n\n /**\n * @inheritdoc\n */\n public getSupportedContractDefinitionProviders(): Array<{\n key: EvmContractDefinitionProviderKey;\n label?: string;\n }> {\n return [\n { key: EvmProviderKeys.Etherscan, label: 'Etherscan' },\n { key: EvmProviderKeys.Sourcify, label: 'Sourcify' },\n ];\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemWalletComponents(): EcosystemWalletComponents | undefined {\n const currentManagerState = evmUiKitManager.getState();\n // Only attempt to resolve components if the manager has a configuration set.\n // During initial app load, currentFullUiKitConfig might be null until the first configure call completes.\n if (!currentManagerState.currentFullUiKitConfig) {\n logger.debug(\n // Changed from warn to debug, as this can be normal during init sequence\n 'EvmAdapter:getEcosystemWalletComponents',\n 'No UI kit configuration available in manager yet. Returning undefined components.'\n );\n return undefined; // Explicitly return undefined if manager isn't configured yet\n }\n // If manager has a config, use that for resolving components.\n return getResolvedWalletComponents(currentManagerState.currentFullUiKitConfig);\n }\n\n public async getAvailableUiKits(): Promise<AvailableUiKit[]> {\n const rainbowkitDefaultCode = generateRainbowKitConfigFile({});\n\n return [\n {\n id: 'custom',\n name: 'Wagmi Custom',\n configFields: [],\n },\n {\n id: 'rainbowkit',\n name: 'RainbowKit',\n linkToDocs: 'https://www.rainbowkit.com/docs/installation#configure',\n description: `Configure RainbowKit for your exported application. This code will be saved as <code class=\"bg-muted px-1 py-0.5 rounded text-xs\">rainbowkit.config.ts</code>.<br/><br/>\n<strong>Export Only:</strong> This configuration is <em>only used in exported apps</em>. The preview always uses the default RainbowKit configuration.<br/><br/>\n<strong>Available options:</strong><br/>\n• <code>wagmiParams</code>: Configure app name, projectId, wallets, etc.<br/>\n• <code>providerProps</code>: Set theme, modal size, and other UI options<br/><br/>\nGet your WalletConnect projectId from <a href=\"https://cloud.walletconnect.com\" target=\"_blank\" rel=\"noopener\" class=\"text-primary underline\">cloud.walletconnect.com</a>`,\n hasCodeEditor: true,\n defaultCode: rainbowkitDefaultCode,\n configFields: [],\n },\n ];\n }\n\n public async getExportableWalletConfigFiles(\n uiKitConfig?: UiKitConfiguration\n ): Promise<Record<string, string>> {\n if (uiKitConfig?.kitName === 'rainbowkit') {\n return generateRainbowKitExportables(uiKitConfig);\n }\n return {};\n }\n\n /**\n * @inheritdoc\n */\n public getUiLabels(): Record<string, string> | undefined {\n return {\n relayerConfigTitle: 'Gas Configuration',\n relayerConfigActiveDesc: 'Customize gas pricing strategy for transaction submission',\n relayerConfigInactiveDesc: 'Using recommended gas configuration for reliable transactions',\n relayerConfigPresetTitle: 'Fast Speed Preset Active',\n relayerConfigPresetDesc:\n 'Transactions will use high priority gas pricing for quick inclusion',\n relayerConfigCustomizeBtn: 'Customize Gas Settings',\n detailsTitle: 'Relayer Details',\n network: 'Network',\n relayerId: 'Relayer ID',\n active: 'Active',\n paused: 'Paused',\n systemDisabled: 'System Disabled',\n balance: 'Balance',\n nonce: 'Nonce',\n pending: 'Pending Transactions',\n lastTransaction: 'Last Transaction',\n };\n }\n\n /**\n * @inheritdoc\n */\n public getContractDefinitionInputs(): FormFieldType[] {\n return [\n {\n id: 'contractAddress',\n name: 'contractAddress',\n label: 'Contract Address',\n type: 'blockchain-address',\n validation: { required: true },\n placeholder: '0x1234...abcd',\n helperText:\n 'Enter the deployed contract address. For verified contracts, the ABI will be fetched automatically from the block explorer.',\n },\n {\n id: 'contractDefinition',\n name: 'contractDefinition',\n label: 'Contract ABI (Optional)',\n type: 'code-editor',\n validation: { required: false },\n placeholder:\n '[{\"inputs\":[],\"name\":\"myFunction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]',\n helperText:\n \"If the contract is not verified on the block explorer, paste the contract's ABI JSON here. You can find this in your contract's compilation artifacts or deployment files.\",\n codeEditorProps: {\n language: 'json',\n placeholder: 'Paste your contract ABI JSON here...',\n maxHeight: '500px',\n performanceThreshold: 3000, // Disable syntax highlighting for large ABIs\n },\n },\n ];\n }\n\n /**\n * @inheritdoc\n */\n public async validateRpcEndpoint(rpcConfig: UserRpcProviderConfig): Promise<boolean> {\n return validateEvmRpcEndpoint(rpcConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async testRpcConnection(rpcConfig: UserRpcProviderConfig): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n }> {\n return testEvmRpcConnection(rpcConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async validateExplorerConfig(explorerConfig: UserExplorerConfig): Promise<boolean> {\n return validateEvmExplorerConfig(explorerConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async testExplorerConnection(explorerConfig: UserExplorerConfig): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n }> {\n return testEvmExplorerConnection(explorerConfig, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async compareContractDefinitions(\n storedSchema: string,\n freshSchema: string\n ): Promise<{\n identical: boolean;\n differences: Array<{\n type: 'added' | 'removed' | 'modified';\n section: string;\n name: string;\n details: string;\n impact: 'low' | 'medium' | 'high';\n oldSignature?: string;\n newSignature?: string;\n }>;\n severity: 'none' | 'minor' | 'major' | 'breaking';\n summary: string;\n }> {\n // Delegate to core convenience function\n return coreCompareContractDefinitions(storedSchema, freshSchema);\n }\n\n /**\n * @inheritdoc\n */\n public validateContractDefinition(definition: string): {\n valid: boolean;\n errors: string[];\n warnings: string[];\n } {\n // Delegate to core convenience function\n return coreValidateContractDefinition(definition);\n }\n\n /**\n * @inheritdoc\n */\n public hashContractDefinition(definition: string): string {\n // Delegate to core convenience function\n return coreHashContractDefinition(definition);\n }\n\n /**\n * @inheritdoc\n */\n public getTypeMappingInfo(): TypeMappingInfo {\n return getEvmTypeMappingInfo();\n }\n}\n\n// Also export as default to ensure compatibility with various import styles\nexport default EvmAdapter;\n","import { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { createConfig, http } from '@wagmi/core';\nimport { mainnet } from 'viem/chains';\nimport { WagmiProvider } from 'wagmi';\nimport React, { useEffect, useMemo, useState } from 'react';\n\nimport { WagmiProviderInitializedContext } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EcosystemReactUiProviderProps } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { evmUiKitManager, type EvmUiKitManagerState } from '../evmUiKitManager';\nimport type { RainbowKitKitConfig, RainbowKitProviderProps } from '../rainbowkit';\n\n// Create a single QueryClient instance to be reused by EvmWalletUiRoot instances.\n// This should be stable across re-renders of EvmWalletUiRoot itself.\nconst stableQueryClient = new QueryClient();\n\n// Create a minimal, default WagmiConfig to use when no other config is ready.\n// This ensures WagmiProvider can always be mounted with a valid config object.\n// Uses mainnet as a minimal default chain with HTTP transport.\nconst minimalDefaultWagmiConfig = createConfig({\n chains: [mainnet], // At least one chain is required in wagmi v2.20+\n connectors: [], // Empty connectors array\n transports: {\n [mainnet.id]: http(), // Basic HTTP transport for the default chain\n },\n});\n\nexport const EvmWalletUiRoot: React.FC<EcosystemReactUiProviderProps> = ({ children }) => {\n const [managerState, setManagerState] = useState<EvmUiKitManagerState>(\n evmUiKitManager.getState()\n );\n\n useEffect(() => {\n const handleStateChange = () => {\n setManagerState(evmUiKitManager.getState());\n };\n const unsubscribe = evmUiKitManager.subscribe(handleStateChange);\n handleStateChange();\n return unsubscribe;\n }, []); // Kept empty dep array as per previous working state of subscription\n\n // Memoize QueryClient to ensure stability if we ever decide to make it configurable per instance\n const queryClient = useMemo(() => stableQueryClient, []);\n\n const {\n wagmiConfig,\n kitProviderComponent,\n isKitAssetsLoaded,\n currentFullUiKitConfig,\n isInitializing,\n error,\n } = managerState;\n\n const configForWagmiProvider = wagmiConfig || minimalDefaultWagmiConfig;\n const isWagmiContextEffectivelyReady = !!wagmiConfig && !error;\n\n let finalChildren = children;\n\n // TODO: If many UI kits are added, and each requires a distinct way of being\n // rendered as a provider around `children` (beyond just passing different providerProps),\n // this conditional logic might become complex. Consider a strategy pattern or a\n // more abstract way to obtain the fully composed `innerContent` based on kitName.\n // For now, with RainbowKit and custom/default, this is manageable.\n if (\n isWagmiContextEffectivelyReady &&\n currentFullUiKitConfig?.kitName === 'rainbowkit' &&\n kitProviderComponent &&\n isKitAssetsLoaded\n ) {\n const DynKitProvider = kitProviderComponent;\n const kitConfig: RainbowKitKitConfig = currentFullUiKitConfig.kitConfig || {};\n\n // Pass through all provider props from the parsed config\n const providerProps: RainbowKitProviderProps = kitConfig.providerProps || {};\n\n logger.info(\n 'EvmWalletUiRoot',\n 'Wrapping children with dynamically loaded KitProvider (RainbowKit).'\n );\n finalChildren = <DynKitProvider {...providerProps}>{children}</DynKitProvider>;\n } else if (currentFullUiKitConfig?.kitName === 'rainbowkit' && !isWagmiContextEffectivelyReady) {\n logger.info(\n 'EvmWalletUiRoot',\n 'RainbowKit configured, but context or assets not ready. Button may show its loading/error state.'\n );\n }\n // For 'custom' kit, finalChildren also remains children.\n\n return (\n <WagmiProvider config={configForWagmiProvider}>\n <QueryClientProvider client={queryClient}>\n <WagmiProviderInitializedContext.Provider value={isWagmiContextEffectivelyReady}>\n {finalChildren}\n {isInitializing && (\n <div\n style={{\n position: 'fixed',\n top: '10px',\n right: '10px',\n background: 'rgba(0,0,0,0.1)',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '0.8em',\n }}\n >\n Updating network...\n </div>\n )}\n {error && !wagmiConfig && (\n <div\n style={{\n position: 'fixed',\n bottom: '10px',\n left: '10px',\n background: 'red',\n color: 'white',\n padding: '10px',\n }}\n >\n Error initializing wallet provider: {error.message}\n </div>\n )}\n </WagmiProviderInitializedContext.Provider>\n </QueryClientProvider>\n </WagmiProvider>\n );\n};\n","import type { WagmiWalletImplementation } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\nimport { createEvmWalletImplementation } from '../implementation/wagmi-implementation';\n\nlet walletImplementationInstance: WagmiWalletImplementation | undefined;\nlet walletImplementationPromise: Promise<WagmiWalletImplementation> | undefined;\n\nconst LOG_SYSTEM = 'EvmWalletImplementationManager';\n\n/**\n * Get or create the singleton instance of WagmiWalletImplementation.\n * This function ensures that the initialization logic runs only once.\n *\n * @returns A Promise resolving to the WagmiWalletImplementation singleton\n */\nexport async function getEvmWalletImplementation(): Promise<WagmiWalletImplementation> {\n if (walletImplementationInstance) {\n return walletImplementationInstance;\n }\n\n if (walletImplementationPromise) {\n return walletImplementationPromise;\n }\n\n walletImplementationPromise = (async () => {\n try {\n logger.info(LOG_SYSTEM, 'Initializing WagmiWalletImplementation singleton (async)... ');\n // Get appName and projectId from appConfigService for RainbowKit\n // This assumes appConfigService is initialized before this manager is first called.\n const initialUiKitConfig = appConfigService.getTypedNestedConfig<UiKitConfiguration>(\n 'walletui',\n 'config'\n );\n\n const wcProjectId = appConfigService.getGlobalServiceParam('walletconnect', 'projectId') as\n | string\n | undefined;\n\n // Use factory function for proper EVM configuration\n const instance = createEvmWalletImplementation(wcProjectId, initialUiKitConfig);\n logger.info(LOG_SYSTEM, 'WagmiWalletImplementation singleton created (async).');\n walletImplementationInstance = instance;\n return instance;\n } catch (error) {\n logger.error(LOG_SYSTEM, 'Failed to initialize WagmiWalletImplementation (async):', error);\n const fallbackInstance = createEvmWalletImplementation();\n walletImplementationInstance = fallbackInstance;\n return fallbackInstance;\n }\n })();\n\n return walletImplementationPromise;\n}\n\n// Optional: A synchronous getter for cases where the instance is known to be initialized.\n// Use with caution, prefer the async getter.\nexport function getInitializedEvmWalletImplementation(): WagmiWalletImplementation | undefined {\n if (!walletImplementationInstance) {\n logger.warn(\n LOG_SYSTEM,\n 'getInitializedEvmWalletImplementation called before instance was ready.'\n );\n }\n return walletImplementationInstance;\n}\n","import {\n NetworkArbitrumOne,\n NetworkAvalanche,\n NetworkBase,\n NetworkBinanceSmartChain,\n NetworkEthereum,\n NetworkLinea,\n NetworkOptimism,\n NetworkPolygon,\n NetworkScroll,\n NetworkZksync,\n} from '@web3icons/react';\nimport {\n arbitrum as viemArbitrum,\n avalanche as viemAvalanche,\n base as viemBase,\n bsc as viemBsc,\n linea as viemLinea,\n mainnet as viemMainnet,\n optimism as viemOptimism,\n polygon as viemPolygon,\n polygonZkEvm as viemPolygonZkEvm,\n scroll as viemScroll,\n zksync as viemZkSync,\n} from 'viem/chains';\n\nimport type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport const ethereumMainnet: TypedEvmNetworkConfig = {\n id: 'ethereum-mainnet',\n exportConstName: 'ethereumMainnet',\n name: 'Ethereum',\n ecosystem: 'evm',\n network: 'ethereum',\n type: 'mainnet',\n isTestnet: false,\n chainId: 1,\n rpcUrl: viemMainnet.rpcUrls.default.http[0],\n explorerUrl: 'https://etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkEthereum,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemMainnet,\n};\n\nexport const arbitrumMainnet: TypedEvmNetworkConfig = {\n id: 'arbitrum-mainnet',\n exportConstName: 'arbitrumMainnet',\n name: 'Arbitrum One',\n ecosystem: 'evm',\n network: 'arbitrum',\n type: 'mainnet',\n isTestnet: false,\n chainId: 42161,\n rpcUrl: viemArbitrum.rpcUrls.default.http[0],\n explorerUrl: 'https://arbiscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkArbitrumOne,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemArbitrum,\n};\n\nexport const polygonMainnet: TypedEvmNetworkConfig = {\n id: 'polygon-mainnet',\n exportConstName: 'polygonMainnet',\n name: 'Polygon',\n ecosystem: 'evm',\n network: 'polygon',\n type: 'mainnet',\n isTestnet: false,\n chainId: 137,\n rpcUrl: viemPolygon.rpcUrls.default.http[0],\n explorerUrl: 'https://polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'MATIC',\n symbol: 'MATIC',\n decimals: 18,\n },\n viemChain: viemPolygon,\n};\n\nexport const polygonZkEvmMainnet: TypedEvmNetworkConfig = {\n id: 'polygon-zkevm-mainnet',\n exportConstName: 'polygonZkEvmMainnet',\n name: 'Polygon zkEVM',\n ecosystem: 'evm',\n network: 'polygon-zkevm',\n type: 'mainnet',\n isTestnet: false,\n chainId: 1101,\n rpcUrl: viemPolygonZkEvm.rpcUrls.default.http[0],\n explorerUrl: 'https://zkevm.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemPolygonZkEvm,\n};\n\nexport const baseMainnet: TypedEvmNetworkConfig = {\n id: 'base-mainnet',\n exportConstName: 'baseMainnet',\n name: 'Base',\n ecosystem: 'evm',\n network: 'base',\n type: 'mainnet',\n isTestnet: false,\n chainId: 8453,\n rpcUrl: viemBase.rpcUrls.default.http[0],\n explorerUrl: 'https://basescan.org',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBase,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemBase,\n};\n\nexport const bscMainnet: TypedEvmNetworkConfig = {\n id: 'bsc-mainnet',\n exportConstName: 'bscMainnet',\n name: 'BNB Smart Chain',\n ecosystem: 'evm',\n network: 'bsc',\n type: 'mainnet',\n isTestnet: false,\n chainId: 56,\n rpcUrl: viemBsc.rpcUrls.default.http[0],\n explorerUrl: 'https://bscscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBinanceSmartChain,\n nativeCurrency: {\n name: 'BNB',\n symbol: 'BNB',\n decimals: 18,\n },\n viemChain: viemBsc,\n};\n\nexport const optimismMainnet: TypedEvmNetworkConfig = {\n id: 'optimism-mainnet',\n exportConstName: 'optimismMainnet',\n name: 'OP Mainnet',\n ecosystem: 'evm',\n network: 'optimism',\n type: 'mainnet',\n isTestnet: false,\n chainId: 10,\n rpcUrl: viemOptimism.rpcUrls.default.http[0],\n explorerUrl: 'https://optimistic.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkOptimism,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemOptimism,\n};\n\nexport const avalancheMainnet: TypedEvmNetworkConfig = {\n id: 'avalanche-mainnet',\n exportConstName: 'avalancheMainnet',\n name: 'Avalanche C-Chain',\n ecosystem: 'evm',\n network: 'avalanche',\n type: 'mainnet',\n isTestnet: false,\n chainId: 43114,\n rpcUrl: viemAvalanche.rpcUrls.default.http[0],\n explorerUrl: 'https://snowscan.xyz',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkAvalanche,\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n viemChain: viemAvalanche,\n};\n\n// TODO: test and setup the api and explorer config\nexport const zkSyncEraMainnet: TypedEvmNetworkConfig = {\n id: 'zksync-era-mainnet',\n exportConstName: 'zkSyncEraMainnet',\n name: 'ZkSync Era',\n ecosystem: 'evm',\n network: 'zksync-era',\n type: 'mainnet',\n isTestnet: false,\n chainId: 324,\n rpcUrl: viemZkSync.rpcUrls.default.http[0],\n explorerUrl: 'https://explorer.zksync.io',\n apiUrl: 'https://block-explorer-api.mainnet.zksync.io/api',\n primaryExplorerApiIdentifier: 'zksync-era-mainnet',\n supportsEtherscanV2: false,\n iconComponent: NetworkZksync,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemZkSync,\n};\n\nexport const scrollMainnet: TypedEvmNetworkConfig = {\n id: 'scroll-mainnet',\n exportConstName: 'scrollMainnet',\n name: 'Scroll',\n ecosystem: 'evm',\n network: 'scroll',\n type: 'mainnet',\n isTestnet: false,\n chainId: 534352,\n rpcUrl: viemScroll.rpcUrls.default.http[0],\n explorerUrl: 'https://scrollscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkScroll,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemScroll,\n};\n\nexport const lineaMainnet: TypedEvmNetworkConfig = {\n id: 'linea-mainnet',\n exportConstName: 'lineaMainnet',\n name: 'Linea',\n ecosystem: 'evm',\n network: 'linea',\n type: 'mainnet',\n isTestnet: false,\n chainId: 59144,\n rpcUrl: viemLinea.rpcUrls.default.http[0],\n explorerUrl: 'https://lineascan.build',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkLinea,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemLinea,\n};\n\n// TODO: Add other EVM mainnet networks with their public RPCs and viemChain objects\n","import {\n NetworkArbitrumOne,\n NetworkAvalanche,\n NetworkBase,\n NetworkBinanceSmartChain,\n NetworkEthereum,\n NetworkLinea,\n NetworkMonad,\n NetworkOptimism,\n NetworkPolygon,\n NetworkScroll,\n NetworkZksync,\n} from '@web3icons/react';\nimport {\n arbitrumSepolia as viemArbitrumSepolia,\n avalancheFuji as viemAvalancheFuji,\n baseSepolia as viemBaseSepolia,\n bscTestnet as viemBscTestnet,\n lineaSepolia as viemLineaSepolia,\n monadTestnet as viemMonadTestnet,\n optimismSepolia as viemOptimismSepolia,\n polygonAmoy as viemPolygonAmoy,\n polygonZkEvmCardona as viemPolygonZkEvmCardona,\n scrollSepolia as viemScrollSepolia,\n sepolia as viemSepolia,\n zksyncSepoliaTestnet as viemZkSyncSepoliaTestnet,\n} from 'viem/chains';\n\nimport type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport const ethereumSepolia: TypedEvmNetworkConfig = {\n id: 'ethereum-sepolia',\n exportConstName: 'ethereumSepolia',\n name: 'Sepolia',\n ecosystem: 'evm',\n network: 'ethereum',\n type: 'testnet',\n isTestnet: true,\n chainId: 11155111,\n rpcUrl: viemSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkEthereum,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemSepolia,\n};\n\nexport const arbitrumSepolia: TypedEvmNetworkConfig = {\n id: 'arbitrum-sepolia',\n exportConstName: 'arbitrumSepolia',\n name: 'Arbitrum Sepolia',\n ecosystem: 'evm',\n network: 'arbitrum',\n type: 'testnet',\n isTestnet: true,\n chainId: 421614,\n rpcUrl: viemArbitrumSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.arbiscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkArbitrumOne,\n nativeCurrency: {\n name: 'Arbitrum Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemArbitrumSepolia,\n};\n\nexport const polygonAmoy: TypedEvmNetworkConfig = {\n id: 'polygon-amoy',\n exportConstName: 'polygonAmoy',\n name: 'Polygon Amoy',\n ecosystem: 'evm',\n network: 'polygon',\n type: 'testnet',\n isTestnet: true,\n chainId: 80002,\n rpcUrl: viemPolygonAmoy.rpcUrls.default.http[0],\n explorerUrl: 'https://amoy.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'MATIC',\n symbol: 'MATIC',\n decimals: 18,\n },\n viemChain: viemPolygonAmoy,\n};\n\nexport const polygonZkEvmCardona: TypedEvmNetworkConfig = {\n id: 'polygon-zkevm-cardona',\n exportConstName: 'polygonZkEvmCardona',\n name: 'Polygon zkEVM Cardona',\n ecosystem: 'evm',\n network: 'polygon-zkevm',\n type: 'testnet',\n isTestnet: true,\n chainId: 2442,\n rpcUrl: viemPolygonZkEvmCardona.rpcUrls.default.http[0],\n explorerUrl: 'https://cardona-zkevm.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemPolygonZkEvmCardona,\n};\n\nexport const baseSepolia: TypedEvmNetworkConfig = {\n id: 'base-sepolia',\n exportConstName: 'baseSepolia',\n name: 'Base Sepolia',\n ecosystem: 'evm',\n network: 'base',\n type: 'testnet',\n isTestnet: true,\n chainId: 84532,\n rpcUrl: viemBaseSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.basescan.org',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBase,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemBaseSepolia,\n};\n\nexport const bscTestnet: TypedEvmNetworkConfig = {\n id: 'bsc-testnet',\n exportConstName: 'bscTestnet',\n name: 'BSC Testnet',\n ecosystem: 'evm',\n network: 'bsc',\n type: 'testnet',\n isTestnet: true,\n chainId: 97,\n rpcUrl: viemBscTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.bscscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBinanceSmartChain,\n nativeCurrency: {\n name: 'BNB',\n symbol: 'BNB',\n decimals: 18,\n },\n viemChain: viemBscTestnet,\n};\n\nexport const optimismSepolia: TypedEvmNetworkConfig = {\n id: 'optimism-sepolia',\n exportConstName: 'optimismSepolia',\n name: 'OP Sepolia',\n ecosystem: 'evm',\n network: 'optimism',\n type: 'testnet',\n isTestnet: true,\n chainId: 11155420,\n rpcUrl: viemOptimismSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia-optimism.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkOptimism,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemOptimismSepolia,\n};\n\nexport const avalancheFuji: TypedEvmNetworkConfig = {\n id: 'avalanche-fuji',\n exportConstName: 'avalancheFuji',\n name: 'Avalanche Fuji C-Chain',\n ecosystem: 'evm',\n network: 'avalanche',\n type: 'testnet',\n isTestnet: true,\n chainId: 43113,\n rpcUrl: viemAvalancheFuji.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.snowscan.xyz',\n apiUrl: 'https://api.etherscan.io/v2/api', // Using Etherscan V2 unified API\n primaryExplorerApiIdentifier: 'etherscan-v2', // Unified identifier for V2 API\n supportsEtherscanV2: true,\n requiresExplorerApiKey: true,\n iconComponent: NetworkAvalanche,\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n viemChain: viemAvalancheFuji,\n};\n\n// TODO: test and setup the api and explorer config\nexport const zksyncSepoliaTestnet: TypedEvmNetworkConfig = {\n id: 'zksync-era-sepolia',\n exportConstName: 'zksyncSepoliaTestnet',\n name: 'ZkSync Era Sepolia',\n ecosystem: 'evm',\n network: 'zksync-era',\n type: 'testnet',\n isTestnet: true,\n chainId: 300,\n rpcUrl: viemZkSyncSepoliaTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.explorer.zksync.io',\n apiUrl: 'https://block-explorer-api.sepolia.zksync.dev/api',\n primaryExplorerApiIdentifier: 'zksync-era-sepolia',\n supportsEtherscanV2: false,\n iconComponent: NetworkZksync,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemZkSyncSepoliaTestnet,\n};\n\nexport const scrollSepolia: TypedEvmNetworkConfig = {\n id: 'scroll-sepolia',\n exportConstName: 'scrollSepolia',\n name: 'Scroll Sepolia',\n ecosystem: 'evm',\n network: 'scroll',\n type: 'testnet',\n isTestnet: true,\n chainId: 534351,\n rpcUrl: viemScrollSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.scrollscan.dev',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkScroll,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemScrollSepolia,\n};\n\nexport const lineaSepolia: TypedEvmNetworkConfig = {\n id: 'linea-sepolia',\n exportConstName: 'lineaSepolia',\n name: 'Linea Sepolia',\n ecosystem: 'evm',\n network: 'linea',\n type: 'testnet',\n isTestnet: true,\n chainId: 59141,\n rpcUrl: viemLineaSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.lineascan.build',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkLinea,\n nativeCurrency: {\n name: 'Linea Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemLineaSepolia,\n};\n\nexport const monadTestnet: TypedEvmNetworkConfig = {\n id: 'monad-testnet',\n exportConstName: 'monadTestnet',\n name: 'Monad Testnet',\n ecosystem: 'evm',\n network: 'monad',\n type: 'testnet',\n isTestnet: true,\n chainId: 10143,\n rpcUrl: viemMonadTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.monadexplorer.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkMonad,\n nativeCurrency: {\n name: 'Monad',\n symbol: 'MON',\n decimals: 18,\n },\n viemChain: viemMonadTestnet,\n};\n\n// TODO: Add other EVM testnet networks as needed (e.g., Arbitrum Sepolia)\n","import type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport {\n arbitrumMainnet,\n avalancheMainnet,\n baseMainnet,\n bscMainnet,\n ethereumMainnet,\n lineaMainnet,\n optimismMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n} from './mainnet';\nimport {\n arbitrumSepolia,\n avalancheFuji,\n baseSepolia,\n bscTestnet,\n ethereumSepolia,\n lineaSepolia,\n monadTestnet,\n optimismSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n scrollSepolia,\n zksyncSepoliaTestnet,\n} from './testnet';\n\n// All mainnet networks\nexport const evmMainnetNetworks: TypedEvmNetworkConfig[] = [\n ethereumMainnet,\n arbitrumMainnet,\n baseMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n // Other mainnet networks...\n];\n\n// All testnet networks\nexport const evmTestnetNetworks: TypedEvmNetworkConfig[] = [\n ethereumSepolia,\n arbitrumSepolia,\n baseSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n monadTestnet,\n // Other testnet networks...\n];\n\n// All EVM networks\n// NOTE: The wagmi integration automatically uses all networks defined here that have a `viemChain` property.\n// This ensures that adding a new network to mainnet.ts or testnet.ts automatically makes it available to wagmi.\nexport const evmNetworks: TypedEvmNetworkConfig[] = [...evmMainnetNetworks, ...evmTestnetNetworks];\n\n// Export individual networks for direct import\nexport {\n // Mainnet networks\n ethereumMainnet,\n arbitrumMainnet,\n baseMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n // Testnet networks\n ethereumSepolia,\n arbitrumSepolia,\n baseSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n monadTestnet,\n};\n","/**\n * EVM Wagmi Wallet Implementation\n *\n * This file configures and exports the core WagmiWalletImplementation\n * with EVM-specific settings.\n */\nimport {\n WagmiWalletImplementation as CoreWagmiWalletImplementation,\n getWagmiConfigForRainbowKit,\n type WagmiConfigChains,\n type WagmiWalletConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\n\nimport { evmNetworks } from '../../networks';\n\n/**\n * Generates the supported chains from EVM network configurations.\n * Only includes networks that have a viemChain property (ensuring wagmi compatibility).\n */\nconst getSupportedChainsFromNetworks = () => {\n return evmNetworks\n .filter((network) => network.viemChain)\n .map((network) => network.viemChain!)\n .filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index);\n};\n\n/**\n * The supported chains for EVM adapter.\n */\nconst defaultSupportedChains = getSupportedChainsFromNetworks();\n\n/**\n * Create an EVM-configured WagmiWalletImplementation instance.\n *\n * @param walletConnectProjectId - Optional WalletConnect project ID\n * @param initialUiKitConfig - Optional initial UI kit configuration\n * @returns A configured WagmiWalletImplementation instance\n */\nexport function createEvmWalletImplementation(\n walletConnectProjectId?: string,\n initialUiKitConfig?: UiKitConfiguration\n): CoreWagmiWalletImplementation {\n const config: WagmiWalletConfig = {\n chains: defaultSupportedChains,\n networkConfigs: evmNetworks,\n walletConnectProjectId,\n initialUiKitConfig,\n logSystem: 'WagmiWalletImplementation',\n };\n\n const instance = new CoreWagmiWalletImplementation(config);\n\n // Inject the RainbowKit config function\n instance.setRainbowKitConfigFn(\n async (uiKitConfiguration, chains, chainIdToNetworkIdMap, getRpcOverride) => {\n return getWagmiConfigForRainbowKit(\n uiKitConfiguration,\n chains as WagmiConfigChains,\n chainIdToNetworkIdMap,\n getRpcOverride\n );\n }\n );\n\n return instance;\n}\n","/**\n * EVM UI Kit Manager\n *\n * Manages UI kit configuration for EVM networks using the shared factory from adapter-evm-core.\n */\n\nimport {\n createUiKitManager,\n ensureRainbowKitAssetsLoaded,\n type UiKitManagerState,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport { getEvmWalletImplementation } from './utils/walletImplementationManager';\n\n/**\n * State interface for EVM UI Kit Manager.\n * This is a type alias to the shared UiKitManagerState for backwards compatibility.\n */\nexport type EvmUiKitManagerState = UiKitManagerState;\n\n/**\n * EVM UI Kit Manager instance.\n * Provides state management for UI kit configuration in EVM adapters.\n */\nexport const evmUiKitManager = createUiKitManager({\n getWalletImplementation: getEvmWalletImplementation,\n loadRainbowKitAssets: ensureRainbowKitAssetsLoaded,\n logPrefix: 'EvmUiKitManager',\n});\n","import {\n useAccount,\n useBalance,\n useChainId,\n useChains,\n useConnect,\n useDisconnect,\n useSendTransaction,\n useSignMessage,\n useSignTypedData,\n useSwitchChain,\n useWaitForTransactionReceipt,\n type UseAccountReturnType,\n type UseBalanceReturnType,\n type UseChainIdReturnType,\n type UseChainsReturnType,\n type UseConnectReturnType,\n type UseDisconnectReturnType,\n type UseSendTransactionReturnType,\n type UseSignMessageReturnType,\n type UseSignTypedDataReturnType,\n type UseSwitchChainReturnType,\n type UseWaitForTransactionReceiptReturnType,\n} from 'wagmi';\n\nimport type { EcosystemSpecificReactHooks } from '@openzeppelin/ui-types';\n\n/**\n * Direct export of wagmi hooks as our facade hooks\n * Using the EcosystemSpecificReactHooks interface which now accepts any function signatures\n */\nexport const evmFacadeHooks: EcosystemSpecificReactHooks = {\n useAccount,\n useConnect,\n useDisconnect,\n useSwitchChain,\n useChainId,\n useChains,\n useBalance,\n useSendTransaction,\n useWaitForTransactionReceipt,\n useSignMessage,\n useSignTypedData,\n};\n\n// Re-export the wagmi hook types for convenience when consuming these hooks\nexport type {\n UseAccountReturnType,\n UseBalanceReturnType,\n UseChainIdReturnType,\n UseChainsReturnType,\n UseConnectReturnType,\n UseDisconnectReturnType,\n UseSendTransactionReturnType,\n UseSignMessageReturnType,\n UseSignTypedDataReturnType,\n UseSwitchChainReturnType,\n UseWaitForTransactionReceiptReturnType,\n};\n","import type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\n/**\n * Default configuration when no specific configuration is provided\n */\nconst defaultConfig: UiKitConfiguration = {\n kitName: 'custom', // Default to using our custom implementation for EVM\n kitConfig: {\n showInjectedConnector: false, // Default to hiding the injected connector\n },\n};\n\n// Singleton instance of the UI kit configuration\nlet uiKitConfig: UiKitConfiguration = { ...defaultConfig };\n\nexport function loadInitialConfigFromAppService(): UiKitConfiguration {\n logger.debug('useUiKitConfig', 'Attempting to load initial config from AppConfigService...');\n const configObj = appConfigService.getWalletUIConfig<UiKitConfiguration>('evm');\n\n if (configObj && configObj.kitName) {\n logger.info(\n 'useUiKitConfig',\n `Loaded initial config from AppConfigService: kitName=${configObj.kitName}`,\n configObj.kitConfig\n );\n // Merge with defaults to ensure all base keys are present if AppConfigService only provides partial config\n return {\n kitName: configObj.kitName,\n kitConfig: { ...defaultConfig.kitConfig, ...(configObj.kitConfig || {}) },\n };\n }\n logger.debug(\n 'useUiKitConfig',\n 'No initial config found in AppConfigService, using module default.'\n );\n return { ...defaultConfig };\n}\n\n/**\n * Updates the UI kit configuration\n * @param config The new configuration to set. This should be the fully resolved\n * config from the adapter, potentially including user-native settings.\n */\nexport function setUiKitConfig(config: UiKitConfiguration): void {\n uiKitConfig = { ...config }; // Store a copy of the provided config\n logger.info(\n 'useUiKitConfig:setUiKitConfig',\n `Global uiKitConfig was SET to: kitName=${uiKitConfig.kitName}`,\n `kitConfig: ${JSON.stringify(uiKitConfig.kitConfig)}`\n );\n}\n\n/**\n * Helper to check if a specific config option is enabled\n * @param key The configuration key to check\n * @returns True if the configuration option is enabled, false otherwise\n */\nexport function isConfigEnabled(key: string): boolean {\n return Boolean(uiKitConfig.kitConfig?.[key]);\n}\n\n/**\n * Hook to access the UI kit configuration.\n * The configuration is typically loaded at module initialization and when `setUiKitConfig` is called.\n * @returns The current UI kit configuration (module-level singleton).\n */\nexport function useUiKitConfig(): UiKitConfiguration {\n // The module-level `uiKitConfig` is updated by `loadInitialConfigFromAppService` (called at module load)\n // and `setUiKitConfig` (called by adapter's configureUiKit).\n // Thus, this hook can simply return the current state of the module-level singleton.\n return uiKitConfig;\n}\n\n/**\n * Getter function to access the current module-level UI kit configuration directly.\n * Useful for initializing adapter instance configurations.\n * @returns The current module-level UI kit configuration.\n */\nexport function getUiKitConfig(): UiKitConfiguration {\n // Return the direct reference to the singleton. Setters should ensure immutability if needed elsewhere.\n // For this flow, setUiKitConfig is the explicit mutator.\n return uiKitConfig;\n}\n","import type { ExecutionMethodDetail } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Returns details for execution methods supported by the EVM adapter.\n */\nexport async function getEvmSupportedExecutionMethods(): Promise<ExecutionMethodDetail[]> {\n logger.warn(\n 'adapter-evm-execution-config',\n 'getEvmSupportedExecutionMethods is using placeholder implementation.'\n );\n // TODO: Implement actual supported methods for EVM (e.g., EOA, Safe).\n return Promise.resolve([\n {\n type: 'eoa',\n name: 'EOA (External Account)',\n description: 'Execute using a standard wallet address.',\n },\n {\n type: 'relayer',\n name: 'OpenZeppelin Relayer',\n description: 'Execute via a OpenZeppelin open source transaction relayer service.',\n disabled: false,\n },\n {\n type: 'multisig',\n name: 'Safe Multisig', // Example for future\n description: 'Execute via a Safe multisignature wallet.',\n disabled: true,\n },\n ]);\n}\n","// Import from core package via barrel files\nimport {\n EvmProviderKeys,\n resolveExplorerApiKeyFromAppConfig,\n type TypedEvmNetworkConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EvmNetworkConfig, NetworkServiceForm } from '@openzeppelin/ui-types';\nimport { appConfigService, userNetworkServiceConfigService } from '@openzeppelin/ui-utils';\n\n/**\n * Returns the default service configuration values for a given service ID.\n * Used for proactive health checks when no user overrides are configured.\n *\n * @param networkConfig The network configuration\n * @param serviceId The service identifier (e.g., 'rpc', 'explorer', 'contract-definitions')\n * @returns The default configuration values, or null if not available\n */\nexport function getEvmDefaultServiceConfig(\n networkConfig: EvmNetworkConfig,\n serviceId: string\n): Record<string, unknown> | null {\n switch (serviceId) {\n case 'rpc':\n if (networkConfig.rpcUrl) {\n return { rpcUrl: networkConfig.rpcUrl };\n }\n break;\n case 'explorer': {\n // For explorer service, we need to include the API key if available\n // Use the shared helper from adapter-evm-core to resolve the API key\n const typedConfig = networkConfig as TypedEvmNetworkConfig;\n const apiKey = resolveExplorerApiKeyFromAppConfig(typedConfig);\n\n // Return config if we have at least an explorer URL or an API key\n if (networkConfig.explorerUrl || apiKey) {\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n ...(apiKey ? { apiKey } : {}),\n };\n }\n break;\n }\n case 'contract-definitions':\n // No connection test for contract definitions service\n return null;\n }\n return null;\n}\n\n/**\n * Returns the network service forms for EVM networks.\n * Defines the UI configuration for RPC, Explorer, and Contract Definitions services.\n */\nexport function getEvmNetworkServiceForms(\n networkConfig: TypedEvmNetworkConfig\n): NetworkServiceForm[] {\n const globalV2ApiKey = appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as\n | string\n | undefined;\n const v2DefaultEnabled = Boolean(globalV2ApiKey);\n // Read any saved contract-definitions config to seed defaults in the UI\n const savedContractDefCfg = userNetworkServiceConfigService.get(\n networkConfig.id,\n 'contract-definitions'\n ) as Record<string, unknown> | null;\n const savedDefaultProvider =\n savedContractDefCfg && typeof savedContractDefCfg.defaultProvider === 'string'\n ? (savedContractDefCfg.defaultProvider as string)\n : undefined;\n return [\n {\n id: 'rpc',\n label: 'RPC Provider',\n description:\n 'Setting your own RPC endpoint ensures better reliability, faster response times, and higher rate limits. Public endpoints may be rate-limited or experience congestion during high traffic periods.',\n fields: [\n {\n id: 'evm-rpc-url',\n name: 'rpcUrl',\n type: 'text',\n label: 'RPC URL',\n placeholder: 'https://mainnet.infura.io/v3/your-key',\n validation: { required: true, pattern: '^https?://.+' },\n width: 'full',\n },\n ],\n },\n {\n id: 'explorer',\n label: 'Block Explorer',\n description:\n 'Public API keys are rate-limited and may be exhausted quickly. Using your own key ensures reliable access to explorer services.',\n fields: [\n // Adapter-led informational notes (rendered generically by the panel)\n {\n id: 'evm-explorer-note-etherscan',\n name: '_note_etherscan',\n type: 'hidden',\n label: '',\n validation: {},\n isHidden: true,\n metadata: {\n note: {\n variant: 'warning',\n title: 'Etherscan API Support',\n html: true,\n lines: [\n '<strong>V2 API (Recommended):</strong> Supports all Etherscan-compatible explorers across multiple chains with a single API key.',\n '<strong>V1 API (Legacy):</strong> Requires chain-specific API endpoints. Some explorers may not be supported.',\n '<strong>Note:</strong> Non-Etherscan explorers (Blockscout, Routescan, etc.) are not supported.',\n ],\n },\n },\n },\n {\n id: 'evm-explorer-api-key',\n name: 'apiKey',\n type: 'password',\n label: 'API Key',\n placeholder: 'Your explorer API key',\n helperText: 'Required for fetching contract ABIs and other API operations',\n validation: {},\n width: 'full',\n },\n {\n id: 'evm-explorer-use-v2',\n name: 'useV2Api',\n type: 'checkbox',\n label: 'Use Etherscan V2 API',\n helperText:\n 'Enable the new V2 API for all Etherscan-compatible networks. V2 provides unified access across all chains.',\n validation: {},\n defaultValue: v2DefaultEnabled,\n metadata: {\n section: 'api-config',\n sectionLabel: 'API Configuration',\n sectionHelp: 'Configure API version and network application settings.',\n },\n },\n {\n id: 'evm-explorer-apply-all',\n name: 'applyToAllNetworks',\n type: 'checkbox',\n label: 'Apply to all compatible networks',\n helperText: 'Apply these settings to all Etherscan-compatible networks in your project.',\n validation: {},\n defaultValue: v2DefaultEnabled,\n // UI hinting for generic renderer to indent under and disable when V2 is off\n metadata: {\n section: 'api-config',\n nestUnder: 'useV2Api',\n disabledWhen: { field: 'useV2Api', equals: false },\n },\n },\n {\n id: 'evm-explorer-url',\n name: 'explorerUrl',\n type: 'text',\n label: 'Explorer Base URL (optional)',\n placeholder: 'https://etherscan.io',\n validation: {},\n helperText:\n 'Base URL for viewing transactions and addresses. If not provided, defaults from the network will be used.',\n width: 'full',\n metadata: {\n section: 'custom-endpoints',\n sectionLabel: 'Custom Endpoints',\n sectionHelp: 'Override default URLs for explorer and API endpoints.',\n },\n },\n {\n id: 'evm-explorer-api-url',\n name: 'apiUrl',\n type: 'text',\n label: 'Explorer API URL (legacy / V1)',\n placeholder: 'https://api.etherscan.io/api',\n validation: {},\n helperText:\n 'API endpoint for fetching contract data. If not provided, defaults from the network will be used.',\n width: 'full',\n metadata: { section: 'custom-endpoints' },\n },\n ],\n },\n {\n id: 'contract-definitions',\n label: 'Contract Definitions',\n description: undefined,\n supportsConnectionTest: false,\n fields: [\n // Informational note\n {\n id: 'evm-contract-def-note',\n name: '_note_contract_def',\n type: 'hidden',\n label: '',\n validation: {},\n isHidden: true,\n metadata: {\n hideTestConnection: true,\n note: {\n variant: 'info',\n title: 'Contract Definition Provider',\n lines: [\n 'Select which provider the builder should try first when loading verified contract definitions. Deep links can override this preference temporarily.',\n ],\n },\n },\n },\n // Default provider select\n {\n id: 'evm-contract-def-provider',\n name: 'defaultProvider',\n type: 'select',\n label: 'Default Contract Definition Provider',\n placeholder: 'Select a provider',\n helperText: 'Used as the first provider to query for contract definitions.',\n validation: {},\n options: [\n { label: 'Etherscan', value: EvmProviderKeys.Etherscan },\n { label: 'Sourcify', value: EvmProviderKeys.Sourcify },\n ],\n // Seed from saved user config or app-config default if present; otherwise empty\n defaultValue:\n savedDefaultProvider ||\n (appConfigService.getGlobalServiceParam('contractdefinition', 'defaultProvider') as\n | string\n | undefined) ||\n '',\n width: 'full',\n },\n // Apply to all networks\n {\n id: 'evm-contract-def-apply-all',\n name: 'applyToAllNetworks',\n type: 'checkbox',\n label: 'Apply to all compatible networks',\n helperText:\n 'Apply this default provider setting to all compatible networks in your project.',\n validation: {},\n defaultValue: false,\n metadata: {\n nestUnder: 'defaultProvider',\n disabledWhen: { field: 'defaultProvider', equals: '' },\n },\n },\n ],\n },\n ];\n}\n","/**\n * Adapter-specific query wrapper\n *\n * Wraps the core queryEvmViewFunction with adapter-specific functionality:\n * - Resolves RPC URL from network config (with user override support)\n * - Supports loading contract schema for proxy implementations\n */\nimport {\n queryEvmViewFunction as coreQueryEvmViewFunction,\n resolveRpcUrl,\n type TypedEvmNetworkConfig,\n type WagmiWalletImplementation,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Query a view function on an EVM contract.\n *\n * This adapter-specific version wraps the core queryEvmViewFunction to:\n * 1. Resolve the RPC URL from network config (supporting user overrides)\n * 2. Support optional wallet implementation for RPC context\n * 3. Support loading proxy implementation schemas via callback\n *\n * @param contractAddress The contract address to query\n * @param functionId The function ID to call\n * @param networkConfig The network configuration\n * @param params The parameters for the function call\n * @param contractSchema Optional contract schema (if not provided, will use loadContractCallback)\n * @param _walletImplementation Optional wallet implementation (reserved for future use)\n * @param loadContractCallback Optional callback to load contract schema when not provided\n * @returns The result of the view function call\n */\nexport async function queryEvmViewFunction(\n contractAddress: string,\n functionId: string,\n networkConfig: TypedEvmNetworkConfig,\n params: unknown[] = [],\n contractSchema?: ContractSchema,\n _walletImplementation?: WagmiWalletImplementation,\n loadContractCallback?: (address: string) => Promise<ContractSchema>\n): Promise<unknown> {\n // Use provided schema or fall back to loading via callback\n let schema = contractSchema;\n if (!schema) {\n if (loadContractCallback) {\n logger.debug('adapter-query', `Loading contract schema for ${contractAddress} via callback`);\n schema = await loadContractCallback(contractAddress);\n } else {\n throw new Error(\n 'Contract schema is required for view function query. ' +\n 'Provide either a contractSchema or a loadContractCallback.'\n );\n }\n }\n\n // Resolve RPC URL from network config (supports user overrides)\n // Note: resolveRpcUrl throws if no valid URL can be resolved\n const rpcUrl = resolveRpcUrl(networkConfig);\n\n logger.debug('adapter-query', `Using RPC URL for query: ${rpcUrl}`);\n\n // Call core function with resolved RPC URL\n return coreQueryEvmViewFunction(\n contractAddress,\n functionId,\n params,\n schema,\n rpcUrl,\n networkConfig\n );\n}\n","import React from 'react';\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@openzeppelin/ui-components';\n\nimport { AdvancedInfo } from './AdvancedInfo';\nimport { CustomGasParameters } from './CustomGasParameters';\nimport { SpeedSelection } from './SpeedSelection';\nimport { useEvmRelayerOptions } from './useEvmRelayerOptions';\n\n/**\n * EVM-specific relayer transaction options component.\n *\n * Provides configuration for gas pricing strategies:\n * - Speed presets: Use predefined gas pricing levels (OpenZeppelin Relayer API)\n * - Custom: Manual gas parameter configuration for precise control\n *\n * We default to Speed mode with FAST preset to ensure valid API requests.\n * The OpenZeppelin Relayer API requires exactly one pricing strategy to be provided.\n */\nexport const EvmRelayerOptions: React.FC<{\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n}> = ({ options, onChange }) => {\n const [showAdvancedInfo, setShowAdvancedInfo] = React.useState(false);\n\n const {\n control,\n formValues,\n configMode,\n gasType,\n handleSpeedChange,\n handleModeChange,\n handleGasTypeSwitch,\n } = useEvmRelayerOptions({ options, onChange });\n\n return (\n <div className=\"space-y-4\">\n <AdvancedInfo\n showAdvancedInfo={showAdvancedInfo}\n onToggle={() => setShowAdvancedInfo(!showAdvancedInfo)}\n />\n\n <Tabs value={configMode} onValueChange={handleModeChange}>\n <TabsList className=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"speed\">Speed</TabsTrigger>\n <TabsTrigger value=\"custom\">Custom</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"speed\" className=\"space-y-4\">\n <SpeedSelection selectedSpeed={formValues.speed} onSpeedChange={handleSpeedChange} />\n </TabsContent>\n\n <TabsContent value=\"custom\" className=\"space-y-4\">\n <CustomGasParameters\n control={control}\n configMode={configMode}\n gasType={gasType}\n showGasLimit={formValues.showGasLimit || false}\n onGasTypeSwitch={handleGasTypeSwitch}\n />\n </TabsContent>\n </Tabs>\n </div>\n );\n};\n","import { Info } from 'lucide-react';\nimport React from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\n\ninterface AdvancedInfoProps {\n showAdvancedInfo: boolean;\n onToggle: () => void;\n}\n\nexport const AdvancedInfo: React.FC<AdvancedInfoProps> = ({ showAdvancedInfo, onToggle }) => {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <label className=\"text-base font-medium\">Gas Pricing Strategy</label>\n <Button variant=\"ghost\" size=\"sm\" onClick={onToggle} className=\"text-xs\" type=\"button\">\n <Info className=\"h-3 w-3 mr-1\" />\n API Requirements\n </Button>\n </div>\n\n {showAdvancedInfo && (\n <div className=\"mt-3 rounded-lg bg-muted/30 p-4\">\n <p className=\"text-sm text-muted-foreground leading-relaxed\">\n The OpenZeppelin Relayer API requires exactly one pricing strategy: either a{' '}\n <strong>Speed</strong> enum value (FASTEST, FAST, AVERAGE, SAFE_LOW) or{' '}\n <strong>custom gas parameters</strong> (gasPrice for legacy, or maxFeePerGas +\n maxPriorityFeePerGas for EIP-1559).\n </p>\n </div>\n )}\n </div>\n );\n};\n","import { Circle } from 'lucide-react';\nimport React from 'react';\nimport { Control } from 'react-hook-form';\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n BooleanField,\n NumberField,\n} from '@openzeppelin/ui-components';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { EvmRelayerFormData } from './useEvmRelayerOptions';\n\ninterface CustomGasParametersProps {\n control: Control<EvmRelayerFormData>;\n configMode: string;\n gasType: string;\n showGasLimit: boolean;\n onGasTypeSwitch: (type: string) => void;\n}\n\nexport const CustomGasParameters: React.FC<CustomGasParametersProps> = ({\n control,\n configMode,\n gasType,\n showGasLimit,\n onGasTypeSwitch,\n}) => {\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-lg bg-muted/50 p-4\">\n <p className=\"text-sm text-muted-foreground leading-relaxed\">\n Manually configure gas parameters. You must provide either <strong>Legacy</strong>{' '}\n (gasPrice) or <strong>EIP-1559</strong> (maxFeePerGas + maxPriorityFeePerGas) values.\n </p>\n </div>\n\n <div className=\"space-y-3\">\n <p className=\"text-xs text-muted-foreground font-medium uppercase tracking-wider\">\n Select Gas Pricing Method\n </p>\n\n <Accordion\n type=\"single\"\n collapsible\n value={gasType}\n onValueChange={(value) => value && onGasTypeSwitch(value)}\n className=\"w-full space-y-3\"\n >\n <AccordionItem\n value=\"eip1559\"\n className={cn(\n 'rounded-lg border shadow-sm overflow-hidden transition-all',\n gasType === 'eip1559'\n ? 'border-primary bg-primary/5'\n : 'border-border bg-card hover:border-muted-foreground/50'\n )}\n >\n <AccordionTrigger className=\"px-4 py-3 text-sm font-medium hover:no-underline\">\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Circle\n className={`h-4 w-4 ${gasType === 'eip1559' ? 'text-primary' : 'text-muted-foreground'}`}\n />\n {gasType === 'eip1559' && (\n <Circle className=\"h-4 w-4 absolute inset-0 text-primary fill-primary scale-50\" />\n )}\n </div>\n <span>EIP-1559</span>\n </div>\n {gasType === 'eip1559' && (\n <span className=\"text-xs text-primary font-medium mr-2\">Selected</span>\n )}\n </div>\n </AccordionTrigger>\n <AccordionContent>\n <div className=\"px-4 pb-4 pt-4 grid gap-4 border-t bg-background/50\">\n <NumberField\n id=\"maxFeePerGas\"\n label=\"Max Fee Per Gas\"\n name=\"transactionOptions.maxFeePerGas\"\n control={control}\n placeholder=\"30\"\n helperText=\"Maximum total fee per gas unit you're willing to pay (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'eip1559' }}\n />\n\n <NumberField\n id=\"maxPriorityFeePerGas\"\n label=\"Max Priority Fee Per Gas\"\n name=\"transactionOptions.maxPriorityFeePerGas\"\n control={control}\n placeholder=\"2\"\n helperText=\"Priority fee (tip) to incentivize miners (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'eip1559' }}\n />\n </div>\n </AccordionContent>\n </AccordionItem>\n\n <AccordionItem\n value=\"legacy\"\n className={cn(\n 'rounded-lg border shadow-sm overflow-hidden transition-all',\n gasType === 'legacy'\n ? 'border-primary bg-primary/5'\n : 'border-border bg-card hover:border-muted-foreground/50'\n )}\n >\n <AccordionTrigger className=\"px-4 py-3 text-sm font-medium hover:no-underline\">\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Circle\n className={`h-4 w-4 ${gasType === 'legacy' ? 'text-primary' : 'text-muted-foreground'}`}\n />\n {gasType === 'legacy' && (\n <Circle className=\"h-4 w-4 absolute inset-0 text-primary fill-primary scale-50\" />\n )}\n </div>\n <span>Legacy Gas Price</span>\n </div>\n {gasType === 'legacy' && (\n <span className=\"text-xs text-primary font-medium mr-2\">Selected</span>\n )}\n </div>\n </AccordionTrigger>\n <AccordionContent>\n <div className=\"px-4 pb-4 pt-4 border-t bg-background/50\">\n <NumberField\n id=\"gasPrice\"\n label=\"Gas Price\"\n name=\"transactionOptions.gasPrice\"\n control={control}\n placeholder=\"20\"\n helperText=\"Fixed gas price for legacy transactions (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'legacy' }}\n />\n </div>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n </div>\n\n <div className=\"space-y-2\">\n <BooleanField\n id=\"showGasLimit\"\n label=\"Override gas limit\"\n name=\"transactionOptions.showGasLimit\"\n control={control}\n helperText=\"Enable manual gas limit configuration\"\n />\n\n {showGasLimit && (\n <div className=\"pl-6\">\n <NumberField\n id=\"gasLimit\"\n label=\"Gas Limit\"\n name=\"transactionOptions.gasLimit\"\n control={control}\n placeholder=\"Auto-detected by relayer\"\n helperText=\"Leave empty to let the relayer estimate. Only override if you need a specific limit.\"\n step={1000}\n min={21000}\n />\n </div>\n )}\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nimport { Speed } from '@openzeppelin/relayer-sdk';\nimport { RadioGroup, RadioGroupItem } from '@openzeppelin/ui-components';\n\ninterface SpeedSelectionProps {\n selectedSpeed: Speed | undefined;\n onSpeedChange: (speed: Speed) => void;\n}\n\nconst speedOptions = [\n {\n value: Speed.FASTEST,\n label: 'Fastest',\n description: 'Maximum priority, highest gas prices',\n },\n {\n value: Speed.FAST,\n label: 'Fast',\n description: 'High priority, recommended for most transactions',\n recommended: true,\n },\n {\n value: Speed.AVERAGE,\n label: 'Average',\n description: 'Standard priority, balanced cost',\n },\n {\n value: Speed.SAFE_LOW,\n label: 'Safe Low',\n description: 'Lower priority, minimal gas cost',\n },\n];\n\nexport const SpeedSelection: React.FC<SpeedSelectionProps> = ({ selectedSpeed, onSpeedChange }) => {\n return (\n <RadioGroup\n value={selectedSpeed || Speed.FAST}\n onValueChange={(value) => onSpeedChange(value as Speed)}\n >\n <div className=\"space-y-3\">\n {speedOptions.map((option) => (\n <label\n key={option.value}\n htmlFor={`speed-${option.value}`}\n className={`relative block rounded-lg border p-4 cursor-pointer transition-colors ${\n selectedSpeed === option.value\n ? 'border-primary bg-primary/5'\n : 'border-border hover:border-muted-foreground/50'\n }`}\n >\n {option.recommended && (\n <span className=\"absolute -top-2 right-4 bg-primary text-primary-foreground text-xs px-2 py-0.5 rounded\">\n Recommended\n </span>\n )}\n <div className=\"flex items-start space-x-3\">\n <RadioGroupItem\n value={option.value}\n id={`speed-${option.value}`}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1\">\n <div className=\"font-medium\">{option.label}</div>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{option.description}</p>\n </div>\n </div>\n </label>\n ))}\n </div>\n </RadioGroup>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { Speed } from '@openzeppelin/relayer-sdk';\nimport {\n gweiToWei,\n weiToGwei,\n type EvmRelayerTransactionOptions,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport interface EvmRelayerFormData {\n transactionOptions: EvmRelayerTransactionOptions & {\n showGasLimit?: boolean;\n };\n}\n\ninterface UseEvmRelayerOptionsProps {\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n}\n\nexport const useEvmRelayerOptions = ({ options, onChange }: UseEvmRelayerOptionsProps) => {\n // Store latest onChange in a ref to avoid effect re-runs due to changing function identity\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n // Initialize form with options from parent (only on mount to prevent loops)\n const initialOptions = {\n speed: (() => {\n const hasCustomSettings = Boolean(\n options.gasPrice || options.maxFeePerGas || options.maxPriorityFeePerGas\n );\n return options.speed || (!hasCustomSettings ? Speed.FAST : undefined);\n })() as Speed,\n gasPrice: weiToGwei(options.gasPrice as number | undefined),\n maxFeePerGas: weiToGwei(options.maxFeePerGas as number | undefined),\n maxPriorityFeePerGas: weiToGwei(options.maxPriorityFeePerGas as number | undefined),\n gasLimit: options.gasLimit as number | undefined,\n showGasLimit: Boolean(options.gasLimit),\n };\n\n const { control, setValue, watch } = useForm<EvmRelayerFormData>({\n defaultValues: {\n transactionOptions: initialOptions,\n },\n });\n\n const formValues = watch('transactionOptions');\n const isInitialMount = useRef(true);\n\n // Determine current mode and gas type\n const hasCustomSettings = Boolean(\n formValues.gasPrice || formValues.maxFeePerGas || formValues.maxPriorityFeePerGas\n );\n const configMode = hasCustomSettings ? 'custom' : 'speed';\n const isEip1559 = Boolean(formValues.maxFeePerGas || formValues.maxPriorityFeePerGas);\n const gasType = isEip1559 ? 'eip1559' : 'legacy';\n\n // Handle initial mount - ensure the default speed value is communicated to parent\n useEffect(() => {\n if (isInitialMount.current) {\n isInitialMount.current = false;\n\n // Only notify parent if we have a default speed value that wasn't already in options\n if (initialOptions.speed && !options.speed) {\n const newOptions: EvmRelayerTransactionOptions = {};\n if (initialOptions.speed) newOptions.speed = initialOptions.speed;\n if (initialOptions.gasLimit) newOptions.gasLimit = initialOptions.gasLimit;\n\n onChange(newOptions as Record<string, unknown>);\n }\n return;\n }\n }, []);\n\n // Notify parent of changes after initial mount (watch specific fields to avoid loops)\n useEffect(() => {\n if (isInitialMount.current) {\n return;\n }\n\n const timeoutId = setTimeout(() => {\n const newOptions: EvmRelayerTransactionOptions = {};\n\n if (formValues.speed) newOptions.speed = formValues.speed;\n if (formValues.gasPrice) newOptions.gasPrice = gweiToWei(formValues.gasPrice);\n if (formValues.maxFeePerGas) newOptions.maxFeePerGas = gweiToWei(formValues.maxFeePerGas);\n if (formValues.maxPriorityFeePerGas) {\n newOptions.maxPriorityFeePerGas = gweiToWei(formValues.maxPriorityFeePerGas);\n }\n if (formValues.gasLimit) newOptions.gasLimit = formValues.gasLimit;\n\n onChangeRef.current(newOptions as Record<string, unknown>);\n }, 100);\n\n return () => clearTimeout(timeoutId);\n }, [\n formValues.speed,\n formValues.gasPrice,\n formValues.maxFeePerGas,\n formValues.maxPriorityFeePerGas,\n formValues.gasLimit,\n ]);\n\n // Event handlers\n const handleSpeedChange = (speed: Speed) => {\n setValue('transactionOptions', {\n ...formValues,\n speed,\n gasPrice: undefined,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n });\n };\n\n const handleModeChange = (mode: string) => {\n if (mode === 'speed') {\n setValue('transactionOptions', {\n ...formValues,\n speed: Speed.FAST,\n gasPrice: undefined,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n });\n } else {\n setValue('transactionOptions', {\n ...formValues,\n speed: undefined,\n maxFeePerGas: 30,\n maxPriorityFeePerGas: 2,\n });\n }\n };\n\n const handleGasTypeSwitch = (type: string) => {\n if (type === 'eip1559') {\n setValue('transactionOptions', {\n ...formValues,\n gasPrice: undefined,\n maxFeePerGas: 30,\n maxPriorityFeePerGas: 2,\n });\n } else {\n setValue('transactionOptions', {\n ...formValues,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n gasPrice: 20,\n });\n }\n };\n\n return {\n control,\n formValues,\n configMode,\n gasType,\n handleSpeedChange,\n handleModeChange,\n handleGasTypeSwitch,\n };\n};\n","import type { GetAccountReturnType } from '@wagmi/core';\n\nimport {\n connectAndEnsureCorrectNetworkCore,\n DEFAULT_DISCONNECTED_STATUS,\n type EvmWalletConnectionResult,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { Connector } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport {\n getEvmWalletImplementation,\n getInitializedEvmWalletImplementation,\n} from './walletImplementationManager';\n\nconst LOG_SYSTEM = 'adapter-evm-connection';\n\n/**\n * Indicates if this adapter implementation supports wallet connection.\n */\nexport function evmSupportsWalletConnection(): boolean {\n // For now, assume EVM always supports wallet connection if wagmi can be initialized.\n // This might depend on walletConnectProjectId being available for WalletConnect to be viable.\n return true;\n}\n\n/**\n * Gets the list of available wallet connectors supported by this adapter's implementation.\n */\nexport async function getEvmAvailableConnectors(): Promise<Connector[]> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.warn(LOG_SYSTEM, 'getEvmAvailableConnectors: Wallet implementation not ready.');\n return [];\n }\n return impl.getAvailableConnectors();\n}\n\n/**\n * Initiates the wallet connection process for a specific connector and ensures the network is correct.\n *\n * @param connectorId - The ID of the connector to use.\n * @param targetChainId - The desired chain ID to switch to after connection.\n * @returns An object containing connection status, address, and any error.\n */\nexport async function connectAndEnsureCorrectNetwork(\n connectorId: string,\n targetChainId: number\n): Promise<EvmWalletConnectionResult> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.error(LOG_SYSTEM, 'connectAndEnsureCorrectNetwork: Wallet implementation not ready.');\n return { connected: false, error: 'Wallet system not initialized.' };\n }\n\n return connectAndEnsureCorrectNetworkCore(impl, connectorId, targetChainId, LOG_SYSTEM);\n}\n\n/**\n * Disconnects the currently connected EVM wallet.\n */\nexport async function disconnectEvmWallet(): Promise<{\n disconnected: boolean;\n error?: string;\n}> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.warn(LOG_SYSTEM, 'disconnectEvmWallet: Wallet implementation not ready.');\n return { disconnected: false, error: 'Wallet system not initialized.' };\n }\n return impl.disconnect();\n}\n\n/**\n * Gets the current wallet connection status.\n * This function might need to become async if getEvmWalletImplementation is async\n * and the status depends on an initialized instance.\n * For now, assuming getWalletConnectionStatus on the impl is synchronous after init.\n */\nexport function getEvmWalletConnectionStatus(): GetAccountReturnType {\n const impl = getInitializedEvmWalletImplementation();\n if (!impl) {\n logger.warn(\n LOG_SYSTEM,\n 'getEvmWalletConnectionStatus: Wallet implementation not ready. Returning default disconnected state.'\n );\n return DEFAULT_DISCONNECTED_STATUS;\n }\n return impl.getWalletConnectionStatus();\n}\n\n/**\n * Subscribes to wallet connection changes.\n */\nexport function onEvmWalletConnectionChange(\n callback: (account: GetAccountReturnType, prevAccount: GetAccountReturnType) => void\n): () => void {\n // Return type is now synchronous () => void\n const walletImplementation = getInitializedEvmWalletImplementation(); // Use sync getter\n if (!walletImplementation) {\n logger.warn(\n 'onEvmWalletConnectionChange',\n 'Wallet implementation not initialized. Cannot subscribe to changes. Returning no-op.'\n );\n return () => {}; // Return a no-op unsubscribe function\n }\n return walletImplementation.onWalletConnectionChange(callback);\n}\n","import {\n CustomAccountDisplay,\n CustomConnectButton,\n CustomNetworkSwitcher,\n filterWalletComponents,\n getComponentExclusionsFromConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createRainbowKitComponents, validateRainbowKitConfig } from '../rainbowkit';\n\n/** Service for resolving UI kit specific components and providers for the EVM adapter. */\n\n/**\n * Determines the final set of wallet components to be provided by the adapter\n * based on the UI kit configuration and any specified exclusions.\n *\n * @param uiKitConfiguration - The UiKitConfiguration from the adapter instance.\n * @returns The EcosystemWalletComponents object or undefined.\n */\nexport function getResolvedWalletComponents(\n uiKitConfiguration: UiKitConfiguration\n): EcosystemWalletComponents | undefined {\n logger.debug(\n 'uiKitService:getResolvedWalletComponents',\n 'Received uiKitConfiguration:',\n JSON.stringify(uiKitConfiguration)\n );\n\n const currentKitName = uiKitConfiguration.kitName || 'custom';\n\n if (currentKitName === 'none') {\n logger.info(\n 'uiKitService',\n 'UI Kit set to \"none\" for getResolvedWalletComponents, not providing wallet components.'\n );\n return undefined;\n }\n\n const exclusions = getComponentExclusionsFromConfig(uiKitConfiguration.kitConfig);\n logger.debug(\n 'uiKitService',\n `Extracted component exclusions for ${currentKitName}: ${exclusions.join(', ') || 'none'}.`\n );\n\n // TODO: If many more UI kits are added, this conditional logic could be refactored\n // using a map or strategy pattern to resolve components based on kitName.\n // For example: const componentFactory = this.kitComponentFactories[currentKitName];\n // if (componentFactory) { return filterWalletComponents(componentFactory(), exclusions, currentKitName); }\n if (currentKitName === 'custom') {\n const allCustomComponents: EcosystemWalletComponents = {\n ConnectButton: CustomConnectButton,\n AccountDisplay: CustomAccountDisplay,\n NetworkSwitcher: CustomNetworkSwitcher,\n };\n return filterWalletComponents(allCustomComponents, exclusions, currentKitName);\n }\n\n if (currentKitName === 'rainbowkit') {\n const validation = validateRainbowKitConfig(uiKitConfiguration.kitConfig);\n\n if (!validation.isValid) {\n logger.warn(\n 'uiKitService',\n `Invalid RainbowKit configuration for components: ${validation.error}. No components provided.`\n );\n return undefined; // Fail fast for components if config is invalid for RainbowKit\n }\n\n // Get RainbowKit components and apply any exclusions\n const rainbowKitComponents = createRainbowKitComponents();\n logger.info('uiKitService', 'Providing RainbowKit components.');\n return filterWalletComponents(rainbowKitComponents, exclusions, currentKitName);\n }\n // if (currentKitName === 'connectkit') { /* return ConnectKit components */ }\n // if (currentKitName === 'appkit') { /* return AppKit components */ }\n logger.warn(\n 'uiKitService',\n `UI Kit \"${currentKitName}\" for getResolvedWalletComponents not explicitly supported. No components provided.`\n );\n return undefined;\n}\n","/**\n * EVM Adapter RainbowKit Components\n *\n * This file exports only React components to support Fast Refresh.\n * Factory functions are in componentFactory.ts.\n */\nimport { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\n\nimport { evmUiKitManager } from '../evmUiKitManager';\n\n/**\n * Props for the RainbowKitConnectButton component.\n */\nexport type RainbowKitConnectButtonProps = BaseComponentProps;\n\n/**\n * RainbowKitConnectButton component configured with the EVM UI kit manager.\n * This component lazily loads the RainbowKit ConnectButton and manages\n * its state through the evmUiKitManager.\n */\nexport const RainbowKitConnectButton: React.FC<RainbowKitConnectButtonProps> =\n createRainbowKitConnectButton(evmUiKitManager);\n","/**\n * EVM Adapter RainbowKit Component Factory\n *\n * Factory function for creating RainbowKit components.\n * Separated from components.tsx to support React Fast Refresh.\n */\nimport { createRainbowKitComponents as coreCreateRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport { RainbowKitConnectButton } from './components';\n\n/**\n * Creates the complete set of RainbowKit wallet components for the EVM adapter.\n *\n * @returns An object containing all RainbowKit wallet components\n */\nexport function createRainbowKitComponents() {\n return coreCreateRainbowKitComponents(RainbowKitConnectButton);\n}\n","import type { GetAccountReturnType } from '@wagmi/core';\n\nimport type { EvmWalletConnectionStatus } from '../types';\n\n/**\n * Converts wagmi's GetAccountReturnType to our enhanced EvmWalletConnectionStatus.\n * This utility preserves all the rich UX capabilities from wagmi while ensuring\n * compatibility with our adapter interface.\n *\n * @param wagmiStatus - The status object from wagmi's GetAccountReturnType\n * @returns Enhanced EvmWalletConnectionStatus with all wagmi properties\n */\nexport function convertWagmiToEvmStatus(\n wagmiStatus: GetAccountReturnType\n): EvmWalletConnectionStatus {\n return {\n isConnected: wagmiStatus.isConnected,\n isConnecting: wagmiStatus.isConnecting,\n isDisconnected: wagmiStatus.isDisconnected,\n isReconnecting: wagmiStatus.isReconnecting,\n status: wagmiStatus.status,\n address: wagmiStatus.address,\n chainId: wagmiStatus.chainId?.toString(),\n addresses: wagmiStatus.addresses,\n connector: wagmiStatus.connector\n ? {\n id: wagmiStatus.connector.id,\n name: wagmiStatus.connector.name,\n type: wagmiStatus.connector.type,\n }\n : undefined,\n chain: wagmiStatus.chain ? { ...wagmiStatus.chain } : undefined,\n };\n}\n","import type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\n\n// Import the actual service functions instead of using placeholders\nimport { getResolvedWalletComponents as getWalletComponentsFromService } from './utils/uiKitService';\n\n// Function to get wallet components based on UiKitConfiguration\nexport function getResolvedWalletComponents(\n uiKitConfig: UiKitConfiguration\n): EcosystemWalletComponents | undefined {\n return getWalletComponentsFromService(uiKitConfig);\n}\n","/**\n * Configuration for the EVM adapter\n *\n * This file defines the dependencies required by the EVM adapter\n * when generating exported projects. It follows the AdapterConfig\n * interface to provide a structured approach to dependency management.\n */\nimport type { AdapterConfig } from '@openzeppelin/ui-types';\n\nexport const evmAdapterConfig: AdapterConfig = {\n /**\n * Dependencies required by the EVM adapter\n * These will be included in exported projects that use this adapter\n */\n dependencies: {\n // Runtime dependencies\n runtime: {\n // Core EVM libraries\n // Wallet connection libraries\n wagmi: '^2.15.0',\n '@wagmi/core': '^2.20.3',\n viem: '^2.28.0',\n '@tanstack/react-query': '^5.0.0',\n // Utility library\n // lodash: '^4.17.21',\n },\n\n // Development dependencies\n dev: {\n // '@types/lodash': '^4.17.16',\n '@types/lodash': '^4.17.5',\n },\n },\n overrides: {\n 'use-sync-external-store': '^1.2.0',\n valtio: '^1.13.2',\n },\n uiKits: {\n rainbowkit: {\n dependencies: {\n runtime: {\n '@rainbow-me/rainbowkit': '^2.2.8',\n },\n },\n overrides: {\n '@paulmillr/qr': 'npm:qr@^0.5.0',\n '@walletconnect/modal': '^2.7.1',\n },\n },\n },\n};\n"],"mappings":"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","names":["import_viem","import_ui_utils","import_lodash","import_react","import_ui_components","import_ui_react","import_jsx_runtime","import_lucide_react","import_core","init_artifacts","__export","logger","__export","SYSTEM_LOG_TAG","init_eoa","logger","module","userNetworkServiceConfigService","appConfigService","isAddress","validateAndConvertEvmArtifacts","simpleHash","createPublicClient","http","logger","SYSTEM_LOG_TAG","EoaExecutionStrategy","RelayerExecutionStrategy","jsx","connect","useState","useEffect","jsxs","Button","useDerivedAccountStatus","useDerivedConnectStatus","disconnect","cn","switchChain","Loader2","__publicField","appConfigService","http","defaultConfig","uiKitConfig","getWagmiWalletClient","getWagmiCorePublicClient","useState","useContext","useEffect","logger","getWalletButtonSizeProps","jsxs","Button","cn","jsx","Loader2","RainbowKitConnectButton","http","LOG_PREFIX","module","SYSTEM_LOG_TAG","logger","import_ui_utils","import_core","import_chains","import_react","import_ui_utils","import_ui_utils","import_react","viemMainnet","viemArbitrum","viemPolygon","viemPolygonZkEvm","viemBase","viemBsc","viemOptimism","viemAvalanche","viemZkSync","viemScroll","viemLinea","import_react","import_chains","viemSepolia","viemArbitrumSepolia","viemPolygonAmoy","viemPolygonZkEvmCardona","viemBaseSepolia","viemBscTestnet","viemOptimismSepolia","viemAvalancheFuji","viemZkSyncSepoliaTestnet","viemScrollSepolia","viemLineaSepolia","viemMonadTestnet","getSupportedChainsFromNetworks","import_jsx_runtime","import_wagmi","import_ui_utils","import_ui_utils","import_ui_utils","import_ui_utils","queryEvmViewFunction","import_react","import_ui_components","import_lucide_react","import_ui_components","import_jsx_runtime","import_lucide_react","import_ui_components","import_ui_utils","import_jsx_runtime","import_relayer_sdk","import_ui_components","import_jsx_runtime","import_react","import_relayer_sdk","hasCustomSettings","import_jsx_runtime","React","import_ui_utils","LOG_SYSTEM","import_ui_utils","createRainbowKitComponents","createRainbowKitComponents","getResolvedWalletComponents","uiKitConfig","queryEvmViewFunction","getResolvedWalletComponents","uiKitConfig"]}
1
+ {"version":3,"sources":["../src/index.ts","../../adapter-evm-core/src/types/artifacts.ts","../../adapter-evm-core/src/utils/artifacts.ts","../../adapter-evm-core/src/utils/json.ts","../../adapter-evm-core/src/utils/formatting.ts","../../adapter-evm-core/src/utils/public-client.ts","../../adapter-evm-core/src/utils/validation.ts","../../adapter-evm-core/src/utils/gas.ts","../../adapter-evm-core/src/utils/index.ts","../../adapter-evm-core/src/validation/eoa.ts","../../adapter-evm-core/src/transaction/eoa.ts","../../adapter-evm-core/src/transaction/relayer.ts","../../adapter-evm-core/src/abi/transformer.ts","../../adapter-evm-core/src/abi/etherscan.ts","../../adapter-evm-core/src/configuration/explorer.ts","../../adapter-evm-core/src/abi/etherscan-v2.ts","../../adapter-evm-core/src/abi/sourcify.ts","../../adapter-evm-core/src/abi/loader.ts","../../adapter-evm-core/src/proxy/detection.ts","../../adapter-evm-core/src/configuration/rpc.ts","../../adapter-evm-core/src/types/providers.ts","../../adapter-evm-core/src/abi/types.ts","../../adapter-evm-core/src/abi/comparison.ts","../../adapter-evm-core/src/mapping/constants.ts","../../adapter-evm-core/src/mapping/type-mapper.ts","../../adapter-evm-core/src/mapping/field-generator.ts","../../adapter-evm-core/src/transform/input-parser.ts","../../adapter-evm-core/src/transform/output-formatter.ts","../../adapter-evm-core/src/query/handler.ts","../../adapter-evm-core/src/query/view-checker.ts","../../adapter-evm-core/src/transaction/formatter.ts","../../adapter-evm-core/src/transaction/index.ts","../../adapter-evm-core/src/transaction/sender.ts","../../adapter-evm-core/src/wallet/context/wagmi-context.tsx","../../adapter-evm-core/src/wallet/hooks/useIsWagmiProviderInitialized.ts","../../adapter-evm-core/src/wallet/components/SafeWagmiComponent.tsx","../../adapter-evm-core/src/wallet/components/connect/ConnectButton.tsx","../../adapter-evm-core/src/wallet/components/connect/ConnectorDialog.tsx","../../adapter-evm-core/src/wallet/components/account/AccountDisplay.tsx","../../adapter-evm-core/src/wallet/components/network/NetworkSwitcher.tsx","../../adapter-evm-core/src/wallet/connection.ts","../../adapter-evm-core/src/wallet/wagmi-implementation.ts","../../adapter-evm-core/src/configuration/access-control-indexer.ts","../../adapter-evm-core/src/configuration/network-services.ts","../../adapter-evm-core/src/types/index.ts","../../adapter-evm-core/src/wallet/rainbowkit/config-generator.ts","../../adapter-evm-core/src/wallet/rainbowkit/types.ts","../../adapter-evm-core/src/wallet/rainbowkit/utils.ts","../../adapter-evm-core/src/wallet/rainbowkit/components.tsx","../../adapter-evm-core/src/wallet/rainbowkit/componentFactory.ts","../../adapter-evm-core/src/wallet/rainbowkit/config-service.ts","../../adapter-evm-core/src/wallet/uiKitManager.ts","../../adapter-evm-core/src/wallet/rainbowkitAssetManager.ts","../../adapter-evm-core/src/wallet/configResolution.ts","../../adapter-evm-core/src/wallet/utils/filterWalletComponents.ts","../../adapter-evm-core/src/validation/index.ts","../../adapter-evm-core/src/validation/relayer.ts","../../adapter-evm-core/src/validation/execution.ts","../../adapter-evm-core/src/index.ts","../../adapter-evm-core/src/access-control/abis.ts","../../adapter-evm-core/src/access-control/actions.ts","../../adapter-evm-core/src/access-control/constants.ts","../../adapter-evm-core/src/access-control/feature-detection.ts","../../adapter-evm-core/src/access-control/indexer-client.ts","../../adapter-evm-core/src/access-control/onchain-reader.ts","../../adapter-evm-core/src/access-control/role-discovery.ts","../../adapter-evm-core/src/access-control/service.ts","../../adapter-evm-core/src/access-control/validation.ts","../src/adapter.ts","../src/wallet/components/EvmWalletUiRoot.tsx","../src/wallet/utils/walletImplementationManager.ts","../src/networks/mainnet.ts","../src/networks/testnet.ts","../src/networks/index.ts","../src/wallet/implementation/wagmi-implementation.ts","../src/wallet/evmUiKitManager.ts","../src/wallet/hooks/facade-hooks.ts","../src/wallet/hooks/useUiKitConfig.ts","../src/configuration/execution.ts","../src/configuration/network-services.ts","../src/query/adapter-query.ts","../src/transaction/components/EvmRelayerOptions.tsx","../src/transaction/components/AdvancedInfo.tsx","../src/transaction/components/CustomGasParameters.tsx","../src/transaction/components/SpeedSelection.tsx","../src/transaction/components/useEvmRelayerOptions.ts","../src/wallet/utils/connection.ts","../src/wallet/utils/uiKitService.ts","../src/wallet/rainbowkit/components.tsx","../src/wallet/rainbowkit/componentFactory.ts","../src/wallet/utils/wallet-status.ts","../src/wallet/utils.ts","../src/config.ts","../src/metadata.ts"],"sourcesContent":["import type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EcosystemExport } from '@openzeppelin/ui-types';\n\nimport { EvmAdapter } from './adapter';\nimport { evmAdapterConfig } from './config';\nimport { ecosystemMetadata } from './metadata';\nimport { evmNetworks } from './networks';\n\nexport { ecosystemMetadata } from './metadata';\nexport { EvmAdapter } from './adapter';\n\nexport const ecosystemDefinition: EcosystemExport = {\n ...ecosystemMetadata,\n networks: evmNetworks,\n createAdapter: (config) => new EvmAdapter(config as TypedEvmNetworkConfig),\n adapterConfig: evmAdapterConfig,\n};\n\n// RainbowKit customization types (re-exported from core via rainbowkit/index.ts)\nexport type {\n AppInfo,\n RainbowKitConnectButtonProps,\n RainbowKitProviderProps,\n RainbowKitKitConfig,\n RainbowKitCustomizations,\n} from './wallet/rainbowkit';\nexport { isRainbowKitCustomizations, extractRainbowKitCustomizations } from './wallet/rainbowkit';\n\n// Individual network exports (useful for specific references)\nexport {\n ethereumMainnet,\n arbitrumMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n baseMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n ethereumSepolia,\n arbitrumSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n baseSepolia,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n} from './networks';\n\n// Core types for public API compatibility\nexport type {\n TypedEvmNetworkConfig,\n WriteContractParameters,\n EvmContractArtifacts,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nexport {\n isEvmContractArtifacts,\n abiComparisonService,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport type { EvmRelayerTransactionOptions } from '@openzeppelin/ui-builder-adapter-evm-core';\n","/**\n * EVM-specific contract artifacts interface\n * Defines the structure of data needed to load EVM contracts\n */\nimport type { EvmContractDefinitionProviderKey } from './providers';\n\nexport interface EvmContractArtifacts {\n /** The deployed contract address (required) */\n contractAddress: string;\n\n /** Optional manual ABI JSON string (for unverified contracts) */\n contractDefinition?: string;\n\n /** Optional proxy detection configuration */\n __proxyDetectionOptions?: {\n /** Skip automatic proxy detection */\n skipProxyDetection?: boolean;\n };\n\n /** Optional forced provider for this load attempt (session-scoped override) */\n __forcedProvider?: EvmContractDefinitionProviderKey;\n}\n\n/**\n * Type guard to check if an object matches EvmContractArtifacts structure\n */\nexport function isEvmContractArtifacts(obj: unknown): obj is EvmContractArtifacts {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n typeof (obj as Record<string, unknown>).contractAddress === 'string'\n );\n}\n","/**\n * Utility functions for EVM contract artifacts validation and conversion\n */\nimport type { EvmContractArtifacts } from '../types/artifacts';\nimport { isEvmContractArtifacts } from '../types/artifacts';\n\n/**\n * Validates and converts generic source input to EvmContractArtifacts\n *\n * @param source - Generic contract source (string address or artifacts object)\n * @returns Validated EvmContractArtifacts\n * @throws Error if the source is invalid\n */\nexport function validateAndConvertEvmArtifacts(\n source: string | Record<string, unknown>\n): EvmContractArtifacts {\n if (typeof source === 'string') {\n // If source is a string, assume it's a contract address\n return { contractAddress: source };\n }\n\n // Validate that the object has the required structure\n if (!isEvmContractArtifacts(source)) {\n throw new Error(\n 'Invalid contract artifacts provided. Expected an object with contractAddress property.'\n );\n }\n\n return source;\n}\n","/**\n * Custom JSON stringifier that handles BigInt values by converting them to strings.\n * @param value The value to stringify.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON text for readability.\n * @returns A JSON string representing the given value.\n */\nexport function stringifyWithBigInt(value: unknown, space?: number | string): string {\n const replacer = (_key: string, val: unknown) => {\n // Check if the value is a BigInt\n if (typeof val === 'bigint') {\n // Convert BigInt to string\n return val.toString();\n }\n // Return the value unchanged for other types\n return val;\n };\n\n return JSON.stringify(value, replacer, space);\n}\n","/**\n * Format a method name for display (e.g., from camelCase to Title Case).\n */\nexport function formatMethodName(name: string): string {\n if (!name) return '';\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (str) => str.toUpperCase())\n .trim();\n}\n\n/**\n * Format an input name for display (e.g., from camelCase or snake_case to Title Case).\n * Provides a default name based on type if the original name is empty.\n */\nexport function formatInputName(name: string, type: string): string {\n if (!name || name === '') {\n return `Parameter (${type})`; // Use type if name is missing\n }\n return name\n .replace(/([A-Z])/g, ' $1') // Add space before capitals\n .replace(/_/g, ' ') // Replace underscores with spaces\n .replace(/^./, (str) => str.toUpperCase()) // Capitalize first letter\n .trim();\n}\n","/**\n * Shared Viem Public Client Factory\n *\n * Creates a viem `PublicClient` for on-chain reads. Consolidates client creation\n * logic that was previously duplicated across query/handler.ts, access-control/onchain-reader.ts,\n * and access-control/role-discovery.ts.\n *\n * @module utils/public-client\n */\n\nimport { createPublicClient, http, type Chain, type PublicClient, type Transport } from 'viem';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nconst LOG_SYSTEM = 'createEvmPublicClient';\n\n/**\n * Default minimal chain config used when no `viemChain` is provided.\n * Sufficient for `readContract()` calls where chain metadata is not needed.\n */\nfunction buildMinimalChain(rpcUrl: string): Chain {\n return {\n id: 1,\n name: 'Unknown',\n nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },\n rpcUrls: {\n default: { http: [rpcUrl] },\n },\n };\n}\n\n/**\n * Creates a viem `PublicClient` for on-chain reads.\n *\n * If `viemChain` is provided, it is used directly. Otherwise a minimal chain\n * config is built from the RPC URL — this is sufficient for `readContract()`\n * calls where chain metadata (block explorers, native currency, etc.) is not required.\n *\n * @param rpcUrl - The RPC endpoint URL\n * @param viemChain - Optional viem Chain object with full chain metadata\n * @returns A viem PublicClient ready for on-chain reads\n * @throws If client creation fails (e.g. invalid RPC URL)\n */\nexport function createEvmPublicClient(\n rpcUrl: string,\n viemChain?: Chain\n): PublicClient<Transport, Chain> {\n if (!viemChain) {\n logger.debug(LOG_SYSTEM, 'No viemChain provided, using minimal chain config');\n }\n\n const chain = viemChain ?? buildMinimalChain(rpcUrl);\n\n return createPublicClient({\n chain,\n transport: http(rpcUrl),\n }) as PublicClient<Transport, Chain>;\n}\n","import { isAddress } from 'viem';\n\n/**\n * Validates if a string is a valid EVM address.\n * @param address The address string to validate.\n * @returns True if the address is valid, false otherwise.\n */\nexport function isValidEvmAddress(address: string): boolean {\n return isAddress(address);\n}\n","import { formatGwei, parseGwei } from 'viem';\n\n/**\n * Convert wei values to gwei for display using viem\n */\nexport const weiToGwei = (wei?: number): number | undefined => {\n if (!wei) return undefined;\n return parseFloat(formatGwei(BigInt(wei)));\n};\n\n/**\n * Convert gwei values to wei using viem\n */\nexport const gweiToWei = (gwei?: number): number | undefined => {\n if (!gwei) return undefined;\n return Number(parseGwei(gwei.toString()));\n};\n","/**\n * Utils Module\n *\n * Utility functions for EVM operations including JSON handling,\n * formatting, gas calculations, validation, and artifacts processing.\n *\n * @module utils\n */\n\n// Barrel file for utils module\nexport * from './artifacts';\nexport * from './json';\nexport * from './formatting';\nexport * from './public-client';\nexport * from './validation';\nexport * from './gas';\n","import type { EoaExecutionConfig } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { isValidEvmAddress } from '../utils/validation';\n\nconst SYSTEM_LOG_TAG = 'EoaValidator';\n\n/**\n * Wallet connection status for EOA validation\n */\nexport interface EvmWalletStatus {\n isConnected: boolean;\n address?: string;\n}\n\n/**\n * Validates an EOA execution configuration.\n *\n * @param config The EOA execution config to validate\n * @param walletStatus Optional wallet connection status for address validation\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateEoaConfig(\n config: EoaExecutionConfig,\n walletStatus?: EvmWalletStatus\n): Promise<true | string> {\n if (!config.allowAny) {\n if (!config.specificAddress) {\n return \"EOA execution selected, but no specific address was provided when 'allowAny' is false.\";\n }\n if (!isValidEvmAddress(config.specificAddress)) {\n return `Invalid specific EOA address format: ${config.specificAddress}`;\n }\n if (walletStatus?.isConnected && walletStatus.address) {\n if (walletStatus.address.toLowerCase() !== config.specificAddress.toLowerCase()) {\n return `Connected wallet address (${walletStatus.address}) does not match the required specific EOA address (${config.specificAddress}). Please connect the correct wallet.`;\n }\n } else if (walletStatus?.isConnected && !walletStatus.address) {\n logger.warn(\n SYSTEM_LOG_TAG,\n 'Wallet is connected but address is unavailable for EOA validation.'\n );\n return 'Connected wallet address is not available for validation against specific EOA.';\n }\n }\n return true;\n}\n\n/**\n * Simple validation of EOA config without wallet status check.\n * Useful for static validation before execution.\n */\nexport function validateEvmEoaConfig(config: EoaExecutionConfig): boolean {\n if (!config.allowAny) {\n if (!config.specificAddress) {\n return false;\n }\n if (!isValidEvmAddress(config.specificAddress)) {\n return false;\n }\n }\n return true;\n}\n","/**\n * EOA Execution Strategy\n *\n * Implements transaction execution for Externally Owned Accounts (EOA).\n * This strategy signs and broadcasts transactions directly from the user's\n * connected wallet, which is the most common way of interacting with a blockchain.\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\nimport type { WalletClient } from 'viem';\n\nimport type {\n EoaExecutionConfig,\n ExecutionConfig,\n TransactionStatusUpdate,\n TxStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WriteContractParameters } from '../types/abi';\nimport { validateEoaConfig } from '../validation/eoa';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\nconst SYSTEM_LOG_TAG = 'EoaExecutionStrategy';\n\n/**\n * Implements the ExecutionStrategy for a standard Externally Owned Account (EOA).\n * This strategy involves signing and broadcasting a transaction directly from the user's\n * connected wallet, which is the most common way of interacting with a blockchain.\n */\nexport class EoaExecutionStrategy implements AdapterExecutionStrategy {\n public async execute(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n // runtimeApiKey is unused in EOA strategy but required by the interface\n _runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const { walletClient, accountStatus } =\n await this.getAuthenticatedWalletClient(walletImplementation);\n\n // Final validation at the point of execution\n const eoaConfig = executionConfig as EoaExecutionConfig;\n const validationResult = await validateEoaConfig(eoaConfig, {\n isConnected: accountStatus.isConnected,\n address: accountStatus.address,\n });\n if (validationResult !== true) {\n throw new Error(validationResult);\n }\n\n logger.info(SYSTEM_LOG_TAG, 'Using EOA execution strategy.');\n try {\n logger.debug(SYSTEM_LOG_TAG, 'Calling walletClient.writeContract with:', {\n account: accountStatus.address,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n\n onStatusChange('pendingSignature', {});\n\n const hash = await walletClient.writeContract({\n account: accountStatus.address!,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n\n logger.info(SYSTEM_LOG_TAG, 'EOA Transaction initiated. Hash:', hash);\n return { txHash: hash };\n } catch (error: unknown) {\n logger.error(SYSTEM_LOG_TAG, 'Error during EOA writeContract call:', error);\n const errorMessage = error instanceof Error ? error.message : 'Unknown EOA transaction error';\n throw new Error(`Transaction failed (EOA): ${errorMessage}`);\n }\n }\n\n private async getAuthenticatedWalletClient(\n walletImplementation: EvmWalletImplementation\n ): Promise<{\n walletClient: WalletClient;\n accountStatus: GetAccountReturnType;\n }> {\n const walletClient = await walletImplementation.getWalletClient();\n if (!walletClient) {\n logger.error(SYSTEM_LOG_TAG, 'Wallet client not available. Is wallet connected?');\n throw new Error('Wallet is not connected or client is unavailable.');\n }\n\n const accountStatus = walletImplementation.getWalletConnectionStatus();\n if (!accountStatus.isConnected || !accountStatus.address) {\n logger.error(SYSTEM_LOG_TAG, 'Account not available. Is wallet connected?');\n throw new Error('Wallet is not connected or account address is unavailable.');\n }\n return { walletClient, accountStatus };\n }\n}\n","/**\n * Relayer Execution Strategy\n *\n * Implements transaction execution through the OpenZeppelin Relayer service.\n * This strategy sends transactions to a relayer for gas sponsorship and broadcasting.\n */\n\nimport { encodeFunctionData, formatEther } from 'viem';\n\nimport {\n Configuration,\n RelayersApi,\n Speed,\n type ApiResponseRelayerResponseData,\n type EvmTransactionRequest,\n type EvmTransactionResponse,\n} from '@openzeppelin/relayer-sdk';\nimport type {\n ExecutionConfig,\n RelayerDetails,\n RelayerDetailsRich,\n RelayerExecutionConfig,\n TransactionStatusUpdate,\n TxStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { EvmCompatibleNetworkConfig } from '../types';\nimport type { WriteContractParameters } from '../types/abi';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\n/**\n * EVM-specific transaction options for the OpenZeppelin Relayer.\n * These options map directly to the EvmTransactionRequest parameters in the SDK.\n */\nexport interface EvmRelayerTransactionOptions {\n // Basic options that most users will want to configure\n speed?: Speed;\n gasLimit?: number;\n\n // Advanced options for fine-grained control\n gasPrice?: number;\n maxFeePerGas?: number;\n maxPriorityFeePerGas?: number;\n\n // Transaction expiration\n validUntil?: string; // ISO 8601 date string\n}\n\n/**\n * Implements the ExecutionStrategy for the OpenZeppelin Relayer.\n * This strategy sends the transaction to the relayer service, which then handles\n * gas payment, signing, and broadcasting. It includes a polling mechanism to wait\n * for the transaction to be mined and return the final hash.\n */\nexport class RelayerExecutionStrategy implements AdapterExecutionStrategy {\n public async execute(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n _walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const relayerConfig = executionConfig as RelayerExecutionConfig;\n\n if (!runtimeApiKey) {\n throw new Error('API Key is required for Relayer execution.');\n }\n\n const { transactionId } = await this.sendTransactionViaRelayer(\n transactionData,\n relayerConfig,\n runtimeApiKey\n );\n\n onStatusChange('pendingRelayer', { transactionId });\n\n const sdkConfig = new Configuration({\n basePath: relayerConfig.serviceUrl,\n accessToken: runtimeApiKey,\n });\n\n const txHash = await this.pollForTransactionHash(\n relayerConfig.relayer.relayerId,\n transactionId,\n sdkConfig\n );\n\n return { txHash };\n }\n\n /**\n * Fetches and filters relayers for a specific EVM network from the OpenZeppelin Relayer service.\n * This function handles pagination to retrieve all available relayers.\n *\n * @param serviceUrl - The base URL of the relayer service.\n * @param accessToken - The session-based API key for authentication.\n * @param networkConfig - EVM-compatible network configuration to filter relayers by (works with any ecosystem).\n * @returns A promise that resolves to an array of compatible relayer details.\n * @throws If the API call fails or returns an unsuccessful response.\n */\n public async getEvmRelayers(\n serviceUrl: string,\n accessToken: string,\n networkConfig: EvmCompatibleNetworkConfig\n ): Promise<RelayerDetails[]> {\n logger.info(\n '[Relayer] Getting relayers with access token',\n accessToken.slice(0, 5).padEnd(accessToken.length, '*')\n );\n const sdkConfig = new Configuration({\n basePath: serviceUrl,\n accessToken,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n let allRelayers: ApiResponseRelayerResponseData[] = [];\n let currentPage = 1;\n let totalItems = 0;\n let hasMore = true;\n\n do {\n const { data } = await relayersApi.listRelayers(currentPage, 100);\n\n if (!data.success || !data.data) {\n throw new Error(`Failed to fetch relayers on page ${currentPage}.`);\n }\n\n allRelayers = [...allRelayers, ...data.data];\n totalItems = data.pagination?.total_items || 0;\n\n if (allRelayers.length >= totalItems) {\n hasMore = false;\n } else {\n currentPage++;\n }\n } while (hasMore);\n\n return allRelayers\n .filter(\n (r: ApiResponseRelayerResponseData) =>\n r.network_type === 'evm' && networkConfig.id.includes(r.network)\n )\n .map((r: ApiResponseRelayerResponseData) => ({\n relayerId: r.id,\n name: r.name,\n address: r.address || '',\n network: r.network,\n paused: r.paused || false,\n }));\n }\n\n /**\n * Fetches comprehensive information about a specific relayer including balance and status.\n * This function combines multiple SDK API calls to provide rich relayer details.\n *\n * @param serviceUrl - The base URL of the relayer service.\n * @param accessToken - The session-based API key for authentication.\n * @param relayerId - The unique identifier of the relayer.\n * @param networkConfig - EVM-compatible network configuration to get the native currency symbol (works with any ecosystem).\n * @returns A promise that resolves to enhanced relayer details including balance and status.\n * @throws If any API call fails or returns an unsuccessful response.\n */\n public async getEvmRelayer(\n serviceUrl: string,\n accessToken: string,\n relayerId: string,\n networkConfig: EvmCompatibleNetworkConfig\n ): Promise<RelayerDetailsRich> {\n logger.info('[Relayer] Getting detailed relayer info', relayerId);\n\n const sdkConfig = new Configuration({\n basePath: serviceUrl,\n accessToken,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n try {\n // Fetch basic relayer details, balance, and status in parallel\n const [relayerResponse, balanceResponse, statusResponse] = await Promise.all([\n relayersApi.getRelayer(relayerId),\n relayersApi.getRelayerBalance(relayerId).catch((err) => {\n logger.warn('[Relayer] Failed to fetch balance', err);\n return null;\n }),\n relayersApi.getRelayerStatus(relayerId).catch((err) => {\n logger.warn('[Relayer] Failed to fetch status', err);\n return null;\n }),\n ]);\n\n if (!relayerResponse.data.success || !relayerResponse.data.data) {\n throw new Error(`Failed to fetch relayer details for ID: ${relayerId}`);\n }\n\n const relayerData = relayerResponse.data.data;\n\n // Build enhanced relayer details object\n const enhancedDetails: RelayerDetailsRich = {\n relayerId: relayerData.id,\n name: relayerData.name,\n address: relayerData.address || '',\n network: relayerData.network,\n paused: relayerData.paused || false,\n systemDisabled: relayerData.system_disabled || false,\n };\n\n // Add balance if available\n if (balanceResponse?.data?.success && balanceResponse.data.data?.balance) {\n try {\n // Format balance from wei to native currency\n const balanceInWei = BigInt(balanceResponse.data.data.balance);\n const balanceInEth = formatEther(balanceInWei);\n const currencySymbol = networkConfig.nativeCurrency.symbol;\n enhancedDetails.balance = `${balanceInEth} ${currencySymbol}`;\n } catch (error) {\n logger.warn('[Relayer] Failed to format balance, using raw value', String(error));\n enhancedDetails.balance = String(balanceResponse.data.data.balance);\n }\n }\n\n // Add status details if available\n if (statusResponse?.data?.success && statusResponse.data.data) {\n const statusData = statusResponse.data.data;\n if (statusData.network_type === 'evm') {\n if (statusData.nonce !== undefined && statusData.nonce !== null) {\n enhancedDetails.nonce = String(statusData.nonce);\n }\n if (statusData.pending_transactions_count !== undefined) {\n enhancedDetails.pendingTransactionsCount = statusData.pending_transactions_count;\n }\n if (statusData.last_confirmed_transaction_timestamp) {\n enhancedDetails.lastConfirmedTransactionTimestamp =\n statusData.last_confirmed_transaction_timestamp;\n }\n }\n }\n\n logger.info('[Relayer] Retrieved enhanced relayer details', JSON.stringify(enhancedDetails));\n return enhancedDetails;\n } catch (error) {\n logger.error(\n '[Relayer] Failed to get relayer details',\n error instanceof Error ? error.message : String(error)\n );\n throw error;\n }\n }\n\n /**\n * Submits a transaction to the relayer service for asynchronous processing.\n * @param transactionData The contract write parameters.\n * @param executionConfig The relayer-specific execution configuration.\n * @param runtimeApiKey The user's session-only API key.\n * @returns A promise that resolves to an object containing the transaction ID assigned by the relayer.\n */\n private async sendTransactionViaRelayer(\n transactionData: WriteContractParameters,\n executionConfig: RelayerExecutionConfig,\n runtimeApiKey: string\n ): Promise<{ transactionId: string }> {\n const data = encodeFunctionData({\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n });\n\n // Type-safe extraction of EVM-specific options\n const evmOptions = executionConfig.transactionOptions as\n | EvmRelayerTransactionOptions\n | undefined;\n\n // Compute value for relayer request. The SDK type is number, but JS Number\n // cannot safely represent large wei amounts. Prefer passing zero when undefined\n // or warn when truncation would occur.\n const valueBigint = transactionData.value ?? 0n;\n let valueNumber: number = 0;\n const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\n if (valueBigint > MAX_SAFE) {\n logger.warn(\n '[Relayer] Value exceeds JS safe integer. Truncating for request.',\n valueBigint.toString()\n );\n valueNumber = Number(MAX_SAFE);\n } else {\n valueNumber = Number(valueBigint);\n }\n\n const relayerTxRequest: EvmTransactionRequest = {\n to: transactionData.address,\n data,\n value: valueNumber,\n // If no explicit gas limit is provided, keep a conservative default but warn.\n gas_limit: (() => {\n if (typeof evmOptions?.gasLimit === 'number') return evmOptions.gasLimit;\n logger.warn(\n '[Relayer]',\n 'No gasLimit provided; using default 210000. Consider setting explicitly.'\n );\n return 210000;\n })(),\n // Note: The OpenZeppelin Relayer API requires exactly one gas pricing strategy to be provided.\n // Valid options are: speed, gas_price, or both max_fee_per_gas + max_priority_fee_per_gas.\n // If none are provided, the API will return a 400 Bad Request error.\n // Only include speed if explicitly set in options\n ...(evmOptions?.speed !== undefined && { speed: evmOptions.speed }),\n // Include optional parameters only if provided\n ...(evmOptions?.gasPrice !== undefined && { gas_price: evmOptions.gasPrice }),\n ...(evmOptions?.maxFeePerGas !== undefined && { max_fee_per_gas: evmOptions.maxFeePerGas }),\n ...(evmOptions?.maxPriorityFeePerGas !== undefined && {\n max_priority_fee_per_gas: evmOptions.maxPriorityFeePerGas,\n }),\n ...(evmOptions?.validUntil !== undefined && { valid_until: evmOptions.validUntil }),\n };\n\n const sdkConfig = new Configuration({\n basePath: executionConfig.serviceUrl,\n accessToken: runtimeApiKey,\n });\n const relayersApi = new RelayersApi(sdkConfig);\n\n const result = await relayersApi.sendTransaction(\n executionConfig.relayer.relayerId,\n relayerTxRequest\n );\n\n if (!result.data.success || !result.data.data?.id) {\n throw new Error(`Relayer API failed to return a transaction ID. Error: ${result.data.error}`);\n }\n\n return { transactionId: result.data.data.id };\n }\n\n /**\n * Polls the relayer for a transaction's status until it is mined and has a hash, or fails.\n * @param relayerId The ID of the relayer processing the transaction.\n * @param transactionId The ID of the transaction to poll.\n * @param sdkConfig The SDK configuration containing the necessary authentication.\n * @returns A promise that resolves to the final transaction hash.\n * @throws If the transaction fails or polling times out.\n */\n private async pollForTransactionHash(\n relayerId: string,\n transactionId: string,\n sdkConfig: Configuration\n ): Promise<string> {\n const relayersApi = new RelayersApi(sdkConfig);\n const POLLING_INTERVAL = 2000;\n const POLLING_TIMEOUT = 300000; // 5 minutes in milliseconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < POLLING_TIMEOUT) {\n const { data } = await relayersApi.getTransactionById(relayerId, transactionId);\n\n if (!data.success || !data.data) {\n throw new Error(`Failed to get transaction status for ID: ${transactionId}`);\n }\n\n const txResponse = data.data as EvmTransactionResponse;\n\n if (txResponse.status === 'mined' || txResponse.status === 'confirmed') {\n if (!txResponse.hash) {\n throw new Error(\n `Transaction is confirmed but no hash was returned for ID: ${transactionId}`\n );\n }\n return txResponse.hash;\n }\n\n if (\n txResponse.status === 'failed' ||\n txResponse.status === 'canceled' ||\n txResponse.status === 'expired'\n ) {\n throw new Error(\n `Transaction ${txResponse.status}: ${txResponse.status_reason || 'No reason provided.'}`\n );\n }\n\n // Continue polling for 'pending' or 'sent' statuses\n await new Promise((resolve) => setTimeout(resolve, POLLING_INTERVAL));\n }\n\n throw new Error(`Polling for transaction hash timed out for ID: ${transactionId}`);\n }\n}\n","import type { AbiFunction, AbiParameter, AbiStateMutability } from 'viem';\n\nimport type { ContractFunction, ContractSchema, FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { AbiItem } from '../types/abi';\nimport { formatInputName, formatMethodName } from '../utils';\n\n/**\n * Transforms a standard ABI array (typically from an EVM-compatible chain)\n * into the project's internal `ContractSchema` format.\n * This schema is used by the builder app and renderer to represent contract interactions\n * in a chain-agnostic way (though this specific transformer is for EVM ABIs).\n *\n * @param abi The raw ABI array (e.g., parsed from a JSON ABI file or fetched from Etherscan).\n * It's expected to be an array of `AbiItem` (from viem types or a compatible structure).\n * @param contractName A name to assign to the contract within the schema. This might be derived\n * from a file name, user input, or a default if not otherwise available.\n * @param address Optional address of the deployed contract. If provided, it's included in the schema.\n * @returns A `ContractSchema` object representing the contract's interface.\n */\nexport function transformAbiToSchema(\n abi: readonly AbiItem[],\n contractName: string,\n address?: string\n): ContractSchema {\n logger.info('transformAbiToSchema', `Transforming ABI to ContractSchema for: ${contractName}`);\n const functions: ContractFunction[] = [];\n\n for (const item of abi) {\n // We are only interested in 'function' type items from the ABI\n // to map them to our ContractFunction interface.\n if (item.type === 'function') {\n // After confirming item.type is 'function', we can safely cast it to AbiFunction\n // to access function-specific properties like `stateMutability`, `inputs`, `outputs`.\n const abiFunctionItem = item as AbiFunction;\n functions.push({\n // Generate a unique ID for the function within the schema.\n // This often combines name and input types to handle overloads.\n id: `${abiFunctionItem.name}_${abiFunctionItem.inputs?.map((i) => i.type).join('_') || ''}`,\n name: abiFunctionItem.name || '', // Fallback for unnamed functions (though rare).\n displayName: formatMethodName(abiFunctionItem.name || ''), // Create a more readable name for UI.\n // Recursively map ABI inputs and outputs to our FunctionParameter structure.\n // This ensures that any non-standard properties (like 'internalType') are stripped.\n inputs: mapAbiParametersToSchemaParameters(abiFunctionItem.inputs),\n outputs: mapAbiParametersToSchemaParameters(abiFunctionItem.outputs),\n type: 'function', // Explicitly set, as we filtered for this type.\n stateMutability: abiFunctionItem.stateMutability, // Preserve EVM-specific state mutability.\n // Determine if the function modifies blockchain state based on its `stateMutability`.\n // This is a crucial piece of information for the UI (e.g., to differentiate read vs. write calls).\n modifiesState:\n !abiFunctionItem.stateMutability || // If undefined, assume it modifies state (safer default)\n !['view', 'pure'].includes(abiFunctionItem.stateMutability),\n });\n }\n }\n\n const contractSchema: ContractSchema = {\n ecosystem: 'evm', // This transformer is specific to EVM.\n name: contractName,\n address,\n functions,\n };\n logger.info(\n 'transformAbiToSchema',\n `Transformation complete. Found ${contractSchema.functions.length} functions.`\n );\n return contractSchema;\n}\n\n/**\n * Recursively maps an array of ABI parameters (from viem's `AbiParameter` type or compatible)\n * to an array of `FunctionParameter` objects, which is our internal representation.\n * This function is crucial for stripping any properties not defined in `FunctionParameter`\n * (e.g., `internalType` from the raw ABI) and for handling nested components (structs/tuples).\n *\n * @param abiParams An array of ABI parameter objects. Can be undefined (e.g., if a function has no inputs/outputs).\n * @returns An array of `FunctionParameter` objects, or an empty array if `abiParams` is undefined.\n */\nfunction mapAbiParametersToSchemaParameters(\n abiParams: readonly AbiParameter[] | undefined\n): FunctionParameter[] {\n if (!abiParams) {\n return [];\n }\n return abiParams.map((param): FunctionParameter => {\n // Create the base FunctionParameter object, picking only defined properties.\n const schemaParam: FunctionParameter = {\n name: param.name || '', // Ensure name is a string, fallback if undefined in ABI.\n type: param.type, // The raw type string from the ABI (e.g., 'uint256', 'address', 'tuple').\n displayName: formatInputName(param.name || '', param.type), // Generate a user-friendly name.\n // `description` is not a standard part of an ABI parameter, so it's not mapped here.\n // It can be added later by the user in the builder app UI.\n };\n // Check for nested components (structs/tuples).\n // `param.type.startsWith('tuple')` checks if it's a tuple or tuple array.\n // `'components' in param` is a type guard for discriminated unions.\n // `param.components && param.components.length > 0` ensures components exist and are not empty.\n if (\n param.type.startsWith('tuple') &&\n 'components' in param && // Type guard for discriminated union (AbiParameter)\n param.components &&\n param.components.length > 0\n ) {\n // If components exist, recursively call this function to map them.\n // This ensures that nested structures also conform to `FunctionParameter` and strip extra fields.\n // Cast `param.components` because TypeScript might not fully infer its type after the `in` check within the map.\n schemaParam.components = mapAbiParametersToSchemaParameters(\n param.components as readonly AbiParameter[]\n );\n }\n return schemaParam;\n });\n}\n\n/**\n * Helper function to convert one of our internal `FunctionParameter` objects\n * back into a format compatible with viem's `AbiParameter` type.\n * This is primarily used by `createAbiFunctionItem` when constructing an `AbiFunction`\n * for interactions with viem or other ABI-consuming libraries.\n * It ensures that only properties expected by `AbiParameter` are included.\n *\n * @param param The internal `FunctionParameter` object.\n * @returns An `AbiParameter` object compatible with viem.\n */\nfunction mapSchemaParameterToAbiParameter(param: FunctionParameter): AbiParameter {\n // Handle tuple types specifically, as `AbiParameter` for tuples requires a `components` array.\n if (param.type.startsWith('tuple') && param.components && param.components.length > 0) {\n return {\n name: param.name || undefined, // ABI parameter names can be undefined (e.g., for return values).\n type: param.type as `tuple${string}`, // Cast to satisfy viem's specific tuple type string.\n // Recursively map nested components back to AbiParameter format.\n components: param.components.map(mapSchemaParameterToAbiParameter),\n };\n }\n // For non-tuple types, return a simpler AbiParameter structure.\n return {\n name: param.name || undefined,\n type: param.type,\n // `internalType` is not part of our `FunctionParameter` model, so it's not added back here.\n // Other ABI-specific fields like `indexed` (for events) are also not relevant here as\n // this function is focused on function parameters for `AbiFunction`.\n };\n}\n\n/**\n * Private helper to convert internal `ContractFunction` details (our model)\n * back into a viem `AbiFunction` object.\n * This is useful when interacting with libraries like viem that expect a standard ABI format.\n * Ensures that the generated AbiFunction conforms to viem's type definitions.\n *\n * @param functionDetails The `ContractFunction` object from our internal schema.\n * @returns An `AbiFunction` object.\n */\nexport function createAbiFunctionItem(functionDetails: ContractFunction): AbiFunction {\n return {\n name: functionDetails.name,\n type: 'function',\n inputs: functionDetails.inputs.map(mapSchemaParameterToAbiParameter),\n outputs: functionDetails.outputs?.map(mapSchemaParameterToAbiParameter) || [],\n stateMutability: (functionDetails.stateMutability ?? 'view') as AbiStateMutability,\n };\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveExplorerConfig } from '../configuration/explorer';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { loadAbiFromEtherscanV2, shouldUseV2Api } from './etherscan-v2';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Result type for Etherscan ABI loading that includes the original ABI string\n */\nexport interface EtherscanAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\n/**\n * IMPORTANT: Etherscan V1 API Deprecation Notice\n *\n * Etherscan has announced the deprecation of their V1 API endpoints in favor of the new V2 unified API.\n * The V2 API provides a single endpoint that works across all EVM chains, making it more scalable and\n * easier to maintain.\n *\n * Key differences:\n * - V1: Each chain has its own API endpoint (e.g., api.etherscan.io, api.bscscan.com, etc.)\n * - V2: Single unified endpoint (api.etherscan.io/v2/api) with chainId parameter\n *\n * Migration strategy:\n * - Networks with `supportsEtherscanV2: true` will automatically use V2 API\n * - Legacy networks without V2 support will continue using V1 until they're updated\n * - New networks should always be configured with V2 support\n *\n * The V1 API functions are maintained for backward compatibility but should be considered\n * deprecated and will be removed in a future release.\n */\n\n/**\n * Fetches and parses an ABI from Etherscan-compatible explorers using a contract address and network config.\n * Automatically selects V1 or V2 API based on network support and user configuration.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscan(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n if (shouldUseV2Api(networkConfig)) {\n logger.info('loadAbiFromEtherscan', 'Using V2 API for fetching ABI');\n return loadAbiFromEtherscanV2(address, networkConfig);\n }\n\n // Use V1 API (legacy)\n logger.info('loadAbiFromEtherscan', 'Using V1 API for fetching ABI');\n return loadAbiFromEtherscanV1(address, networkConfig);\n}\n\n/**\n * Fetches and parses an ABI from Etherscan V1 API using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscanV1(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n const explorerConfig = resolveExplorerConfig(networkConfig);\n\n if (!explorerConfig.apiUrl) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `API URL is missing for ${networkConfig.name} explorer.`\n );\n throw new Error(`Explorer API URL for ${networkConfig.name} is not configured.`);\n }\n\n const url = new URL(explorerConfig.apiUrl);\n url.searchParams.append('module', 'contract');\n url.searchParams.append('action', 'getabi');\n url.searchParams.append('address', address);\n\n // Only append API key if provided\n if (explorerConfig.apiKey) {\n url.searchParams.append('apikey', explorerConfig.apiKey);\n }\n\n let response: Response;\n try {\n logger.info(\n 'loadAbiFromEtherscanV1',\n `Fetching ABI from ${explorerConfig.apiUrl} for address: ${address}`\n );\n response = await fetch(url);\n } catch (networkError) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Network error fetching ABI from Explorer API: ${networkError}`\n );\n throw new Error(`Network error fetching ABI: ${(networkError as Error).message}`);\n }\n\n if (!response.ok) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Explorer API request failed with status: ${response.status}`\n );\n throw new Error(`Explorer API request failed: ${response.status} ${response.statusText}`);\n }\n\n let apiResult: { status: string; message: string; result: string };\n try {\n apiResult = await response.json();\n } catch (jsonError) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Failed to parse Explorer API response as JSON: ${jsonError}`\n );\n throw new Error('Invalid JSON response received from Explorer API.');\n }\n\n if (apiResult.status !== '1') {\n logger.warn(\n 'loadAbiFromEtherscanV1',\n `Explorer API error: Status ${apiResult.status}, Message: ${apiResult.message}, Result: ${apiResult.result}`\n );\n if (apiResult.result?.includes('Contract source code not verified')) {\n throw new Error(\n `Contract not verified on ${networkConfig.name} explorer (address: ${address}). ABI not available. You can provide the contract's ABI manually.`\n );\n }\n throw new Error(`Explorer API Error: ${apiResult.result || apiResult.message}`);\n }\n\n // Store the original raw ABI string before parsing\n const originalAbiString = apiResult.result;\n\n let abi: AbiItem[];\n try {\n abi = JSON.parse(originalAbiString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed ABI from Explorer API is not an array.');\n }\n } catch (error) {\n logger.error(\n 'loadAbiFromEtherscanV1',\n `Failed to parse ABI JSON string from Explorer API result: ${error}`\n );\n throw new Error(`Invalid ABI JSON received from Explorer API: ${(error as Error).message}`);\n }\n\n logger.info(\n 'loadAbiFromEtherscanV1',\n `Successfully parsed ABI for ${networkConfig.name} with ${abi.length} items.`\n );\n // TODO: Fetch contract name?\n const contractName = `Contract_${address.substring(0, 6)}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return {\n schema,\n originalAbi: originalAbiString,\n };\n}\n","import { trimEnd } from 'lodash';\n\nimport { UserExplorerConfig } from '@openzeppelin/ui-types';\nimport { appConfigService, logger, userNetworkServiceConfigService } from '@openzeppelin/ui-utils';\n\nimport { shouldUseV2Api, testEtherscanV2Connection } from '../abi/etherscan-v2';\nimport { EvmCompatibleNetworkConfig } from '../types/network';\nimport { isValidEvmAddress } from '../utils';\n\n/**\n * Resolves the explorer API key from app configuration (without user overrides).\n * This is used by getDefaultServiceConfig to provide defaults for health checks.\n *\n * Priority order:\n * 1. For V2 API networks: Global Etherscan V2 API key\n * 2. Network-specific global service config API key\n * 3. Fallback to explorer API key by identifier\n *\n * @param networkConfig - EVM-compatible network configuration\n * @returns The resolved API key, or undefined if not configured\n */\nexport function resolveExplorerApiKeyFromAppConfig(\n networkConfig: EvmCompatibleNetworkConfig\n): string | undefined {\n const isV2 =\n networkConfig.supportsEtherscanV2 &&\n networkConfig.primaryExplorerApiIdentifier === 'etherscan-v2';\n\n // For V2-compatible networks, check global Etherscan V2 API key first\n if (isV2) {\n const globalV2ApiKey = appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as\n | string\n | undefined;\n if (globalV2ApiKey) {\n return globalV2ApiKey;\n }\n }\n\n // For non-V2 networks or when no V2 key is available, check network-specific configs\n if (networkConfig.primaryExplorerApiIdentifier) {\n const globalServiceConfig = appConfigService.getGlobalServiceConfig(\n networkConfig.primaryExplorerApiIdentifier\n );\n const apiKey =\n (globalServiceConfig?.apiKey as string | undefined) ??\n appConfigService.getExplorerApiKey(networkConfig.primaryExplorerApiIdentifier);\n if (apiKey) {\n return apiKey;\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolves the explorer configuration for a given EVM network.\n * Priority order:\n * 1. User-configured explorer (from UserExplorerConfigService)\n * 2. For V2 API networks: Global Etherscan V2 API key (from AppConfigService global service configs)\n * 3. App-configured explorer API key (from AppConfigService network service configs)\n * 4. Default network explorer (from NetworkConfig)\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem).\n * @returns The resolved explorer configuration.\n */\nexport function resolveExplorerConfig(\n networkConfig: EvmCompatibleNetworkConfig\n): UserExplorerConfig {\n // Precompute app-level keys and defaults for merging\n const isV2 =\n networkConfig.supportsEtherscanV2 &&\n networkConfig.primaryExplorerApiIdentifier === 'etherscan-v2';\n const globalV2ApiKey = isV2\n ? (appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as string | undefined)\n : undefined;\n\n // For non-V2 networks, check globalServiceConfigs first (e.g., routescan), then fall back to explorer API keys\n let appApiKey: string | undefined;\n if (networkConfig.primaryExplorerApiIdentifier) {\n // First check globalServiceConfigs (supports routescan, blockscout, etc.)\n const globalServiceConfig = appConfigService.getGlobalServiceConfig(\n networkConfig.primaryExplorerApiIdentifier\n );\n appApiKey =\n (globalServiceConfig?.apiKey as string | undefined) ??\n appConfigService.getExplorerApiKey(networkConfig.primaryExplorerApiIdentifier);\n }\n\n // 1. Check for user-configured explorer via new generic service\n const rawCfg = userNetworkServiceConfigService.get(networkConfig.id, 'explorer');\n if (rawCfg && typeof rawCfg === 'object') {\n const userCfg = rawCfg as Record<string, unknown>;\n logger.info('ExplorerConfig', `Using user-configured explorer for ${networkConfig.name}`);\n return {\n explorerUrl: (userCfg.explorerUrl as string | undefined) ?? networkConfig.explorerUrl,\n apiUrl: (userCfg.apiUrl as string | undefined) ?? networkConfig.apiUrl,\n apiKey: (userCfg.apiKey as string | undefined) ?? globalV2ApiKey ?? appApiKey,\n name: `${networkConfig.name} Explorer`,\n isCustom: true,\n };\n }\n\n // 2. For V2 API networks using 'etherscan-v2' identifier, check for global Etherscan V2 API key\n if (isV2 && globalV2ApiKey) {\n logger.info('ExplorerConfig', `Using global Etherscan V2 API key for ${networkConfig.name}`);\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n apiKey: globalV2ApiKey,\n name: `${networkConfig.name} Explorer (V2 API)`,\n isCustom: false,\n };\n }\n\n // 3. Check for app-configured API key (V1 style or other identifiers)\n if (appApiKey) {\n logger.info('ExplorerConfig', `Using app-configured API key for ${networkConfig.name}`);\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n apiKey: appApiKey,\n name: `${networkConfig.name} Explorer`,\n isCustom: false,\n };\n }\n\n // 4. Use default network explorer (no API key)\n logger.info(\n 'ExplorerConfig',\n `Using default explorer for ${networkConfig.name} (no API key configured)`\n );\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n name: `${networkConfig.name} Explorer`,\n isCustom: false,\n };\n}\n\n/**\n * Gets a blockchain explorer URL for an EVM address.\n * Uses the resolved explorer configuration.\n *\n * @param address - Contract or wallet address\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function getEvmExplorerAddressUrl(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): string | null {\n if (!isValidEvmAddress(address)) {\n return null;\n }\n\n const explorerConfig = resolveExplorerConfig(networkConfig);\n if (!explorerConfig.explorerUrl) {\n return null;\n }\n\n // Construct the URL using the explorerUrl from the config\n const baseUrl = trimEnd(explorerConfig.explorerUrl, '/');\n return `${baseUrl}/address/${address}`;\n}\n\n/**\n * Gets a blockchain explorer URL for an EVM transaction.\n * Uses the resolved explorer configuration.\n *\n * @param txHash - Transaction hash\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function getEvmExplorerTxUrl(\n txHash: string,\n networkConfig: EvmCompatibleNetworkConfig\n): string | null {\n if (!txHash) {\n return null;\n }\n\n const explorerConfig = resolveExplorerConfig(networkConfig);\n if (!explorerConfig.explorerUrl) {\n return null;\n }\n\n // Construct the URL using the explorerUrl from the config\n const baseUrl = trimEnd(explorerConfig.explorerUrl, '/');\n return `${baseUrl}/tx/${txHash}`;\n}\n\n/**\n * Validates an EVM explorer configuration.\n * Checks URL formats and API key format.\n */\nexport function validateEvmExplorerConfig(explorerConfig: UserExplorerConfig): boolean {\n // Validate URLs if provided\n if (explorerConfig.explorerUrl) {\n try {\n new URL(explorerConfig.explorerUrl);\n } catch {\n return false;\n }\n }\n\n if (explorerConfig.apiUrl) {\n try {\n new URL(explorerConfig.apiUrl);\n } catch {\n return false;\n }\n }\n\n // Basic API key validation (not empty)\n if (explorerConfig.apiKey !== undefined && explorerConfig.apiKey.trim().length === 0) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Tests the connection to an EVM explorer API.\n * Makes a test API call to verify the API key works.\n * Automatically uses V2 API testing for networks that support it.\n *\n * @param explorerConfig - Explorer configuration to test\n * @param networkConfig - Optional EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function testEvmExplorerConnection(\n explorerConfig: UserExplorerConfig,\n networkConfig?: EvmCompatibleNetworkConfig\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n // Check if this network supports V2 API and should use it\n if (networkConfig && shouldUseV2Api(networkConfig)) {\n // Use the V2-specific connection test\n logger.info(\n 'testEvmExplorerConnection',\n `Using V2 API connection test for ${networkConfig.name}`\n );\n return testEtherscanV2Connection(networkConfig, explorerConfig.apiKey);\n }\n\n // V1 API testing path\n // Check if API key is required for this network\n const requiresApiKey =\n networkConfig && 'requiresExplorerApiKey' in networkConfig\n ? networkConfig.requiresExplorerApiKey !== false\n : true;\n\n if (requiresApiKey && !explorerConfig.apiKey) {\n return {\n success: false,\n error: 'API key is required for testing connection to this explorer',\n };\n }\n\n // Use provided API URL or fall back to network config if available\n let apiUrl = explorerConfig.apiUrl;\n if (!apiUrl && networkConfig?.apiUrl) {\n apiUrl = networkConfig.apiUrl;\n }\n\n if (!apiUrl) {\n return {\n success: false,\n error:\n 'API URL is required for testing connection. Please provide an API URL or ensure the network has a default API URL configured.',\n };\n }\n\n const startTime = Date.now();\n\n try {\n // Test with a simple API call - get the latest block number\n const url = new URL(apiUrl);\n url.searchParams.append('module', 'proxy');\n url.searchParams.append('action', 'eth_blockNumber');\n if (explorerConfig.apiKey) {\n url.searchParams.append('apikey', explorerConfig.apiKey);\n }\n\n const response = await fetch(url.toString());\n const latency = Date.now() - startTime;\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n latency,\n };\n }\n\n const data = await response.json();\n\n // Check for API errors in the response\n if (data.status === '0' && data.message) {\n return {\n success: false,\n error: data.message,\n latency,\n };\n }\n\n // Success if we got a valid response\n return {\n success: true,\n latency,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection test failed',\n latency: Date.now() - startTime,\n };\n }\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveExplorerConfig } from '../configuration/explorer';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Result type for Etherscan ABI loading that includes the original ABI string\n */\nexport interface EtherscanAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\n// Etherscan V2 unified API base URL\nconst ETHERSCAN_V2_BASE_URL = 'https://api.etherscan.io/v2/api';\n\n/**\n * Builds a V2 API URL for Etherscan-compatible explorers\n */\nfunction buildV2ApiUrl(\n chainId: number,\n module: string,\n action: string,\n params: Record<string, string>,\n apiKey?: string // Some explorers don't require an API key (routescan.io)\n): string {\n const url = new URL(ETHERSCAN_V2_BASE_URL);\n url.searchParams.append('chainid', chainId.toString());\n url.searchParams.append('module', module);\n url.searchParams.append('action', action);\n\n Object.entries(params).forEach(([key, value]) => {\n url.searchParams.append(key, value);\n });\n\n if (apiKey) {\n url.searchParams.append('apikey', apiKey);\n }\n\n return url.toString();\n}\n\n/**\n * Checks if the network supports V2 API\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport function shouldUseV2Api(networkConfig: EvmCompatibleNetworkConfig): boolean {\n if (!networkConfig.supportsEtherscanV2) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Fetches and parses an ABI from Etherscan V2 API using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function loadAbiFromEtherscanV2(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EtherscanAbiResult> {\n const explorerConfig = resolveExplorerConfig(networkConfig);\n\n const url = buildV2ApiUrl(\n networkConfig.chainId,\n 'contract',\n 'getabi',\n { address },\n explorerConfig.apiKey\n );\n\n let response: Response;\n try {\n logger.info(\n 'loadAbiFromEtherscanV2',\n `Fetching ABI from Etherscan V2 API for address: ${address} on chain ${networkConfig.chainId}`\n );\n response = await fetch(url);\n } catch (networkError) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Network error fetching ABI from Explorer V2 API: ${networkError}`\n );\n throw new Error(`Network error fetching ABI: ${(networkError as Error).message}`);\n }\n\n if (!response.ok) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Explorer V2 API request failed with status: ${response.status}`\n );\n throw new Error(`Explorer V2 API request failed: ${response.status} ${response.statusText}`);\n }\n\n let apiResult: { status: string; message: string; result: string };\n try {\n apiResult = await response.json();\n } catch (jsonError) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Failed to parse Explorer V2 API response as JSON: ${jsonError}`\n );\n throw new Error('Invalid JSON response received from Explorer V2 API.');\n }\n\n if (apiResult.status !== '1') {\n logger.warn(\n 'loadAbiFromEtherscanV2',\n `Explorer V2 API error: Status ${apiResult.status}, Message: ${apiResult.message}, Result: ${apiResult.result}`\n );\n\n // Handle specific V2 API error messages\n if (apiResult.message?.includes('NOTOK')) {\n if (apiResult.result?.includes('Invalid API Key')) {\n throw new Error(\n `Invalid API key for Etherscan V2. Please check your API key configuration.`\n );\n }\n if (apiResult.result?.includes('Contract source code not verified')) {\n throw new Error(\n `Contract not verified on ${networkConfig.name} explorer (address: ${address}). ABI not available. You can provide the contract's ABI manually.`\n );\n }\n if (apiResult.result?.includes('Invalid chain')) {\n throw new Error(\n `Chain ID ${networkConfig.chainId} is not supported by Etherscan V2 API. Please check if this chain is available.`\n );\n }\n }\n\n throw new Error(`Explorer V2 API Error: ${apiResult.result || apiResult.message}`);\n }\n\n // Store the original raw ABI string before parsing\n const originalAbiString = apiResult.result;\n\n let abi: AbiItem[];\n try {\n abi = JSON.parse(originalAbiString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed ABI from Explorer V2 API is not an array.');\n }\n } catch (error) {\n logger.error(\n 'loadAbiFromEtherscanV2',\n `Failed to parse ABI JSON string from Explorer V2 API result: ${error}`\n );\n throw new Error(`Invalid ABI JSON received from Explorer V2 API: ${(error as Error).message}`);\n }\n\n logger.info(\n 'loadAbiFromEtherscanV2',\n `Successfully parsed ABI for ${networkConfig.name} with ${abi.length} items using V2 API.`\n );\n\n // TODO: Fetch contract name?\n const contractName = `Contract_${address.substring(0, 6)}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return {\n schema,\n originalAbi: originalAbiString,\n };\n}\n\n/**\n * Test connection to Etherscan V2 API\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param apiKey - Optional API key for authentication\n */\nexport async function testEtherscanV2Connection(\n networkConfig: EvmCompatibleNetworkConfig,\n apiKey?: string\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n const startTime = Date.now();\n\n const requiresApiKey = networkConfig.requiresExplorerApiKey ?? true;\n\n if (requiresApiKey && !apiKey) {\n return {\n success: false,\n error: 'API key is required for testing connection to this explorer',\n };\n }\n\n try {\n // Test with a simple API call - get the latest block number\n const url = buildV2ApiUrl(networkConfig.chainId, 'proxy', 'eth_blockNumber', {}, apiKey);\n\n const response = await fetch(url);\n const latency = Date.now() - startTime;\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n latency,\n };\n }\n\n const data = await response.json();\n\n // Check for API errors in the response\n if (data.status === '0' && data.message) {\n // Handle specific V2 API error messages\n if (data.result?.includes('Invalid API Key')) {\n return {\n success: false,\n error: 'Invalid API key. Please check your Etherscan API key.',\n latency,\n };\n }\n if (data.result?.includes('Invalid chain')) {\n return {\n success: false,\n error: `Chain ID ${networkConfig.chainId} is not supported by Etherscan V2 API.`,\n latency,\n };\n }\n\n return {\n success: false,\n error: data.result || data.message,\n latency,\n };\n }\n\n // Success if we got a valid response\n return {\n success: true,\n latency,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection test failed',\n latency: Date.now() - startTime,\n };\n }\n}\n","import type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { AbiItem } from '../types/abi';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { transformAbiToSchema } from './transformer';\n\nexport interface SourcifyAbiResult {\n schema: ContractSchema;\n originalAbi: string;\n}\n\nconst SOURCIFY_APP_BASE = 'https://repo.sourcify.dev';\n\nexport function getSourcifyContractAppUrl(chainId: number, address: string): string {\n return `${SOURCIFY_APP_BASE}/${chainId}/${address}`;\n}\n\nconst SOURCIFY_API_BASE = 'https://sourcify.dev/server/v2';\n\ninterface SourcifyApiContractResponse {\n abi?: AbiItem[];\n metadata?: {\n contractName?: string;\n output?: {\n abi?: AbiItem[];\n };\n };\n}\n\nfunction buildSourcifyApiUrl(chainId: number, address: string): string {\n const normalizedAddress = address.toLowerCase();\n const url = new URL(\n `${SOURCIFY_API_BASE}/contract/${chainId}/${normalizedAddress}?fields=abi,metadata`\n );\n return url.toString();\n}\n\n/**\n * Fetches and parses an ABI from Sourcify using a contract address and network config.\n *\n * @param address - Contract address to fetch ABI for\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param timeoutMs - Timeout in milliseconds (default: 4000ms)\n */\nexport async function loadAbiFromSourcify(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig,\n timeoutMs = 4000\n): Promise<SourcifyAbiResult> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const url = buildSourcifyApiUrl(networkConfig.chainId, address);\n logger.info('loadAbiFromSourcify', `Fetching contract from ${url}`);\n\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) {\n throw new Error(`Sourcify request failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as SourcifyApiContractResponse;\n const abi = payload.abi ?? payload.metadata?.output?.abi;\n\n if (!abi || !Array.isArray(abi)) {\n throw new Error('Sourcify metadata did not include a valid ABI array');\n }\n\n const normalizedAddress = address.toLowerCase();\n const contractName =\n payload.metadata?.contractName ||\n `Contract_${normalizedAddress.substring(0, 6).toUpperCase()}`;\n const schema = transformAbiToSchema(abi, contractName, address);\n\n return { schema, originalAbi: JSON.stringify(abi) };\n } catch (error) {\n logger.warn('loadAbiFromSourcify', `Failed to fetch ABI from Sourcify: ${String(error)}`);\n throw error as Error;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import { isAddress } from 'viem';\n\nimport type { ContractDefinitionMetadata, ContractSchema, ProxyInfo } from '@openzeppelin/ui-types';\nimport {\n appConfigService,\n logger,\n simpleHash,\n userNetworkServiceConfigService,\n withTimeout,\n} from '@openzeppelin/ui-utils';\n\nimport { getEvmExplorerAddressUrl } from '../configuration/explorer';\nimport { detectProxyFromAbi, getAdminAddress, getImplementationAddress } from '../proxy/detection';\nimport type { AbiItem } from '../types/abi';\nimport type { EvmContractArtifacts } from '../types/artifacts';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport {\n EvmProviderKeys,\n isEvmProviderKey,\n type EvmContractDefinitionProviderKey,\n} from '../types/providers';\nimport { loadAbiFromEtherscan } from './etherscan';\nimport { getSourcifyContractAppUrl, loadAbiFromSourcify } from './sourcify';\nimport { transformAbiToSchema } from './transformer';\n\n/**\n * Loads and parses an ABI directly from a JSON string.\n */\nasync function loadAbiFromJson(abiJsonString: string): Promise<ContractSchema> {\n let abi: AbiItem[];\n try {\n abi = JSON.parse(abiJsonString);\n if (!Array.isArray(abi)) {\n throw new Error('Parsed JSON is not an array.');\n }\n } catch (error) {\n logger.error('loadAbiFromJson', 'Failed to parse source string as JSON ABI:', error);\n throw new Error(`Invalid JSON ABI provided: ${(error as Error).message}`);\n }\n\n logger.info('loadAbiFromJson', `Successfully parsed JSON ABI with ${abi.length} items.`);\n const contractName = 'ContractFromABI'; // Default name for direct ABI\n return transformAbiToSchema(abi, contractName, undefined);\n}\n\n/**\n * Enhanced result type for ABI loading with metadata and proxy information\n */\nexport interface EvmContractLoadResult {\n schema: ContractSchema;\n source: 'fetched' | 'manual';\n contractDefinitionOriginal?: string;\n metadata?: ContractDefinitionMetadata;\n proxyInfo?: ProxyInfo;\n}\n\n/**\n * Options for contract loading behavior\n */\nexport interface ContractLoadOptions {\n /** Skip proxy detection and load the contract ABI as-is */\n skipProxyDetection?: boolean;\n /** Force treating the address as an implementation contract */\n treatAsImplementation?: boolean;\n}\n\nconst PER_PROVIDER_TIMEOUT_MS = 4000;\nconst OVERALL_BUDGET_MS = 10000;\n\n/**\n * Loads contract schema from artifacts provided by the UI, prioritizing manual ABI input.\n * Returns enhanced result with schema source information and automatic proxy detection.\n *\n * @param artifacts - Contract artifacts containing address and optional ABI\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param options - Optional loading options\n */\nexport async function loadEvmContract(\n artifacts: EvmContractArtifacts,\n networkConfig: EvmCompatibleNetworkConfig,\n options: ContractLoadOptions = {}\n): Promise<EvmContractLoadResult> {\n const { contractAddress, contractDefinition, __proxyDetectionOptions } = artifacts;\n\n // Extract proxy detection options from form data if present\n const proxyOptions = __proxyDetectionOptions as { skipProxyDetection?: boolean } | undefined;\n if (proxyOptions?.skipProxyDetection) {\n options.skipProxyDetection = true;\n }\n\n if (!contractAddress || typeof contractAddress !== 'string' || !isAddress(contractAddress)) {\n throw new Error('A valid contract address is required.');\n }\n\n // 1. Prioritize manual contract definition input if provided.\n if (\n contractDefinition &&\n typeof contractDefinition === 'string' &&\n contractDefinition.trim().length > 0\n ) {\n // Try to detect if this looks like JSON\n const trimmed = contractDefinition.trim();\n const hasJsonContent = trimmed.includes('[') && trimmed.includes(']') && trimmed.includes('{');\n\n if (hasJsonContent) {\n logger.info('loadEvmContract', 'Manual contract definition provided. Attempting to parse...');\n try {\n const schema = await loadAbiFromJson(contractDefinition);\n // Attach the address to the schema from the separate address field.\n return {\n schema: { ...schema, address: contractAddress },\n source: 'manual' as const,\n contractDefinitionOriginal: contractDefinition,\n metadata: {\n contractName: schema.name,\n fetchTimestamp: new Date(),\n verificationStatus: 'unknown', // Manual ABI - verification status unknown\n },\n // Note: No proxy detection for manual ABIs - user provides what they want\n };\n } catch (error) {\n logger.error('loadEvmContract', 'Failed to parse manually provided ABI:', error);\n // If manual ABI is provided but invalid, it's a hard error.\n throw new Error(`The provided ABI JSON is invalid: ${(error as Error).message}`);\n }\n }\n }\n\n // Extract optional forced provider (from adapter-specific field or generic 'service')\n const forcedRaw =\n (artifacts as unknown as { __forcedProvider?: string }).__forcedProvider ||\n (artifacts as unknown as { service?: string }).service;\n const forcedProvider: EvmContractDefinitionProviderKey | null = isEvmProviderKey(forcedRaw)\n ? (forcedRaw as EvmContractDefinitionProviderKey)\n : null;\n\n // 2. If no manual ABI, fall back to fetching from provider(s) with proxy detection.\n logger.info(\n 'loadEvmContract',\n `No manual ABI detected. Attempting Etherscan fetch for address: ${contractAddress}...`\n );\n\n return await loadContractWithProxyDetection(\n contractAddress,\n networkConfig,\n options,\n forcedProvider\n );\n}\n\n/**\n * Builds a standard contract result with metadata\n */\nfunction buildContractResult(\n contractAddress: string,\n abiResult: { schema: ContractSchema; originalAbi: string },\n networkConfig: EvmCompatibleNetworkConfig,\n sourceProvider: EvmContractDefinitionProviderKey | null,\n proxyInfo?: ProxyInfo\n): EvmContractLoadResult {\n // Determine provenance URL based on the provider that supplied the ABI\n let fetchedFrom: string | undefined = undefined;\n if (sourceProvider === EvmProviderKeys.Etherscan) {\n fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || undefined;\n } else if (sourceProvider === EvmProviderKeys.Sourcify) {\n fetchedFrom = getSourcifyContractAppUrl(networkConfig.chainId, contractAddress);\n } else {\n // Fallback to resolved explorer URL when provider is unknown\n fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || undefined;\n }\n\n return {\n schema: { ...abiResult.schema, address: contractAddress },\n source: 'fetched',\n contractDefinitionOriginal: abiResult.originalAbi,\n metadata: {\n fetchedFrom,\n contractName: abiResult.schema.name,\n verificationStatus: 'verified',\n fetchTimestamp: new Date(),\n definitionHash: simpleHash(abiResult.originalAbi),\n },\n proxyInfo,\n };\n}\n\n/**\n * Attempts to load implementation ABI for a detected proxy\n */\nasync function loadImplementationAbi(\n _contractAddress: string,\n implementationAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n _proxyType: string\n): Promise<{ schema: ContractSchema; originalAbi: string } | null> {\n try {\n const implementationResult = await loadAbiFromEtherscan(implementationAddress, networkConfig);\n\n logger.info(\n 'loadImplementationAbi',\n `Successfully fetched implementation ABI with ${implementationResult.schema.functions.length} functions`\n );\n\n return implementationResult;\n } catch (implementationError) {\n logger.warn(\n 'loadImplementationAbi',\n `Failed to load implementation ABI: ${implementationError}`\n );\n return null;\n }\n}\n\n/**\n * Handles the proxy detection flow and returns appropriate result\n */\nasync function handleProxyDetection(\n contractAddress: string,\n initialResult: { schema: ContractSchema; originalAbi: string },\n networkConfig: EvmCompatibleNetworkConfig,\n initialProvider: EvmContractDefinitionProviderKey | null\n): Promise<EvmContractLoadResult | null> {\n // Parse the ABI to check for proxy patterns\n const abi: AbiItem[] = JSON.parse(initialResult.originalAbi);\n const proxyDetection = detectProxyFromAbi(abi);\n\n if (!proxyDetection.isProxy) {\n return null; // Not a proxy, let caller handle normal flow\n }\n\n logger.info(\n 'handleProxyDetection',\n `Proxy detected: ${proxyDetection.proxyType} (confidence: ${proxyDetection.confidence})`\n );\n\n const proxyType = proxyDetection.proxyType || 'unknown';\n const implementationAddress = await getImplementationAddress(\n contractAddress,\n networkConfig,\n proxyType\n );\n\n // Attempt to resolve admin address as well for display purposes\n const adminAddress = await getAdminAddress(contractAddress, networkConfig);\n\n if (!implementationAddress) {\n logger.info('handleProxyDetection', 'Proxy detected but implementation address not found');\n\n // Return proxy ABI with proxy info indicating detection failure\n return buildContractResult(contractAddress, initialResult, networkConfig, initialProvider, {\n isProxy: true,\n proxyType,\n proxyAddress: contractAddress,\n detectionMethod: 'automatic',\n });\n }\n\n logger.info('handleProxyDetection', `Found implementation at: ${implementationAddress}`);\n\n // Try to load implementation ABI\n const implementationResult = await loadImplementationAbi(\n contractAddress,\n implementationAddress,\n networkConfig,\n proxyType\n );\n\n const baseProxyInfo = {\n isProxy: true,\n proxyType,\n implementationAddress,\n proxyAddress: contractAddress,\n detectionMethod: 'automatic',\n ...(adminAddress ? { adminAddress } : {}),\n };\n\n if (implementationResult) {\n // Use implementation ABI with proxy metadata\n // Implementation ABI was fetched from Etherscan\n return buildContractResult(\n contractAddress,\n implementationResult,\n networkConfig,\n EvmProviderKeys.Etherscan,\n baseProxyInfo\n );\n } else {\n // Fall back to proxy ABI with proxy info (provenance from initial provider)\n return buildContractResult(\n contractAddress,\n initialResult,\n networkConfig,\n initialProvider,\n baseProxyInfo\n );\n }\n}\n\n/**\n * Loads contract with automatic proxy detection and implementation resolution\n */\nasync function loadContractWithProxyDetection(\n contractAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n options: ContractLoadOptions = {},\n forcedProvider: EvmContractDefinitionProviderKey | null = null\n): Promise<EvmContractLoadResult> {\n try {\n // Determine provider precedence based on forced provider and user config\n let uiDefault: EvmContractDefinitionProviderKey | null = null;\n // 1) New generic per-service config\n const svcCfg = userNetworkServiceConfigService.get(networkConfig.id, 'contract-definitions');\n if (svcCfg && typeof svcCfg === 'object' && 'defaultProvider' in svcCfg) {\n const raw = (svcCfg as Record<string, unknown>).defaultProvider;\n if (isEvmProviderKey(raw)) uiDefault = raw as EvmContractDefinitionProviderKey;\n }\n // App-config default provider (optional)\n const appDefaultRaw = appConfigService.getGlobalServiceParam(\n 'contractdefinition',\n 'defaultProvider'\n );\n const appDefault: EvmContractDefinitionProviderKey | null =\n typeof appDefaultRaw === 'string' && isEvmProviderKey(appDefaultRaw)\n ? (appDefaultRaw as EvmContractDefinitionProviderKey)\n : null;\n\n // Helper function to build provider array from primary provider\n const buildProviderArray = (\n primary: EvmContractDefinitionProviderKey\n ): Array<EvmContractDefinitionProviderKey> => [\n primary,\n primary === EvmProviderKeys.Etherscan ? EvmProviderKeys.Sourcify : EvmProviderKeys.Etherscan,\n ];\n\n const providers: Array<EvmContractDefinitionProviderKey> = forcedProvider\n ? [forcedProvider]\n : uiDefault\n ? buildProviderArray(uiDefault)\n : appDefault\n ? buildProviderArray(appDefault)\n : [EvmProviderKeys.Etherscan, EvmProviderKeys.Sourcify];\n\n const overallDeadline = Date.now() + OVERALL_BUDGET_MS;\n let initialResult: { schema: ContractSchema; originalAbi: string } | null = null;\n let lastError: unknown = null;\n let usedProvider: EvmContractDefinitionProviderKey | null = null;\n for (const provider of providers) {\n try {\n const remainingOverall = Math.max(100, overallDeadline - Date.now());\n const attemptTimeout = Math.min(PER_PROVIDER_TIMEOUT_MS, remainingOverall);\n\n if (provider === EvmProviderKeys.Etherscan) {\n initialResult = await withTimeout(\n loadAbiFromEtherscan(contractAddress, networkConfig),\n attemptTimeout,\n 'etherscan'\n );\n } else if (provider === EvmProviderKeys.Sourcify) {\n initialResult = await withTimeout(\n loadAbiFromSourcify(contractAddress, networkConfig, attemptTimeout),\n attemptTimeout,\n 'sourcify'\n );\n }\n if (initialResult) {\n usedProvider = provider;\n break;\n }\n } catch (err) {\n lastError = err;\n continue;\n }\n }\n if (!initialResult) throw lastError ?? new Error('No provider succeeded');\n\n logger.info(\n 'loadContractWithProxyDetection',\n `Successfully fetched initial ABI for ${contractAddress} with ${initialResult.schema.functions.length} functions`\n );\n\n // Step 2: Handle proxy detection if enabled\n if (!options.skipProxyDetection && !options.treatAsImplementation) {\n const proxyResult = await handleProxyDetection(\n contractAddress,\n initialResult,\n networkConfig,\n usedProvider\n );\n if (proxyResult) {\n return proxyResult;\n }\n }\n\n // Step 3: Not a proxy or proxy detection skipped - return original ABI\n return buildContractResult(contractAddress, initialResult, networkConfig, usedProvider);\n } catch (error) {\n logger.warn('loadContractWithProxyDetection', `Contract loading failed: ${error}`);\n\n // If a forced provider was specified, honor it and do NOT fallback automatically\n if (forcedProvider) {\n throw error;\n }\n\n // Check if this is a \"contract not verified\" error\n const errorMessage = (error as Error).message || '';\n if (errorMessage.includes('Contract not verified')) {\n throw new Error(\n `Contract at ${contractAddress} is not verified on the block explorer. ` +\n `Verification status: unverified. Please provide the contract ABI manually.`\n );\n }\n // Otherwise, rethrow the last error from provider attempts\n throw error;\n }\n}\n\n// ============================================================================\n// Convenience Wrapper Functions\n// ============================================================================\n\n/**\n * Convenience wrapper that loads a contract and returns just the schema.\n * Handles artifact validation, ABI fetching, and proxy detection.\n *\n * @param source - Contract address string or artifacts object\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param options - Optional loading options\n * @returns The contract schema\n *\n * @example\n * ```typescript\n * // Load by address (fetches ABI from explorer)\n * const schema = await loadContractSchema('0x1234...', networkConfig);\n *\n * // Load with manual ABI\n * const schema = await loadContractSchema(\n * { contractAddress: '0x1234...', contractDefinition: '[...]' },\n * networkConfig\n * );\n * ```\n */\nexport async function loadContractSchema(\n source: string | Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig,\n options?: ContractLoadOptions\n): Promise<ContractSchema> {\n const { validateAndConvertEvmArtifacts } = await import('../utils');\n const artifacts = validateAndConvertEvmArtifacts(source);\n const result = await loadEvmContract(artifacts, networkConfig, options);\n return result.schema;\n}\n\n/**\n * Convenience wrapper that loads a contract with full metadata.\n * Returns schema, source information, original ABI, metadata, and proxy info.\n *\n * @param source - Contract address string or artifacts object\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @returns Full contract load result with metadata\n *\n * @example\n * ```typescript\n * const result = await loadContractWithFullMetadata('0x1234...', networkConfig);\n * console.log(result.schema.name); // Contract name\n * console.log(result.source); // 'fetched' | 'manual'\n * console.log(result.metadata?.fetchedFrom); // Explorer URL\n * console.log(result.proxyInfo?.isProxy); // Proxy detection result\n * ```\n */\nexport async function loadContractWithFullMetadata(\n source: string | Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<EvmContractLoadResult> {\n const { validateAndConvertEvmArtifacts } = await import('../utils');\n const artifacts = validateAndConvertEvmArtifacts(source);\n return loadEvmContract(artifacts, networkConfig);\n}\n","/**\n * Proxy Contract Detection Utilities\n *\n * Automatically detects proxy contracts and resolves implementation addresses\n * for UUPS, Transparent, Beacon, and other proxy patterns.\n */\nimport { createPublicClient, http, keccak256, parseAbi, toHex } from 'viem';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveRpcUrl } from '../configuration/rpc';\nimport { AbiItem } from '../types/abi';\nimport { EvmCompatibleNetworkConfig } from '../types/network';\n\nexport interface ProxyDetectionResult {\n isProxy: boolean;\n proxyType: 'uups' | 'transparent' | 'beacon' | 'diamond' | 'minimal' | 'unknown' | null;\n confidence: 'high' | 'medium' | 'low';\n indicators: string[];\n}\n\n/**\n * Analyzes an ABI to determine if it belongs to a proxy contract\n */\nexport function detectProxyFromAbi(abi: AbiItem[]): ProxyDetectionResult {\n const functions = abi.filter((item) => item.type === 'function');\n const events = abi.filter((item) => item.type === 'event');\n const errors = abi.filter((item) => item.type === 'error');\n\n const indicators: string[] = [];\n let proxyType: ProxyDetectionResult['proxyType'] = null;\n let confidence: ProxyDetectionResult['confidence'] = 'low';\n\n // Check for UUPS proxy indicators\n const hasUpgradeEvent = events.some((e) => e.name === 'Upgraded');\n const hasImplementationFunction = functions.some((f) => f.name === 'implementation');\n const hasUUPSErrors = errors.some((e) => e.name?.includes('ERC1967'));\n const hasUpgradeToFunction = functions.some(\n (f) => f.name === 'upgradeToAndCall' || f.name === 'upgradeTo'\n );\n\n if (hasUpgradeEvent || hasUUPSErrors) {\n indicators.push('ERC1967 upgrade pattern detected');\n proxyType = 'uups';\n confidence = 'high';\n }\n\n if (hasImplementationFunction) {\n indicators.push('implementation() function found');\n if (proxyType === 'uups') {\n confidence = 'high';\n } else {\n proxyType = 'transparent';\n confidence = 'medium';\n }\n }\n\n if (hasUpgradeToFunction && proxyType === 'uups') {\n indicators.push('UUPS upgrade functions found');\n confidence = 'high';\n }\n\n // Check for Transparent proxy indicators\n const hasAdminFunction = functions.some((f) => f.name === 'admin');\n const hasProxyAdminErrors = errors.some((e) => e.name?.includes('ProxyDenied'));\n const hasChangeAdminFunction = functions.some((f) => f.name === 'changeAdmin');\n\n if (hasAdminFunction || hasProxyAdminErrors || hasChangeAdminFunction) {\n indicators.push('Transparent proxy admin pattern detected');\n if (proxyType === null) {\n proxyType = 'transparent';\n confidence = 'medium';\n }\n }\n\n // Check for Beacon proxy indicators\n const hasBeaconFunction = functions.some((f) => f.name === 'beacon');\n const hasBeaconUpgrade = events.some((e) => e.name === 'BeaconUpgraded');\n\n if (hasBeaconFunction || hasBeaconUpgrade) {\n indicators.push('Beacon proxy pattern detected');\n proxyType = 'beacon';\n confidence = 'high';\n }\n\n // Check for Diamond proxy indicators\n const hasDiamondCut = functions.some((f) => f.name === 'diamondCut');\n const hasFacets = functions.some((f) => f.name === 'facets');\n const hasFacetFunctionSelectors = functions.some((f) => f.name === 'facetFunctionSelectors');\n\n if (hasDiamondCut || (hasFacets && hasFacetFunctionSelectors)) {\n indicators.push('Diamond (EIP-2535) proxy pattern detected');\n proxyType = 'diamond';\n confidence = 'high';\n }\n\n // General proxy indicators\n const hasFallback = abi.some((item) => item.type === 'fallback');\n const hasProxyConstructor = abi.some(\n (item) =>\n item.type === 'constructor' &&\n item.inputs?.some(\n (input: AbiItem) =>\n input.name === 'implementation' || input.name === '_logic' || input.name === '_data'\n )\n );\n\n if (hasFallback) {\n indicators.push('Fallback function present');\n }\n\n if (hasProxyConstructor) {\n indicators.push('Proxy-style constructor detected');\n }\n\n // Minimal proxy (EIP-1167) detection\n const hasMinimalFunctions = functions.length <= 1; // Usually no functions except maybe implementation()\n const hasNoEvents = events.length === 0;\n\n if (hasMinimalFunctions && hasNoEvents && hasFallback && proxyType === null) {\n indicators.push('Minimal proxy pattern detected');\n proxyType = 'minimal';\n confidence = 'medium';\n }\n\n // Final proxy determination\n const isProxy =\n proxyType !== null ||\n (hasFallback && hasMinimalFunctions && (hasProxyConstructor || functions.length === 0));\n\n if (isProxy && proxyType === null) {\n proxyType = 'unknown';\n indicators.push('Generic proxy pattern detected');\n confidence = 'low';\n }\n\n return {\n isProxy,\n proxyType,\n confidence,\n indicators,\n };\n}\n\n/**\n * Attempts to resolve the implementation address for a proxy contract\n *\n * @param proxyAddress - Address of the proxy contract\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @param proxyType - Type of proxy (uups, transparent, beacon, diamond, minimal, unknown)\n */\nexport async function getImplementationAddress(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig,\n proxyType: string\n): Promise<string | null> {\n logger.info(\n 'getImplementationAddress',\n `Resolving implementation for ${proxyType} proxy: ${proxyAddress}`\n );\n\n try {\n switch (proxyType) {\n case 'uups':\n case 'transparent': {\n // Try modern EIP-1967 slot first\n const eip1967Impl = await getEIP1967Implementation(proxyAddress, networkConfig);\n if (eip1967Impl) return eip1967Impl;\n\n // Fall back to legacy OZ Unstructured Storage slot used by older proxies\n const legacyImpl = await getLegacyOZImplementation(proxyAddress, networkConfig);\n if (legacyImpl) return legacyImpl;\n\n return null;\n }\n\n case 'beacon':\n return await getBeaconImplementation(proxyAddress, networkConfig);\n\n case 'diamond':\n // Diamond proxies don't have a single implementation\n // Would need to handle facets separately\n logger.info('getImplementationAddress', 'Diamond proxies not fully supported yet');\n return null;\n\n case 'minimal':\n return await getMinimalProxyImplementation(proxyAddress, networkConfig);\n\n default:\n // Try common methods for unknown proxy types\n return await tryCommonImplementationMethods(proxyAddress, networkConfig);\n }\n } catch (error) {\n logger.warn('getImplementationAddress', `Failed to resolve implementation: ${error}`);\n return null;\n }\n}\n\n/**\n * Attempts to resolve the admin address for a proxy contract\n * Tries EIP-1967 admin slot first, then legacy OZ slot\n *\n * @param proxyAddress - Address of the proxy contract\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n */\nexport async function getAdminAddress(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const eip1967Admin = await getEIP1967Admin(proxyAddress, networkConfig);\n if (eip1967Admin) return eip1967Admin;\n\n const legacyAdmin = await getLegacyOZAdmin(proxyAddress, networkConfig);\n if (legacyAdmin) return legacyAdmin;\n\n return null;\n } catch (error) {\n logger.warn('getAdminAddress', `Failed to resolve admin: ${error}`);\n return null;\n }\n}\n\n/**\n * Reads implementation address from EIP-1967 storage slot\n */\nasync function getEIP1967Implementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n // EIP-1967 implementation storage slot\n const implementationSlot = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc';\n\n return await readStorageSlot(proxyAddress, implementationSlot, networkConfig);\n}\n\n/**\n * Reads admin address from EIP-1967 admin storage slot\n * Slot: bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\nasync function getEIP1967Admin(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n const adminSlot = '0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103';\n return await readStorageSlot(proxyAddress, adminSlot, networkConfig);\n}\n\n/**\n * Reads admin address from legacy OpenZeppelin Unstructured Storage slot\n * Slot: keccak256(\"org.zeppelinos.proxy.admin\")\n */\nasync function getLegacyOZAdmin(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const slot = keccak256(toHex('org.zeppelinos.proxy.admin'));\n logger.info('getLegacyOZAdmin', `Trying legacy OZ admin slot: ${slot}`);\n return await readStorageSlot(proxyAddress, slot, networkConfig);\n } catch (error) {\n logger.warn('getLegacyOZAdmin', `Failed computing or reading legacy admin slot: ${error}`);\n return null;\n }\n}\n\n/**\n * Reads implementation address from legacy OpenZeppelin Unstructured Storage slot\n * Slot: keccak256(\"org.zeppelinos.proxy.implementation\")\n */\nasync function getLegacyOZImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n // Compute slot deterministically at runtime to avoid hardcoding\n const slot = keccak256(toHex('org.zeppelinos.proxy.implementation'));\n logger.info('getLegacyOZImplementation', `Trying legacy OZ slot: ${slot}`);\n return await readStorageSlot(proxyAddress, slot, networkConfig);\n } catch (error) {\n logger.warn('getLegacyOZImplementation', `Failed computing or reading legacy slot: ${error}`);\n return null;\n }\n}\n\n/**\n * Resolves implementation through beacon proxy pattern\n */\nasync function getBeaconImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n // EIP-1967 beacon storage slot\n const beaconSlot = '0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50';\n\n const beaconAddress = await readStorageSlot(proxyAddress, beaconSlot, networkConfig);\n if (!beaconAddress) {\n return null;\n }\n\n // Call implementation() on the beacon contract\n return await callContractFunction(beaconAddress, 'implementation()', [], networkConfig);\n}\n\n/**\n * Extracts implementation from minimal proxy bytecode\n */\nasync function getMinimalProxyImplementation(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n // Get the contract bytecode\n const bytecode = await getContractBytecode(proxyAddress, networkConfig);\n\n if (!bytecode || bytecode.length < 42) {\n return null;\n }\n\n // Minimal proxy (EIP-1167) has a specific bytecode pattern\n // 0x363d3d373d3d3d363d73{implementation}5af43d82803e903d91602b57fd5bf3\n if (\n bytecode.startsWith('0x363d3d373d3d3d363d73') &&\n bytecode.includes('5af43d82803e903d91602b57fd5bf3')\n ) {\n // Extract the 20-byte implementation address\n const implementationHex = bytecode.slice(22, 62); // Skip prefix, take 20 bytes (40 hex chars)\n return '0x' + implementationHex;\n }\n\n return null;\n } catch (error) {\n logger.warn('getMinimalProxyImplementation', `Error reading bytecode: ${error}`);\n return null;\n }\n}\n\n/**\n * Tries common proxy implementation methods\n */\nasync function tryCommonImplementationMethods(\n proxyAddress: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n const commonMethods = [\n 'implementation()',\n 'getImplementation()',\n '_implementation()',\n 'target()',\n ];\n\n for (const method of commonMethods) {\n try {\n const result = await callContractFunction(proxyAddress, method, [], networkConfig);\n if (result && result !== '0x0000000000000000000000000000000000000000') {\n logger.info(\n 'tryCommonImplementationMethods',\n `Found implementation via ${method}: ${result}`\n );\n return result;\n }\n } catch {\n // Continue to next method\n continue;\n }\n }\n\n // Try EIP-1967 storage as last resort\n return await getEIP1967Implementation(proxyAddress, networkConfig);\n}\n\n/**\n * Creates a viem public client for the given network configuration\n */\nfunction createViemClient(networkConfig: EvmCompatibleNetworkConfig) {\n // Honor user/app RPC overrides\n const rpcUrl = resolveRpcUrl(networkConfig);\n return createPublicClient({\n transport: http(rpcUrl),\n });\n}\n\n/**\n * Reads a storage slot from a contract using viem\n */\nasync function readStorageSlot(\n address: string,\n slot: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n const storageValue = await client.getStorageAt({\n address: address as `0x${string}`,\n slot: slot as `0x${string}`,\n });\n\n // Convert from 32-byte storage format to 20-byte address\n if (\n storageValue &&\n storageValue !== '0x0000000000000000000000000000000000000000000000000000000000000000'\n ) {\n logger.info('readStorageSlot', `Found non-zero value at slot ${slot}: ${storageValue}`);\n const implAddress = '0x' + storageValue.slice(-40); // Last 20 bytes\n return implAddress;\n }\n\n return null;\n } catch (error) {\n logger.warn('readStorageSlot', `Failed to read storage slot ${slot}: ${error}`);\n return null;\n }\n}\n\n/**\n * Calls a function on a contract using viem's readContract\n * Supports functions with parameters and proper return value decoding\n */\nasync function callContractFunction(\n address: string,\n signature: string,\n params: unknown[],\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n // Parse the function signature to get proper ABI format\n const abi = parseAbi([signature]);\n const func = abi[0] as { name: string; type: 'function' };\n\n // Use viem's readContract for cleaner, more robust contract calls\n const result = await client.readContract({\n address: address as `0x${string}`,\n abi,\n functionName: func.name,\n args: params as readonly unknown[],\n });\n\n // For proxy functions, we expect an address return value\n const addressResult = result as string;\n if (addressResult && addressResult !== '0x0000000000000000000000000000000000000000') {\n return addressResult;\n }\n\n return null;\n } catch (error) {\n logger.warn('callContractFunction', `Failed to call ${signature}: ${error}`);\n return null;\n }\n}\n\n/**\n * Gets contract bytecode using viem\n */\nasync function getContractBytecode(\n address: string,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<string | null> {\n try {\n const client = createViemClient(networkConfig);\n\n const bytecode = await client.getCode({\n address: address as `0x${string}`,\n });\n\n return bytecode || null;\n } catch (error) {\n logger.warn('getContractBytecode', `Failed to get bytecode: ${error}`);\n return null;\n }\n}\n","import type { UserRpcProviderConfig } from '@openzeppelin/ui-types';\nimport {\n appConfigService,\n isValidUrl,\n logger,\n userNetworkServiceConfigService,\n} from '@openzeppelin/ui-utils';\n\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\n\n/**\n * Builds a complete RPC URL from a user RPC provider configuration.\n * For simplified RPC configuration, this just returns the URL as-is since\n * users are now providing complete RPC URLs including any API keys.\n *\n * @param config The user RPC provider configuration\n * @returns The RPC URL\n */\nexport function buildRpcUrl(config: UserRpcProviderConfig): string {\n return config.url;\n}\n\n/**\n * Extracts the user-configured RPC URL from UserNetworkServiceConfigService.\n *\n * @param networkId - The network ID to get the RPC URL for\n * @returns The RPC URL string if configured, undefined otherwise\n */\nexport function getUserRpcUrl(networkId: string): string | undefined {\n const svcCfg = userNetworkServiceConfigService.get(networkId, 'rpc');\n if (svcCfg && typeof svcCfg === 'object' && 'rpcUrl' in svcCfg) {\n return (svcCfg as Record<string, unknown>).rpcUrl as string;\n }\n return undefined;\n}\n\n/**\n * Resolves the RPC URL for a given EVM network configuration.\n * Priority order:\n * 1. User-provided RPC configuration (from UserRpcConfigService)\n * 2. RPC URL override from AppConfigService\n * 3. Default rpcUrl from the network configuration\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem).\n * @returns The resolved RPC URL string.\n * @throws If no RPC URL can be resolved (neither user config, override, nor default is present and valid).\n */\nexport function resolveRpcUrl(networkConfig: EvmCompatibleNetworkConfig): string {\n const logSystem = 'RpcResolver';\n const networkId = networkConfig.id;\n\n // First priority: Check adapter-led service config (generic)\n const userRpcUrl = getUserRpcUrl(networkId);\n if (userRpcUrl) {\n const userRpcUrlString = String(userRpcUrl);\n if (isValidUrl(userRpcUrlString)) {\n logger.info(logSystem, `Using user-configured RPC URL for network ${networkId}`);\n return userRpcUrlString;\n } else {\n logger.warn(\n logSystem,\n `User-configured RPC URL for ${networkId} is invalid: ${userRpcUrlString}. Falling back.`\n );\n }\n }\n\n // Second priority: Check AppConfigService for an override\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(networkId);\n let rpcUrlFromOverride: string | undefined;\n\n if (typeof rpcOverrideSetting === 'string') {\n rpcUrlFromOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting) {\n // Check if it's a UserRpcProviderConfig\n if ('url' in rpcOverrideSetting && 'isCustom' in rpcOverrideSetting) {\n const userConfig = rpcOverrideSetting as UserRpcProviderConfig;\n rpcUrlFromOverride = buildRpcUrl(userConfig);\n } else if ('http' in rpcOverrideSetting) {\n // It's an RpcEndpointConfig\n rpcUrlFromOverride = rpcOverrideSetting.http;\n }\n }\n\n if (rpcUrlFromOverride) {\n logger.info(\n logSystem,\n `Using overridden RPC URL for network ${networkId}: ${rpcUrlFromOverride}`\n );\n if (isValidUrl(rpcUrlFromOverride)) {\n return rpcUrlFromOverride;\n } else {\n logger.warn(\n logSystem,\n `Overridden RPC URL for ${networkId} is invalid: ${rpcUrlFromOverride}. Falling back.`\n );\n }\n }\n\n // Third priority: Fallback to the rpcUrl in the networkConfig\n if (networkConfig.rpcUrl && isValidUrl(networkConfig.rpcUrl)) {\n logger.debug(\n logSystem,\n `Using default RPC URL for network ${networkId}: ${networkConfig.rpcUrl}`\n );\n return networkConfig.rpcUrl;\n }\n\n logger.error(\n logSystem,\n `No valid RPC URL could be resolved for network ${networkId}. Checked user config, override, and networkConfig.rpcUrl.`\n );\n throw new Error(\n `No valid RPC URL configured for network ${networkConfig.name} (ID: ${networkId}).`\n );\n}\n\n/**\n * Validates an RPC endpoint configuration for EVM networks.\n * @param rpcConfig - The RPC provider configuration to validate\n * @returns True if the configuration is valid, false otherwise\n */\nexport function validateEvmRpcEndpoint(rpcConfig: UserRpcProviderConfig): boolean {\n try {\n // Check if it's a valid URL (our validator already ensures HTTP/HTTPS)\n if (!isValidUrl(rpcConfig.url)) {\n logger.error('validateEvmRpcEndpoint', `Invalid RPC URL format: ${rpcConfig.url}`);\n return false;\n }\n\n // Additional EVM-specific validation could be added here\n // For example, checking if the URL follows known provider patterns\n\n return true;\n } catch (error) {\n logger.error('validateEvmRpcEndpoint', 'Error validating RPC endpoint:', error);\n return false;\n }\n}\n\n/**\n * Tests the connection to an EVM RPC endpoint with a timeout.\n * @param rpcConfig - The RPC provider configuration to test\n * @param timeoutMs - Timeout in milliseconds (default: 5000ms)\n * @returns Connection test results including success status, latency, and any errors\n */\nexport async function testEvmRpcConnection(\n rpcConfig: UserRpcProviderConfig,\n timeoutMs: number = 5000\n): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n}> {\n if (!rpcConfig.url) {\n return { success: false, error: 'RPC URL is required' };\n }\n\n // Create an AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const startTime = Date.now();\n\n // Use fetch to make a JSON-RPC call to test the connection\n const response = await fetch(rpcConfig.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_blockNumber',\n params: [],\n id: 1,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return { success: false, error: `HTTP error: ${response.status}` };\n }\n\n const data = await response.json();\n const latency = Date.now() - startTime;\n\n if (data.error) {\n return { success: false, error: data.error.message || 'RPC error' };\n }\n\n return { success: true, latency };\n } catch (error) {\n logger.error('testEvmRpcConnection', 'Connection test failed:', error);\n\n // Check if the error was due to timeout\n if (error instanceof Error && error.name === 'AbortError') {\n return {\n success: false,\n error: `Connection timeout after ${timeoutMs}ms`,\n };\n }\n\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Connection failed',\n };\n } finally {\n // Clear the timeout\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Gets the current block number from an EVM network.\n *\n * @param networkConfig - EVM-compatible network configuration (works with any ecosystem)\n * @returns Promise resolving to the current block number\n * @throws Error if the RPC call fails\n */\nexport async function getEvmCurrentBlock(\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<number> {\n const rpcUrl = resolveRpcUrl(networkConfig);\n\n try {\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'eth_blockNumber',\n params: [],\n id: 1,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`RPC request failed with status ${response.status}`);\n }\n\n const data = await response.json();\n if (data.error) {\n throw new Error(data.error.message || 'RPC error');\n }\n\n // eth_blockNumber returns a hex string\n if (data.result === undefined || data.result === null) {\n throw new Error('RPC response missing result field');\n }\n const blockNumber = parseInt(data.result, 16);\n if (isNaN(blockNumber)) {\n throw new Error(`Invalid block number returned: ${data.result}`);\n }\n return blockNumber;\n } catch (error) {\n logger.error('getEvmCurrentBlock', 'Failed to get current block:', error);\n throw new Error(\n `Failed to get current block: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n","/**\n * EVM Contract Definition Provider keys and ordering\n * Avoid magic strings by using typed constants and a union type.\n */\n\nexport const EvmProviderKeys = {\n Etherscan: 'etherscan',\n Sourcify: 'sourcify',\n} as const;\n\nexport type EvmContractDefinitionProviderKey =\n (typeof EvmProviderKeys)[keyof typeof EvmProviderKeys];\n\nexport const EVM_PROVIDER_ORDER_DEFAULT: readonly EvmContractDefinitionProviderKey[] = [\n EvmProviderKeys.Etherscan,\n EvmProviderKeys.Sourcify,\n] as const;\n\nexport function isEvmProviderKey(value: unknown): value is EvmContractDefinitionProviderKey {\n return value === EvmProviderKeys.Etherscan || value === EvmProviderKeys.Sourcify;\n}\n","/**\n * EVM-specific ABI types for comparison and validation\n * Uses viem's Abi type as the foundation for type safety\n */\n\nimport type { Abi } from 'viem';\n\n/**\n * Result of comparing two ABIs\n */\nexport interface AbiComparisonResult {\n /** Whether the ABIs are identical after normalization */\n identical: boolean;\n /** List of differences found between the ABIs */\n differences: AbiDifference[];\n /** Overall severity of the changes */\n severity: 'none' | 'minor' | 'major' | 'breaking';\n /** Human-readable summary of the comparison */\n summary: string;\n}\n\n/**\n * Represents a single difference between two ABIs\n */\nexport interface AbiDifference {\n /** Type of change */\n type: 'added' | 'removed' | 'modified';\n /** Which section of the ABI was affected */\n section: 'function' | 'event' | 'constructor' | 'error' | 'fallback' | 'receive';\n /** Name of the affected item (or type if no name) */\n name: string;\n /** Detailed description of the change */\n details: string;\n /** Impact level of this change */\n impact: 'low' | 'medium' | 'high';\n /** Signature before the change (for removed/modified) */\n oldSignature?: string;\n /** Signature after the change (for added/modified) */\n newSignature?: string;\n}\n\n/**\n * Result of validating an ABI structure\n */\nexport interface AbiValidationResult {\n /** Whether the ABI is structurally valid */\n valid: boolean;\n /** List of validation errors found */\n errors: string[];\n /** List of validation warnings */\n warnings: string[];\n /** Normalized ABI if validation passed */\n normalizedAbi?: Abi;\n}\n\n/**\n * Type guard to check if a value is a valid ABI array\n */\nexport function isValidAbiArray(value: unknown): value is Abi {\n return Array.isArray(value) && value.every(isValidAbiItem);\n}\n\n/**\n * Type guard to check if a value is a valid ABI item\n */\nexport function isValidAbiItem(item: unknown): boolean {\n if (typeof item !== 'object' || item === null) {\n return false;\n }\n\n const abiItem = item as Record<string, unknown>;\n\n // Must have a valid type\n if (typeof abiItem.type !== 'string') {\n return false;\n }\n\n const validTypes = ['function', 'event', 'constructor', 'error', 'fallback', 'receive'];\n if (!validTypes.includes(abiItem.type)) {\n return false;\n }\n\n // Functions and events must have a name\n if (\n (abiItem.type === 'function' || abiItem.type === 'event') &&\n typeof abiItem.name !== 'string'\n ) {\n return false;\n }\n\n // Functions, events, and constructors should have inputs array\n if (\n (abiItem.type === 'function' || abiItem.type === 'event' || abiItem.type === 'constructor') &&\n abiItem.inputs !== undefined &&\n !Array.isArray(abiItem.inputs)\n ) {\n return false;\n }\n\n return true;\n}\n","/**\n * ABI comparison service for EVM contracts\n * Provides detailed analysis of differences between ABIs\n */\n\nimport type { Abi } from 'viem';\n\nimport { logger, simpleHash } from '@openzeppelin/ui-utils';\n\nimport type { AbiComparisonResult, AbiDifference, AbiValidationResult } from './types';\nimport { isValidAbiArray } from './types';\n\n/**\n * Service for comparing and validating EVM ABIs\n */\nexport class AbiComparisonService {\n /**\n * Compares two ABIs and returns detailed difference analysis\n */\n public compareAbis(abi1: string, abi2: string): AbiComparisonResult {\n try {\n const validation1 = this.validateAbi(abi1);\n const validation2 = this.validateAbi(abi2);\n\n if (!validation1.valid || !validation2.valid) {\n return {\n identical: false,\n differences: [],\n severity: 'breaking',\n summary: 'One or both ABIs are invalid and cannot be compared',\n };\n }\n\n const normalized1 = this.normalizeAbi(validation1.normalizedAbi!);\n const normalized2 = this.normalizeAbi(validation2.normalizedAbi!);\n\n const hash1 = simpleHash(JSON.stringify(normalized1));\n const hash2 = simpleHash(JSON.stringify(normalized2));\n\n if (hash1 === hash2) {\n return {\n identical: true,\n differences: [],\n severity: 'none',\n summary: 'ABIs are identical',\n };\n }\n\n const differences = this.findDifferences(normalized1, normalized2);\n const severity = this.calculateSeverity(differences);\n\n return {\n identical: false,\n differences,\n severity,\n summary: this.generateSummary(differences),\n };\n } catch (error) {\n logger.error('ABI comparison failed:', (error as Error).message);\n return {\n identical: false,\n differences: [],\n severity: 'breaking',\n summary: `Comparison failed: ${(error as Error).message}`,\n };\n }\n }\n\n /**\n * Validates ABI structure and format\n */\n public validateAbi(abiString: string): AbiValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n try {\n // Parse JSON\n const abi = JSON.parse(abiString);\n\n if (!Array.isArray(abi)) {\n errors.push('ABI must be an array');\n return { valid: false, errors, warnings };\n }\n\n // Empty ABI arrays are not valid contract definitions\n if (abi.length === 0) {\n errors.push(\n 'ABI array cannot be empty - contract must have at least one function, event, or constructor'\n );\n return { valid: false, errors, warnings };\n }\n\n // Validate each ABI item\n for (let i = 0; i < abi.length; i++) {\n const item = abi[i];\n\n if (!item.type) {\n errors.push(`Item ${i}: Missing 'type' field`);\n continue;\n }\n\n if (\n !['function', 'event', 'constructor', 'error', 'fallback', 'receive'].includes(item.type)\n ) {\n errors.push(`Item ${i}: Invalid type '${item.type}'`);\n }\n\n if (item.type === 'function' && !item.name) {\n errors.push(`Item ${i}: Function missing 'name' field`);\n }\n\n if ((item.type === 'function' || item.type === 'event') && !Array.isArray(item.inputs)) {\n errors.push(`Item ${i}: Missing or invalid 'inputs' array`);\n }\n\n if (item.type === 'function' && !Array.isArray(item.outputs)) {\n warnings.push(`Item ${i}: Function missing 'outputs' array`);\n }\n }\n\n // Additional viem-specific validation\n if (errors.length === 0 && !isValidAbiArray(abi)) {\n errors.push('ABI does not conform to expected format');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n normalizedAbi: errors.length === 0 ? (abi as Abi) : undefined,\n };\n } catch (parseError) {\n errors.push(`Invalid JSON: ${(parseError as Error).message}`);\n return { valid: false, errors, warnings };\n }\n }\n\n /**\n * Creates deterministic hash of ABI for quick comparison\n */\n public hashAbi(abiString: string): string {\n try {\n const validation = this.validateAbi(abiString);\n if (!validation.valid || !validation.normalizedAbi) {\n throw new Error('Cannot hash invalid ABI');\n }\n\n const normalized = this.normalizeAbi(validation.normalizedAbi);\n const normalizedString = JSON.stringify(normalized);\n\n return simpleHash(normalizedString);\n } catch (error) {\n logger.error('ABI hashing failed:', (error as Error).message);\n throw new Error(`Failed to hash ABI: ${(error as Error).message}`);\n }\n }\n\n /**\n * Normalizes ABI for consistent comparison\n */\n private normalizeAbi(abi: Abi): Abi {\n return abi\n .map((item) => {\n // Remove ordering-dependent fields and sort inputs/outputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const normalized: any = { ...item };\n\n if (normalized.inputs) {\n normalized.inputs = [...normalized.inputs].sort((a, b) =>\n (a.name || '').localeCompare(b.name || '')\n );\n }\n\n if (normalized.outputs) {\n normalized.outputs = [...normalized.outputs].sort((a, b) =>\n (a.name || '').localeCompare(b.name || '')\n );\n }\n\n return normalized;\n })\n .sort((a, b) => {\n // Sort by type first, then by name\n const typeOrder = {\n constructor: 0,\n fallback: 1,\n receive: 2,\n function: 3,\n event: 4,\n error: 5,\n };\n const aOrder = typeOrder[a.type as keyof typeof typeOrder] ?? 99;\n const bOrder = typeOrder[b.type as keyof typeof typeOrder] ?? 99;\n\n if (aOrder !== bOrder) return aOrder - bOrder;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const aName = (a as any).name || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bName = (b as any).name || '';\n return aName.localeCompare(bName);\n }) as Abi;\n }\n\n /**\n * Finds detailed differences between two normalized ABIs\n */\n private findDifferences(abi1: Abi, abi2: Abi): AbiDifference[] {\n const differences: AbiDifference[] = [];\n\n // Create maps for efficient lookup\n const map1 = this.createAbiMap(abi1);\n const map2 = this.createAbiMap(abi2);\n\n // Find removed items\n for (const [key, item] of map1) {\n if (!map2.has(key)) {\n differences.push({\n type: 'removed',\n section: item.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item as any).name || item.type,\n details: `${item.type} was removed`,\n impact: this.calculateImpact(item.type, 'removed'),\n oldSignature: this.generateSignature(item),\n });\n }\n }\n\n // Find added items\n for (const [key, item] of map2) {\n if (!map1.has(key)) {\n differences.push({\n type: 'added',\n section: item.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item as any).name || item.type,\n details: `${item.type} was added`,\n impact: this.calculateImpact(item.type, 'added'),\n newSignature: this.generateSignature(item),\n });\n }\n }\n\n // Find modified items\n for (const [key, item1] of map1) {\n const item2 = map2.get(key);\n if (item2 && !this.itemsEqual(item1, item2)) {\n differences.push({\n type: 'modified',\n section: item1.type as AbiDifference['section'],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n name: (item1 as any).name || item1.type,\n details: `${item1.type} signature changed`,\n impact: this.calculateImpact(item1.type, 'modified'),\n oldSignature: this.generateSignature(item1),\n newSignature: this.generateSignature(item2),\n });\n }\n }\n\n return differences;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private createAbiMap(abi: Abi): Map<string, any> {\n const map = new Map();\n\n for (const item of abi) {\n const key = this.generateItemKey(item);\n map.set(key, item);\n }\n\n return map;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private generateItemKey(item: any): string {\n if (item.type === 'constructor' || item.type === 'fallback' || item.type === 'receive') {\n return item.type;\n }\n\n const name = item.name || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const inputs = item.inputs?.map((input: any) => input.type).join(',') || '';\n return `${item.type}:${name}(${inputs})`;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private generateSignature(item: any): string {\n if (item.type === 'constructor') {\n const inputs =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n item.inputs?.map((input: any) => `${input.type} ${input.name || ''}`).join(', ') || '';\n return `constructor(${inputs})`;\n }\n\n if (item.type === 'fallback' || item.type === 'receive') {\n return item.type + '()';\n }\n\n if (item.type === 'function') {\n const inputs =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n item.inputs?.map((input: any) => `${input.type} ${input.name || ''}`).join(', ') || '';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const outputs = item.outputs?.map((output: any) => output.type).join(', ') || '';\n const mutability = item.stateMutability ? ` ${item.stateMutability}` : '';\n return `function ${item.name}(${inputs})${mutability}${outputs ? ` returns (${outputs})` : ''}`;\n }\n\n if (item.type === 'event') {\n const inputs =\n item.inputs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ?.map((input: any) => {\n const indexed = input.indexed ? ' indexed' : '';\n return `${input.type}${indexed} ${input.name || ''}`;\n })\n .join(', ') || '';\n return `event ${item.name}(${inputs})`;\n }\n\n return JSON.stringify(item);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private itemsEqual(item1: any, item2: any): boolean {\n return JSON.stringify(item1) === JSON.stringify(item2);\n }\n\n private calculateImpact(\n type: string,\n changeType: 'added' | 'removed' | 'modified'\n ): 'low' | 'medium' | 'high' {\n if (type === 'constructor' || type === 'fallback' || type === 'receive') {\n return changeType === 'modified' ? 'high' : 'medium';\n }\n\n if (type === 'function') {\n if (changeType === 'removed') return 'high'; // Breaking: removes functionality\n if (changeType === 'modified') return 'medium'; // Major: changes behavior\n if (changeType === 'added') return 'low'; // Minor: adds functionality\n }\n\n if (type === 'event') {\n return 'low'; // Events don't break existing functionality\n }\n\n if (type === 'error') {\n return 'low'; // Custom errors don't break existing functionality\n }\n\n return 'medium';\n }\n\n private calculateSeverity(differences: AbiDifference[]): 'none' | 'minor' | 'major' | 'breaking' {\n if (differences.length === 0) return 'none';\n\n const hasHighImpact = differences.some((d) => d.impact === 'high');\n const hasMediumImpact = differences.some((d) => d.impact === 'medium');\n const hasRemovedFunctions = differences.some(\n (d) => d.type === 'removed' && d.section === 'function'\n );\n\n if (hasRemovedFunctions || hasHighImpact) return 'breaking';\n if (hasMediumImpact) return 'major';\n return 'minor';\n }\n\n private generateSummary(differences: AbiDifference[]): string {\n const counts = {\n added: differences.filter((d) => d.type === 'added').length,\n removed: differences.filter((d) => d.type === 'removed').length,\n modified: differences.filter((d) => d.type === 'modified').length,\n };\n\n const parts: string[] = [];\n if (counts.added > 0) parts.push(`${counts.added} added`);\n if (counts.removed > 0) parts.push(`${counts.removed} removed`);\n if (counts.modified > 0) parts.push(`${counts.modified} modified`);\n\n const summary = parts.join(', ');\n return `${summary}`;\n }\n}\n\n// Export singleton instance\nexport const abiComparisonService = new AbiComparisonService();\n\n// ============================================================================\n// Convenience Wrapper Functions\n// ============================================================================\n\n/**\n * Compare two contract definitions (ABI strings).\n * Convenience wrapper around abiComparisonService.compareAbis().\n *\n * @param storedSchema - The stored/original ABI JSON string\n * @param freshSchema - The new/fresh ABI JSON string to compare against\n * @returns Comparison result with differences and severity\n *\n * @example\n * ```typescript\n * const result = await compareContractDefinitions(oldAbi, newAbi);\n * if (!result.identical) {\n * console.log(`Changes detected: ${result.summary}`);\n * console.log(`Severity: ${result.severity}`);\n * }\n * ```\n */\nexport async function compareContractDefinitions(\n storedSchema: string,\n freshSchema: string\n): Promise<AbiComparisonResult> {\n return abiComparisonService.compareAbis(storedSchema, freshSchema);\n}\n\n/**\n * Validate a contract definition (ABI string).\n * Convenience wrapper around abiComparisonService.validateAbi().\n *\n * @param definition - The ABI JSON string to validate\n * @returns Validation result with errors and warnings\n *\n * @example\n * ```typescript\n * const result = validateContractDefinition(abiJson);\n * if (!result.valid) {\n * console.log('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateContractDefinition(definition: string): AbiValidationResult {\n return abiComparisonService.validateAbi(definition);\n}\n\n/**\n * Hash a contract definition (ABI string) for comparison.\n * Convenience wrapper around abiComparisonService.hashAbi().\n *\n * @param definition - The ABI JSON string to hash\n * @returns Deterministic hash of the normalized ABI\n *\n * @example\n * ```typescript\n * const hash1 = hashContractDefinition(abi1);\n * const hash2 = hashContractDefinition(abi2);\n * if (hash1 === hash2) {\n * console.log('ABIs are identical');\n * }\n * ```\n */\nexport function hashContractDefinition(definition: string): string {\n return abiComparisonService.hashAbi(definition);\n}\n","import type { FieldType, TypeMappingInfo } from '@openzeppelin/ui-types';\n\n/**\n * EVM-specific type mapping to default form field types.\n *\n * Note: Large integer types (uint128, uint256, int128, int256) are mapped to 'bigint'\n * instead of 'number' to avoid JavaScript's Number precision limitations.\n * JavaScript's Number type can only safely represent integers up to 2^53 - 1,\n * but these types can hold much larger values. The BigIntField component stores values\n * as strings and the EVM adapter handles BigInt conversion automatically.\n */\nexport const EVM_TYPE_TO_FIELD_TYPE: Record<string, FieldType> = {\n address: 'blockchain-address',\n string: 'text',\n uint: 'number',\n uint8: 'number',\n uint16: 'number',\n uint32: 'number',\n uint64: 'bigint',\n uint128: 'bigint',\n uint256: 'bigint',\n int: 'number',\n int8: 'number',\n int16: 'number',\n int32: 'number',\n int64: 'bigint',\n int128: 'bigint',\n int256: 'bigint',\n bool: 'checkbox',\n bytes: 'bytes',\n bytes32: 'bytes',\n};\n\n/**\n * EVM dynamic type patterns handled through pattern matching.\n */\nconst EVM_DYNAMIC_PATTERNS: TypeMappingInfo['dynamicPatterns'] = [\n { name: 'array', syntax: 'T[]', mapsTo: 'array', description: 'Dynamic array of primitives' },\n { name: 'fixed-array', syntax: 'T[N]', mapsTo: 'array', description: 'Fixed-size array' },\n {\n name: 'tuple-array',\n syntax: 'tuple[]',\n mapsTo: 'array-object',\n description: 'Array of structs',\n },\n { name: 'tuple', syntax: 'tuple', mapsTo: 'object', description: 'Struct/tuple type' },\n];\n\n/**\n * Returns complete type mapping information for EVM.\n */\nexport function getEvmTypeMappingInfo(): TypeMappingInfo {\n return {\n primitives: { ...EVM_TYPE_TO_FIELD_TYPE },\n dynamicPatterns: EVM_DYNAMIC_PATTERNS,\n };\n}\n","import type { FieldType } from '@openzeppelin/ui-types';\n\nimport { EVM_TYPE_TO_FIELD_TYPE } from './constants';\n\n/**\n * Map a blockchain-specific parameter type to a default form field type.\n * @param parameterType The blockchain parameter type (e.g., 'uint256', 'address', 'tuple')\n * @returns The appropriate default form field type (e.g., 'number', 'blockchain-address', 'object')\n */\nexport function mapEvmParamTypeToFieldType(parameterType: string): FieldType {\n // Check if this is an array of tuples/objects\n if (parameterType.match(/^tuple\\[\\d*\\]$/)) {\n return 'array-object';\n }\n\n // Check if this is an array type (ends with [] or [number])\n if (parameterType.match(/\\[\\d*\\]$/)) {\n return 'array';\n }\n\n // Extract the base type from array types (e.g., uint256[] -> uint256)\n const baseType = parameterType.replace(/\\[\\d*\\]/g, '');\n\n // Handle tuples (structs) - use object for composite types\n if (baseType.startsWith('tuple')) {\n return 'object';\n }\n\n // Handle all bytesN types (bytes1-bytes32) - map to 'bytes' field for proper hex validation\n if (baseType.match(/^bytes\\d+$/)) {\n return 'bytes';\n }\n\n // Map common EVM types to appropriate field types\n return EVM_TYPE_TO_FIELD_TYPE[baseType] || 'text'; // Default to 'text'\n}\n\n/**\n * Get field types compatible with a specific parameter type.\n * @param parameterType The blockchain parameter type.\n * @returns Array of compatible form field types.\n */\nexport function getEvmCompatibleFieldTypes(parameterType: string): FieldType[] {\n // Handle array of objects\n if (parameterType.match(/^tuple\\[\\d*\\]$/)) {\n return ['array-object', 'textarea', 'text'];\n }\n\n // Handle array types - allow array field or fallback to textarea/text\n if (parameterType.match(/\\[\\d*\\]$/)) {\n return ['array', 'textarea', 'text'];\n }\n\n const baseType = parameterType.replace(/\\[\\d*\\]/g, '');\n\n // Handle tuples/objects\n if (baseType.startsWith('tuple')) {\n return ['object', 'textarea', 'text'];\n }\n\n // Define compatibility map for base types\n const compatibilityMap: Record<string, FieldType[]> = {\n address: ['blockchain-address', 'text'],\n uint: ['number', 'amount', 'text'],\n uint8: ['number', 'amount', 'text'],\n uint16: ['number', 'amount', 'text'],\n uint32: ['number', 'amount', 'text'],\n uint64: ['bigint', 'number', 'amount', 'text'],\n uint128: ['bigint', 'number', 'amount', 'text'],\n uint256: ['bigint', 'number', 'amount', 'text'],\n int: ['number', 'text'],\n int8: ['number', 'text'],\n int16: ['number', 'text'],\n int32: ['number', 'text'],\n int64: ['bigint', 'number', 'text'],\n int128: ['bigint', 'number', 'text'],\n int256: ['bigint', 'number', 'text'],\n bool: ['checkbox', 'select', 'radio', 'text'],\n string: ['text', 'textarea', 'email', 'password'],\n bytes: ['bytes', 'textarea', 'text'],\n bytes32: ['bytes', 'textarea', 'text'],\n };\n\n // Handle all bytesN types (bytes1-bytes32) - allow 'bytes' field for proper hex validation\n if (baseType.match(/^bytes\\d+$/)) {\n return ['bytes', 'textarea', 'text'];\n }\n\n return compatibilityMap[baseType] || ['text']; // Default to 'text'\n}\n","import { startCase } from 'lodash';\n\nimport type {\n FieldType,\n FieldValidation,\n FieldValue,\n FormFieldType,\n FunctionParameter,\n} from '@openzeppelin/ui-types';\nimport {\n enhanceNumericValidation,\n getDefaultValueForType,\n type NumericBoundsMap,\n} from '@openzeppelin/ui-utils';\n\nimport { mapEvmParamTypeToFieldType } from './type-mapper';\n\n/**\n * Extracts the byte size from a fixed-size bytes type (e.g., bytes32 -> 32)\n * @param parameterType - The parameter type (e.g., 'bytes32', 'bytes4', 'bytes')\n * @returns The byte size if fixed-size, undefined if dynamic\n */\nfunction extractBytesSize(parameterType: string): number | undefined {\n const match = parameterType.match(/^bytes(\\d+)$/);\n if (match) {\n return Number.parseInt(match[1], 10);\n }\n return undefined;\n}\n\n/**\n * Extracts the inner type from an EVM array type.\n * @param parameterType - The parameter type (e.g., 'uint32[]', 'address[]')\n * @returns The inner type (e.g., 'uint32', 'address') or null if not an array type\n */\nfunction extractArrayElementType(parameterType: string): string | null {\n // Handle array types like uint32[], address[], bytes32[]\n const arrayMatch = parameterType.match(/^(.+)\\[\\d*\\]$/);\n if (arrayMatch) {\n return arrayMatch[1];\n }\n return null;\n}\n\n/**\n * Get default validation rules for a parameter.\n * Field-specific validation is handled by the field components themselves.\n */\nfunction getDefaultValidation(): FieldValidation {\n return { required: true };\n}\n\n/**\n * EVM numeric type bounds.\n * Maps EVM type names to their min/max value constraints.\n * Note: uint64, uint128, uint256, int64, int128, int256 exceed JavaScript's Number.MAX_SAFE_INTEGER\n * and are handled via BigInt fields, so bounds are not applied here.\n */\nconst EVM_NUMERIC_BOUNDS: NumericBoundsMap = {\n uint: { min: 0 },\n uint8: { min: 0, max: 255 },\n uint16: { min: 0, max: 65_535 },\n uint32: { min: 0, max: 4_294_967_295 },\n int: {},\n int8: { min: -128, max: 127 },\n int16: { min: -32_768, max: 32_767 },\n int32: { min: -2_147_483_648, max: 2_147_483_647 },\n};\n\n/**\n * Generate default field configuration for an EVM function parameter.\n */\nexport function generateEvmDefaultField<T extends FieldType = FieldType>(\n parameter: FunctionParameter\n): FormFieldType<T> {\n const fieldType = mapEvmParamTypeToFieldType(parameter.type) as T;\n\n const baseField: FormFieldType<T> = {\n id: `field-${Math.random().toString(36).substring(2, 9)}`,\n name: parameter.name || parameter.type, // Use type if name missing\n label: startCase(parameter.displayName || parameter.name || parameter.type),\n type: fieldType,\n placeholder: `Enter ${parameter.displayName || parameter.name || parameter.type}`,\n helperText: parameter.description || '',\n defaultValue: getDefaultValueForType(fieldType) as FieldValue<T>,\n validation: enhanceNumericValidation(\n getDefaultValidation(),\n parameter.type,\n EVM_NUMERIC_BOUNDS\n ),\n width: 'full',\n };\n\n // Add exactBytes metadata for fixed-size bytes types (bytes1, bytes4, bytes32, etc.)\n const bytesSize = extractBytesSize(parameter.type);\n if (bytesSize !== undefined) {\n baseField.metadata = {\n ...(baseField.metadata ?? {}),\n exactBytes: bytesSize,\n };\n }\n\n // For array types, provide element type information\n if (fieldType === 'array') {\n const elementType = extractArrayElementType(parameter.type);\n if (elementType) {\n const elementFieldType = mapEvmParamTypeToFieldType(elementType);\n\n // Check if element type is a fixed-size bytes type\n const elementBytesSize = extractBytesSize(elementType);\n\n // Add array-specific properties\n const arrayField = {\n ...baseField,\n elementType: elementFieldType,\n elementFieldConfig: {\n type: elementFieldType,\n validation: enhanceNumericValidation(\n getDefaultValidation(),\n elementType,\n EVM_NUMERIC_BOUNDS\n ),\n placeholder: `Enter ${elementType}`,\n // Include exactBytes metadata for fixed-size bytes array elements (e.g., bytes32[])\n ...(elementBytesSize !== undefined && {\n metadata: { exactBytes: elementBytesSize },\n }),\n },\n };\n return arrayField;\n }\n }\n\n // Preserve components for object and array-object types\n if (parameter.components && (fieldType === 'object' || fieldType === 'array-object')) {\n const result = {\n ...baseField,\n components: parameter.components,\n };\n return result;\n }\n\n return baseField;\n}\n","import { getAddress, isAddress } from 'viem';\n\nimport type { FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Recursively parses a raw input value based on its expected ABI type definition.\n *\n * @param param The ABI parameter definition ({ name, type, components?, ... })\n * @param rawValue The raw value obtained from the form input or hardcoded config.\n * @param isRecursive Internal flag to indicate if the call is nested.\n * @returns The parsed and typed value suitable for ABI encoding.\n * @throws {Error} If parsing or type validation fails.\n */\nexport function parseEvmInput(\n param: FunctionParameter,\n rawValue: unknown,\n isRecursive = false\n): unknown {\n const { type, name } = param;\n const baseType = type.replace(/\\[\\d*\\]$/, ''); // Remove array indicators like `[]` or `[2]`\n const isArray = type.endsWith(']');\n\n try {\n // --- Handle Arrays --- //\n if (isArray) {\n // Only expect string at the top level, recursive calls get arrays directly\n let parsedArray: unknown[];\n if (!isRecursive) {\n if (typeof rawValue !== 'string') {\n throw new Error('Array input must be a JSON string representation.');\n }\n try {\n parsedArray = JSON.parse(rawValue);\n } catch (e) {\n throw new Error(`Invalid JSON for array: ${(e as Error).message}`);\n }\n } else {\n // If recursive, rawValue should already be an array\n if (!Array.isArray(rawValue)) {\n throw new Error('Internal error: Expected array in recursive call.');\n }\n parsedArray = rawValue;\n }\n\n if (!Array.isArray(parsedArray)) {\n // Double check after parsing/assignment\n throw new Error('Parsed JSON is not an array.');\n }\n\n // Recursively parse each element\n const itemAbiParam = { ...param, type: baseType }; // Create a dummy param for the base type\n return parsedArray.map((item) => parseEvmInput(itemAbiParam, item, true)); // Pass isRecursive=true\n }\n\n // --- Handle Tuples --- //\n if (baseType === 'tuple') {\n if (!param.components) {\n throw new Error(`ABI definition missing 'components' for tuple parameter '${name}'.`);\n }\n // Only expect string at the top level, recursive calls get objects directly\n let parsedObject: Record<string, unknown>;\n if (!isRecursive) {\n if (typeof rawValue !== 'string') {\n throw new Error('Tuple input must be a JSON string representation of an object.');\n }\n try {\n parsedObject = JSON.parse(rawValue);\n } catch (e) {\n throw new Error(`Invalid JSON for tuple: ${(e as Error).message}`);\n }\n } else {\n // If recursive, rawValue should already be an object\n if (typeof rawValue !== 'object' || rawValue === null || Array.isArray(rawValue)) {\n throw new Error('Internal error: Expected object in recursive tuple call.');\n }\n parsedObject = rawValue as Record<string, unknown>; // Cast needed\n }\n\n if (\n typeof parsedObject !== 'object' ||\n parsedObject === null ||\n Array.isArray(parsedObject)\n ) {\n // Double check\n throw new Error('Parsed JSON is not an object for tuple.');\n }\n\n // Recursively parse each component\n const resultObject: Record<string, unknown> = {};\n for (const component of param.components) {\n if (!(component.name in parsedObject)) {\n throw new Error(`Missing component '${component.name}' in tuple JSON.`);\n }\n resultObject[component.name] = parseEvmInput(\n component,\n parsedObject[component.name],\n true // Pass isRecursive=true\n );\n }\n // Check for extra, unexpected keys in the provided JSON object\n if (Object.keys(parsedObject).length !== param.components.length) {\n const expectedKeys = param.components.map((c) => c.name).join(', ');\n const actualKeys = Object.keys(parsedObject).join(', ');\n throw new Error(\n `Tuple object has incorrect number of keys. Expected ${param.components.length} (${expectedKeys}), but got ${Object.keys(parsedObject).length} (${actualKeys}).`\n );\n }\n return resultObject;\n }\n\n // --- Handle Bytes --- //\n if (baseType.startsWith('bytes')) {\n if (typeof rawValue !== 'string') {\n throw new Error('Bytes input must be a string.');\n }\n if (!/^0x([0-9a-fA-F]{2})*$/.test(rawValue)) {\n throw new Error(\n `Invalid hex string format for ${type}: must start with 0x and contain only hex characters.`\n );\n }\n // Check byte length for fixed-size bytes? (e.g., bytes32)\n const fixedSizeMatch = baseType.match(/^bytes(\\d+)$/);\n if (fixedSizeMatch) {\n const expectedBytes = parseInt(fixedSizeMatch[1], 10);\n const actualBytes = (rawValue.length - 2) / 2;\n if (actualBytes !== expectedBytes) {\n throw new Error(\n `Invalid length for ${type}: expected ${expectedBytes} bytes (${expectedBytes * 2} hex chars), got ${actualBytes} bytes.`\n );\n }\n }\n return rawValue as `0x${string}`; // Already validated, cast to viem type\n }\n\n // --- Handle Simple Types --- //\n if (baseType.startsWith('uint') || baseType.startsWith('int')) {\n if (rawValue === '' || rawValue === null || rawValue === undefined)\n throw new Error('Numeric value cannot be empty.');\n try {\n // Use BigInt for all integer types\n return BigInt(rawValue as string | number | bigint);\n } catch {\n throw new Error(`Invalid numeric value: '${rawValue}'.`);\n }\n } else if (baseType === 'address') {\n if (typeof rawValue !== 'string' || !rawValue)\n throw new Error('Address value must be a non-empty string.');\n if (!isAddress(rawValue)) throw new Error(`Invalid address format: '${rawValue}'.`);\n return getAddress(rawValue); // Return checksummed address\n } else if (baseType === 'bool') {\n if (typeof rawValue === 'boolean') return rawValue;\n if (typeof rawValue === 'string') {\n const lowerVal = rawValue.toLowerCase().trim();\n if (lowerVal === 'true') return true;\n if (lowerVal === 'false') return false;\n }\n // Try simple truthy/falsy conversion as fallback\n return Boolean(rawValue);\n } else if (baseType === 'string') {\n // Ensure it's treated as a string\n return String(rawValue);\n }\n\n // --- Fallback for unknown types --- //\n logger.warn(\n 'parseEvmInput',\n `Unknown EVM parameter type encountered: '${type}'. Using raw value.`\n );\n return rawValue;\n } catch (error) {\n // Add parameter context to the error message\n throw new Error(\n `Failed to parse value for parameter '${name || '(unnamed)'}' (type '${type}'): ${(error as Error).message}`\n );\n }\n}\n","import type { ContractFunction } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { stringifyWithBigInt } from '../utils';\n\n/**\n * Formats the decoded result of an EVM view function call into a user-friendly string.\n *\n * @param decodedValue The decoded value (can be primitive, array, object, BigInt).\n * @param functionDetails The ABI details of the function called.\n * @returns A string representation suitable for display.\n */\nexport function formatEvmFunctionResult(\n decodedValue: unknown,\n functionDetails: ContractFunction\n): string {\n if (!functionDetails.outputs || !Array.isArray(functionDetails.outputs)) {\n logger.warn(\n 'formatEvmFunctionResult',\n `Output ABI definition missing or invalid for function ${functionDetails.name}.`\n );\n return '[Error: Output ABI definition missing]';\n }\n\n try {\n let valueToFormat: unknown;\n // Handle potential array wrapping for single returns from viem\n if (Array.isArray(decodedValue)) {\n if (decodedValue.length === 1) {\n valueToFormat = decodedValue[0]; // Single output, format the inner value\n } else {\n // Multiple outputs, format the whole array as JSON\n valueToFormat = decodedValue;\n }\n } else {\n // Not an array, could be a single value (like from a struct return) or undefined\n valueToFormat = decodedValue;\n }\n\n // Format based on type\n if (typeof valueToFormat === 'bigint') {\n return valueToFormat.toString();\n } else if (\n typeof valueToFormat === 'string' ||\n typeof valueToFormat === 'number' ||\n typeof valueToFormat === 'boolean'\n ) {\n return String(valueToFormat);\n } else if (valueToFormat === null || valueToFormat === undefined) {\n return '(null)'; // Represent null/undefined clearly\n } else {\n // Handles arrays with multiple elements or objects (structs) by stringifying\n return stringifyWithBigInt(valueToFormat, 2); // Pretty print with 2 spaces\n }\n } catch (error) {\n const errorMessage = `Error formatting result for ${functionDetails.name}: ${(error as Error).message}`;\n logger.error('formatEvmFunctionResult', errorMessage, {\n functionName: functionDetails.name,\n decodedValue,\n error,\n });\n return `[${errorMessage}]`;\n }\n}\n","import { isAddress } from 'viem';\n\nimport type { ContractSchema, FunctionParameter } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createAbiFunctionItem } from '../abi/transformer';\nimport { parseEvmInput } from '../transform/input-parser';\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\nimport { createEvmPublicClient } from '../utils/public-client';\nimport { isEvmViewFunction } from './view-checker';\n\n/**\n * Core logic for querying an EVM view function.\n * This is a stateless version that accepts an RPC URL directly.\n *\n * @param contractAddress - Address of the contract.\n * @param functionId - ID of the function to query.\n * @param params - Raw parameters for the function call.\n * @param schema - Contract schema with function definitions.\n * @param rpcUrl - RPC URL to use for the query.\n * @param networkConfig - Optional EVM-compatible network configuration for chain metadata (works with any ecosystem).\n * @returns The decoded result of the view function call.\n */\nexport async function queryEvmViewFunction(\n contractAddress: string,\n functionId: string,\n params: unknown[],\n schema: ContractSchema,\n rpcUrl: string,\n networkConfig?: EvmCompatibleNetworkConfig\n): Promise<unknown> {\n logger.info(\n 'queryEvmViewFunction',\n `Querying view function: ${functionId} on ${contractAddress}`,\n { params }\n );\n\n try {\n // --- Validate Address --- //\n if (!contractAddress || !isAddress(contractAddress)) {\n throw new Error(`Invalid contract address provided: ${contractAddress}`);\n }\n\n // --- Get Function Details --- //\n const functionDetails = schema.functions.find((fn) => fn.id === functionId);\n if (!functionDetails) {\n throw new Error(`Function with ID ${functionId} not found in contract schema.`);\n }\n if (!isEvmViewFunction(functionDetails)) {\n throw new Error(`Function ${functionDetails.name} is not a view function.`);\n }\n\n // --- Parse Input Parameters --- //\n const expectedInputs: readonly FunctionParameter[] = functionDetails.inputs;\n if (params.length !== expectedInputs.length) {\n throw new Error(\n `Incorrect number of parameters provided for ${functionDetails.name}. Expected ${expectedInputs.length}, got ${params.length}.`\n );\n }\n const args = expectedInputs.map((inputParam: FunctionParameter, index: number) => {\n let rawValue = params[index];\n // If the ABI parameter type is an array and the incoming raw value is an actual array,\n // stringify it to align with parseEvmInput expectations for top-level arrays.\n if (\n typeof inputParam.type === 'string' &&\n inputParam.type.endsWith('[]') &&\n Array.isArray(rawValue)\n ) {\n rawValue = JSON.stringify(rawValue);\n }\n return parseEvmInput(inputParam, rawValue, false);\n });\n logger.debug('queryEvmViewFunction', 'Parsed Args for readContract:', args);\n\n // --- Create Public Client --- //\n const publicClient = createEvmPublicClient(rpcUrl, networkConfig?.viemChain);\n\n // --- Construct ABI Item --- //\n const functionAbiItem = createAbiFunctionItem(functionDetails);\n\n logger.debug(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] Calling readContract with ABI:`,\n functionAbiItem,\n 'Args:',\n args\n );\n\n // --- Call readContract --- //\n let decodedResult: unknown;\n try {\n decodedResult = await publicClient.readContract({\n address: contractAddress as `0x${string}`,\n abi: [functionAbiItem],\n functionName: functionDetails.name,\n args: args,\n });\n } catch (readError) {\n logger.error(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] publicClient.readContract specific error:`,\n readError\n );\n throw new Error(\n `Viem readContract failed for ${functionDetails.name}: ${(readError as Error).message}`\n );\n }\n\n logger.debug(\n 'queryEvmViewFunction',\n `[Query ${functionDetails.name}] Raw decoded result:`,\n decodedResult\n );\n\n return decodedResult;\n } catch (error) {\n const errorMessage = `Failed to query view function ${functionId}: ${(error as Error).message}`;\n logger.error('queryEvmViewFunction', errorMessage, {\n contractAddress,\n functionId,\n params,\n error,\n });\n throw new Error(errorMessage);\n }\n}\n","import type { ContractFunction } from '@openzeppelin/ui-types';\n\n/**\n * Determines if a function is a view/pure function (read-only).\n * @param functionDetails The function details from the contract schema.\n * @returns True if the function is read-only, false otherwise.\n */\nexport function isEvmViewFunction(functionDetails: ContractFunction): boolean {\n return functionDetails.stateMutability === 'view' || functionDetails.stateMutability === 'pure';\n}\n","import { isAddress } from 'viem';\n\nimport type { ContractSchema, FormFieldType } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createAbiFunctionItem } from '../abi/transformer';\nimport { parseEvmInput } from '../transform/input-parser';\nimport type { WriteContractParameters } from '../types/abi';\n\n/**\n * Formats transaction data for EVM chains based on parsed inputs.\n *\n * @param contractSchema The contract schema.\n * @param functionId The ID of the function being called.\n * @param submittedInputs The raw data submitted from the form.\n * @param fields The fields of the form schema.\n * @returns The formatted data payload suitable for signAndBroadcast.\n */\nexport function formatEvmTransactionData(\n contractSchema: ContractSchema,\n functionId: string,\n submittedInputs: Record<string, unknown>,\n fields: FormFieldType[]\n): WriteContractParameters {\n logger.info(\n 'formatEvmTransactionData',\n `Formatting EVM transaction data for function: ${functionId}`\n );\n\n // --- Step 1: Determine Argument Order --- //\n const functionDetails = contractSchema.functions.find((fn) => fn.id === functionId);\n if (!functionDetails) {\n throw new Error(`Function definition for ${functionId} not found in provided contract schema.`);\n }\n const expectedArgs = functionDetails.inputs;\n\n // --- Step 2: Iterate and Select Values --- //\n const orderedRawValues: unknown[] = [];\n for (const expectedArg of expectedArgs) {\n const fieldConfig = fields.find((field: FormFieldType) => field.name === expectedArg.name);\n if (!fieldConfig) {\n throw new Error(`Configuration missing for argument: ${expectedArg.name} in provided fields`);\n }\n let value: unknown;\n if (fieldConfig.isHardcoded) {\n value = fieldConfig.hardcodedValue;\n } else if (fieldConfig.isHidden) {\n throw new Error(`Field '${fieldConfig.name}' cannot be hidden without being hardcoded.`);\n } else {\n if (!(fieldConfig.name in submittedInputs)) {\n throw new Error(`Missing submitted input for required field: ${fieldConfig.name}`);\n }\n value = submittedInputs[fieldConfig.name];\n }\n orderedRawValues.push(value);\n }\n\n // --- Step 3: Parse/Transform Values using the imported parser --- //\n const transformedArgs = expectedArgs.map((param, index) => {\n let valueToParse = orderedRawValues[index];\n\n // If the ABI parameter type is an array (e.g., 'tuple[]', 'address[]') and\n // the raw value from the form/runtime is an array (not already a string),\n // stringify it for parseEvmInput which expects JSON at the top-level.\n if (\n typeof param.type === 'string' &&\n param.type.endsWith('[]') &&\n Array.isArray(valueToParse)\n ) {\n valueToParse = JSON.stringify(valueToParse);\n }\n\n return parseEvmInput(param, valueToParse, false);\n });\n\n // --- Step 4 & 5: Prepare Return Object --- //\n const isPayable = functionDetails.stateMutability === 'payable';\n let transactionValue = 0n; // Use BigInt zero\n if (isPayable) {\n logger.warn(\n 'formatEvmTransactionData',\n 'Payable function detected, but sending 0 ETH. Implement value input.'\n );\n // TODO: Read value from submittedInputs or config when payable input is implemented\n }\n\n const functionAbiItem = createAbiFunctionItem(functionDetails);\n\n if (!contractSchema.address || !isAddress(contractSchema.address)) {\n throw new Error('Contract address is missing or invalid in the provided schema.');\n }\n\n const paramsForSignAndBroadcast: WriteContractParameters = {\n address: contractSchema.address,\n abi: [functionAbiItem],\n functionName: functionDetails.name,\n args: transformedArgs,\n value: transactionValue, // Pass BigInt value\n };\n return paramsForSignAndBroadcast;\n}\n","/**\n * Transaction Module\n *\n * Transaction formatting, execution strategies, and transaction sending for EVM contracts.\n * This module structure mirrors the adapter-evm transaction/ directory.\n *\n * @module transaction\n */\n\n// Formatting\nexport { formatEvmTransactionData } from './formatter';\n\n// Execution strategy interface\nexport type { AdapterExecutionStrategy } from './execution-strategy';\n\n// Execution strategies\nexport { EoaExecutionStrategy } from './eoa';\nexport { RelayerExecutionStrategy, type EvmRelayerTransactionOptions } from './relayer';\n\n// Transaction sending and execution\nexport {\n executeEvmTransaction,\n signAndBroadcastEvmTransaction,\n waitForEvmTransactionConfirmation,\n} from './sender';\n\n// Types\nexport type {\n EvmWalletImplementation,\n EvmWalletConnectionStatus,\n EvmWalletConnectionResult,\n EvmWalletDisconnectResult,\n} from './types';\n","/**\n * Transaction Sender\n *\n * Core functions for signing and broadcasting EVM transactions.\n * These functions work with any wallet implementation that implements EvmWalletImplementation.\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\nimport type { TransactionReceipt, WalletClient } from 'viem';\n\nimport type { ExecutionConfig, TransactionStatusUpdate, TxStatus } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WriteContractParameters } from '../types/abi';\nimport type { AdapterExecutionStrategy } from './execution-strategy';\nimport type { EvmWalletImplementation } from './types';\n\nconst SYSTEM_LOG_TAG = 'evm-core-sender';\n\n// --- Helper Functions ---\n\nasync function _ensureCorrectNetworkOrSwitch(\n walletImplementation: EvmWalletImplementation,\n targetChainId: number\n): Promise<GetAccountReturnType> {\n const initialAccountStatus = walletImplementation.getWalletConnectionStatus();\n if (!initialAccountStatus.isConnected || !initialAccountStatus.chainId) {\n logger.error(\n SYSTEM_LOG_TAG,\n 'Wallet not connected or chainId unavailable before network check.'\n );\n throw new Error('Wallet not connected or chain ID is unavailable.');\n }\n\n if (initialAccountStatus.chainId !== targetChainId) {\n logger.info(\n SYSTEM_LOG_TAG,\n `Wallet on chain ${initialAccountStatus.chainId}, target ${targetChainId}. Switching...`\n );\n try {\n await walletImplementation.switchNetwork(targetChainId);\n const postSwitchAccountStatus = walletImplementation.getWalletConnectionStatus();\n if (postSwitchAccountStatus.chainId !== targetChainId) {\n logger.error(\n SYSTEM_LOG_TAG,\n `Failed to switch to target chain ${targetChainId}. Current: ${postSwitchAccountStatus.chainId}`\n );\n throw new Error(`Failed to switch to the required network (target: ${targetChainId}).`);\n }\n logger.info(SYSTEM_LOG_TAG, `Successfully switched to target chain ${targetChainId}.`);\n return postSwitchAccountStatus;\n } catch (error) {\n logger.error(SYSTEM_LOG_TAG, 'Network switch failed:', error);\n throw error;\n }\n }\n logger.info(SYSTEM_LOG_TAG, 'Wallet already on target chain.');\n return initialAccountStatus;\n}\n\nasync function _getAuthenticatedWalletClient(\n walletImplementation: EvmWalletImplementation\n): Promise<{\n walletClient: WalletClient;\n accountStatus: GetAccountReturnType;\n}> {\n const walletClient = await walletImplementation.getWalletClient();\n if (!walletClient) {\n logger.error(SYSTEM_LOG_TAG, 'Wallet client not available. Is wallet connected?');\n throw new Error('Wallet is not connected or client is unavailable.');\n }\n\n const accountStatus = walletImplementation.getWalletConnectionStatus();\n if (!accountStatus.isConnected || !accountStatus.address) {\n logger.error(SYSTEM_LOG_TAG, 'Account not available. Is wallet connected?');\n throw new Error('Wallet is not connected or account address is unavailable.');\n }\n return { walletClient, accountStatus };\n}\n\nasync function _executeEoaTransaction(\n transactionData: WriteContractParameters,\n walletClient: WalletClient,\n accountStatus: GetAccountReturnType\n): Promise<{ txHash: string }> {\n logger.info(SYSTEM_LOG_TAG, 'Using EOA execution strategy.');\n try {\n logger.debug(SYSTEM_LOG_TAG, 'Calling walletClient.writeContract with:', {\n account: accountStatus.address,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n const hash = await walletClient.writeContract({\n account: accountStatus.address!,\n address: transactionData.address,\n abi: transactionData.abi,\n functionName: transactionData.functionName,\n args: transactionData.args,\n value: transactionData.value,\n chain: walletClient.chain,\n });\n logger.info(SYSTEM_LOG_TAG, 'EOA Transaction initiated. Hash:', hash);\n return { txHash: hash };\n } catch (error: unknown) {\n logger.error(SYSTEM_LOG_TAG, 'Error during EOA writeContract call:', error);\n const errorMessage = error instanceof Error ? error.message : 'Unknown EOA transaction error';\n throw new Error(`Transaction failed (EOA): ${errorMessage}`);\n }\n}\n\n// --- Main Exported Functions ---\n\n/**\n * Sign and broadcast an EVM transaction using the provided wallet implementation.\n *\n * This function handles:\n * - Network switching (if wallet is on wrong chain)\n * - Transaction signing via the wallet\n * - Transaction broadcasting\n *\n * @param transactionData - The contract write parameters\n * @param walletImplementation - The wallet implementation to use for signing\n * @param targetChainId - The chain ID to execute the transaction on\n * @param executionConfig - Optional execution configuration (for future method support)\n * @returns The transaction hash\n */\nexport async function signAndBroadcastEvmTransaction(\n transactionData: WriteContractParameters,\n walletImplementation: EvmWalletImplementation,\n targetChainId: number,\n executionConfig?: ExecutionConfig\n): Promise<{ txHash: string }> {\n logger.info(SYSTEM_LOG_TAG, 'Sign & Broadcast EVM Tx:', {\n data: transactionData,\n targetChainId,\n execConfig: executionConfig,\n });\n\n const currentMethod = executionConfig?.method || 'eoa';\n\n await _ensureCorrectNetworkOrSwitch(walletImplementation, targetChainId);\n const { walletClient, accountStatus } = await _getAuthenticatedWalletClient(walletImplementation);\n\n switch (currentMethod) {\n case 'eoa':\n return _executeEoaTransaction(transactionData, walletClient, accountStatus);\n\n case 'relayer':\n // Relayer execution is handled by RelayerExecutionStrategy in adapter-evm\n // This function is for direct EOA execution\n logger.warn(SYSTEM_LOG_TAG, 'Relayer method should use RelayerExecutionStrategy directly.');\n throw new Error('Use RelayerExecutionStrategy for relayer execution.');\n\n case 'multisig':\n logger.warn(SYSTEM_LOG_TAG, 'Multisig execution method not yet implemented.');\n throw new Error('Multisig execution method not yet implemented.');\n\n default:\n const exhaustiveCheck: never = currentMethod;\n logger.error(SYSTEM_LOG_TAG, `Unsupported execution method encountered: ${exhaustiveCheck}`);\n throw new Error(`Unsupported execution method: ${exhaustiveCheck}`);\n }\n}\n\n/**\n * Sign and broadcast a transaction using the appropriate execution strategy.\n * This is a high-level router function that selects EOA or Relayer strategy\n * based on the execution configuration.\n *\n * @param transactionData - The contract write parameters\n * @param executionConfig - The execution configuration specifying method (eoa, relayer, multisig)\n * @param walletImplementation - The wallet implementation to use for signing\n * @param onStatusChange - Callback for status updates during transaction lifecycle\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns The transaction hash\n */\nexport async function executeEvmTransaction(\n transactionData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n walletImplementation: EvmWalletImplementation,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n): Promise<{ txHash: string }> {\n const method = executionConfig.method || 'eoa';\n\n logger.info(SYSTEM_LOG_TAG, 'executeEvmTransaction: Starting transaction execution', { method });\n\n // Import strategies dynamically to avoid circular dependencies\n const { EoaExecutionStrategy } = await import('./eoa');\n const { RelayerExecutionStrategy } = await import('./relayer');\n\n let strategy: AdapterExecutionStrategy;\n\n switch (method) {\n case 'eoa':\n strategy = new EoaExecutionStrategy();\n break;\n\n case 'relayer':\n strategy = new RelayerExecutionStrategy();\n break;\n\n case 'multisig':\n logger.warn(SYSTEM_LOG_TAG, 'Multisig execution not yet implemented');\n throw new Error('Multisig execution is not yet supported.');\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported execution method: ${exhaustiveCheck}`);\n }\n }\n\n return strategy.execute(\n transactionData,\n executionConfig,\n walletImplementation,\n onStatusChange,\n runtimeApiKey\n );\n}\n\n/**\n * Waits for a transaction to be confirmed on the blockchain.\n *\n * @param txHash - The transaction hash to wait for\n * @param walletImplementation - The wallet implementation to get the public client from\n * @returns The transaction status and receipt\n */\nexport async function waitForEvmTransactionConfirmation(\n txHash: string,\n walletImplementation: EvmWalletImplementation\n): Promise<{\n status: 'success' | 'error';\n receipt?: TransactionReceipt;\n error?: Error;\n}> {\n logger.info(SYSTEM_LOG_TAG, `Waiting for tx: ${txHash}`);\n try {\n // Get the public client\n const resolvedPublicClient = await walletImplementation.getPublicClient();\n if (!resolvedPublicClient) {\n throw new Error('Public client not available to wait for transaction.');\n }\n\n // Wait for the transaction receipt\n const receipt = await resolvedPublicClient.waitForTransactionReceipt({\n hash: txHash as `0x${string}`,\n });\n\n logger.info(SYSTEM_LOG_TAG, 'Received receipt:', receipt);\n\n // Check the status field in the receipt\n if (receipt.status === 'success') {\n return { status: 'success', receipt };\n } else {\n logger.error(SYSTEM_LOG_TAG, 'Transaction reverted:', receipt);\n return { status: 'error', receipt, error: new Error('Transaction reverted.') };\n }\n } catch (error) {\n logger.error(SYSTEM_LOG_TAG, 'Error waiting for transaction confirmation:', error);\n return {\n status: 'error',\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n","import { createContext } from 'react';\n\n/**\n * Context to track Wagmi provider initialization status\n * Used by components to safely render when the provider is ready\n */\nexport const WagmiProviderInitializedContext = createContext<boolean>(false);\n","import { useContext } from 'react';\n\nimport { WagmiProviderInitializedContext } from '../context/wagmi-context';\n\n/**\n * Hook to check if WagmiProvider is ready\n * @returns boolean indicating if the provider is initialized\n */\nexport const useIsWagmiProviderInitialized = (): boolean => {\n return useContext(WagmiProviderInitializedContext);\n};\n","import React, { useEffect, useState } from 'react';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { useIsWagmiProviderInitialized } from '../hooks/useIsWagmiProviderInitialized';\n\n/**\n * A wrapper component that safely renders children that use wagmi hooks.\n * It handles errors and provider initialization state to prevent crashes.\n */\nexport const SafeWagmiComponent = ({\n children,\n fallback = null,\n}: {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n}) => {\n const isProviderInitialized = useIsWagmiProviderInitialized();\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n // Reset error state if provider initializes\n if (isProviderInitialized) {\n setHasError(false);\n }\n }, [isProviderInitialized]);\n\n // Setup global error handler for wagmi errors\n useEffect(() => {\n const handleError = (event: ErrorEvent) => {\n // Only handle wagmi-related errors\n if (\n event.error?.message?.includes('useConfig') ||\n event.error?.message?.includes('WagmiProvider')\n ) {\n logger.debug(\n 'SafeWagmiComponent',\n 'Caught wagmi error via window error event:',\n event.error\n );\n setHasError(true);\n event.preventDefault(); // Prevent the error from propagating\n }\n };\n\n window.addEventListener('error', handleError);\n return () => {\n window.removeEventListener('error', handleError);\n };\n }, []);\n\n // If provider isn't ready yet or we had an error, show fallback\n if (!isProviderInitialized || hasError) {\n return <>{fallback}</>;\n }\n\n try {\n return <>{children}</>;\n } catch (error) {\n // Only catch render errors related to wagmi hooks\n if (\n error instanceof Error &&\n (error.message.includes('useConfig') || error.message.includes('WagmiProvider'))\n ) {\n logger.debug('SafeWagmiComponent', 'Caught wagmi error:', error);\n setHasError(true);\n return <>{fallback}</>;\n }\n // Re-throw other errors\n throw error;\n }\n};\n","import { Loader2, Wallet } from 'lucide-react';\nimport React, { useEffect, useState } from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedConnectStatus } from '@openzeppelin/ui-react';\nimport type { BaseComponentProps, WalletComponentSize } from '@openzeppelin/ui-types';\nimport { cn, getWalletButtonSizeProps } from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\nimport { ConnectorDialog } from './ConnectorDialog';\n\n/**\n * A button that allows users to connect their wallet.\n * Opens a dialog to select from available connectors.\n * @param hideWhenConnected - Whether to hide the button when wallet is connected (default: true)\n * @param showInjectedConnector - Whether to show the injected connector in the dialog (default: false)\n */\nexport interface ConnectButtonProps extends BaseComponentProps {\n hideWhenConnected?: boolean;\n showInjectedConnector?: boolean;\n}\n\nexport const CustomConnectButton: React.FC<ConnectButtonProps> = ({\n className,\n size,\n variant,\n fullWidth,\n hideWhenConnected = true,\n showInjectedConnector = false,\n}) => {\n const [dialogOpen, setDialogOpen] = useState(false);\n const sizeProps = getWalletButtonSizeProps(size);\n\n const unavailableButton = (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Button\n disabled={true}\n variant={variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, fullWidth && 'w-full')}\n >\n <Wallet className={cn(sizeProps.iconSize, 'mr-1')} />\n Wallet Unavailable\n </Button>\n </div>\n );\n\n return (\n <SafeWagmiComponent fallback={unavailableButton}>\n <ConnectButtonContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n dialogOpen={dialogOpen}\n setDialogOpen={setDialogOpen}\n hideWhenConnected={hideWhenConnected}\n showInjectedConnector={showInjectedConnector}\n />\n </SafeWagmiComponent>\n );\n};\n\nconst ConnectButtonContent: React.FC<{\n className?: string;\n size?: WalletComponentSize;\n variant?: BaseComponentProps['variant'];\n fullWidth?: boolean;\n dialogOpen: boolean;\n setDialogOpen: (open: boolean) => void;\n hideWhenConnected: boolean;\n showInjectedConnector: boolean;\n}> = ({\n className,\n size,\n variant,\n fullWidth,\n dialogOpen,\n setDialogOpen,\n hideWhenConnected,\n showInjectedConnector,\n}) => {\n const { isConnected } = useDerivedAccountStatus();\n const { isConnecting: isHookConnecting, error: connectError } = useDerivedConnectStatus();\n\n // Local state to indicate the button has been clicked and dialog is open, awaiting user selection\n const [isManuallyInitiated, setIsManuallyInitiated] = useState(false);\n\n const sizeProps = getWalletButtonSizeProps(size);\n\n useEffect(() => {\n if (isConnected && hideWhenConnected) {\n setDialogOpen(false);\n setIsManuallyInitiated(false); // Reset if dialog closes due to connection\n }\n }, [isConnected, hideWhenConnected, setDialogOpen]);\n\n // If dialog is closed, reset manual initiation state\n useEffect(() => {\n if (!dialogOpen) {\n setIsManuallyInitiated(false);\n }\n }, [dialogOpen]);\n\n // If wagmi hook reports it's connecting, we no longer need our manual pending state\n useEffect(() => {\n if (isHookConnecting) {\n setIsManuallyInitiated(false);\n }\n }, [isHookConnecting]);\n\n const handleConnectClick = () => {\n if (!isConnected) {\n setIsManuallyInitiated(true); // User clicked, show pending on button\n setDialogOpen(true);\n }\n };\n\n if (isConnected && hideWhenConnected) {\n return null;\n }\n\n // Button shows loading if either hook reports connecting OR if user just clicked to open dialog\n const showButtonLoading = isHookConnecting || isManuallyInitiated;\n\n return (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Button\n onClick={handleConnectClick}\n disabled={showButtonLoading || isConnected}\n variant={variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, fullWidth && 'w-full')}\n title={isConnected ? 'Connected' : connectError?.message || 'Connect Wallet'}\n >\n {showButtonLoading ? (\n <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1')} />\n ) : (\n <Wallet className={cn(sizeProps.iconSize, 'mr-1')} />\n )}\n {showButtonLoading ? 'Connecting...' : 'Connect Wallet'}\n </Button>\n\n <ConnectorDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n setDialogOpen(open);\n // If dialog is closed manually by user before selection, reset manual initiation\n if (!open) {\n setIsManuallyInitiated(false);\n }\n }}\n showInjectedConnector={showInjectedConnector}\n />\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\n\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedConnectStatus } from '@openzeppelin/ui-react';\nimport type { Connector } from '@openzeppelin/ui-types';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * Dialog component for selecting a wallet connector\n * @param showInjectedConnector - Whether to show the injected connector (default: false)\n */\ninterface ConnectorDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n showInjectedConnector?: boolean;\n}\n\nexport const ConnectorDialog: React.FC<ConnectorDialogProps> = ({\n open,\n onOpenChange,\n showInjectedConnector = false,\n}) => {\n // Prepare fallback dialog content\n const unavailableContent = (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Wallet Connection Unavailable</DialogTitle>\n <DialogDescription>\n The wallet connection system is not properly initialized.\n </DialogDescription>\n </DialogHeader>\n </DialogContent>\n </Dialog>\n );\n\n // Only render wagmi-dependent part when provider is initialized\n return (\n <SafeWagmiComponent fallback={unavailableContent}>\n <ConnectorDialogContent\n open={open}\n onOpenChange={onOpenChange}\n showInjectedConnector={showInjectedConnector}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner content that uses wagmi hooks\nconst ConnectorDialogContent: React.FC<ConnectorDialogProps> = ({\n open,\n onOpenChange,\n showInjectedConnector = false,\n}) => {\n const { connect, connectors, error: connectError, isConnecting } = useDerivedConnectStatus();\n const { isConnected } = useDerivedAccountStatus();\n const [connectingId, setConnectingId] = useState<string | null>(null);\n\n // Track connection attempts for dialog closure\n useEffect(() => {\n // If we're connected and there was a connection attempt, close the dialog\n if (isConnected && connectingId) {\n onOpenChange(false);\n setConnectingId(null);\n }\n }, [isConnected, connectingId, onOpenChange]);\n\n // If connect function itself is not available (e.g., adapter doesn't provide useConnect facade hook)\n if (!connect) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Error</DialogTitle>\n </DialogHeader>\n <p>Wallet connection function is not available.</p>\n </DialogContent>\n </Dialog>\n );\n }\n\n const handleConnectorSelect = (selectedConnector: Connector) => {\n setConnectingId(selectedConnector.id);\n connect({ connector: selectedConnector });\n };\n\n // Filter out the injected connector if showInjectedConnector is false\n const filteredConnectors = connectors.filter((connector: Connector) => {\n const isInjected = connector.id === 'injected';\n return !(isInjected && !showInjectedConnector);\n });\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Connect Wallet</DialogTitle>\n <DialogDescription>\n Select a wallet provider to connect with this application.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"grid gap-4 py-4\">\n {filteredConnectors.length === 0 ? (\n <p className=\"text-center text-muted-foreground\">No wallet connectors available.</p>\n ) : (\n filteredConnectors.map((connector: Connector) => (\n <Button\n key={connector.id}\n onClick={() => handleConnectorSelect(connector)}\n disabled={isConnecting && connectingId === connector.id}\n variant=\"outline\"\n className=\"flex justify-between items-center w-full py-6\"\n >\n <span>{connector.name}</span>\n {isConnecting && connectingId === connector.id && (\n <span className=\"ml-2 text-xs\">Connecting...</span>\n )}\n </Button>\n ))\n )}\n </div>\n\n {connectError && (\n <p className=\"text-sm text-red-500 mt-1\">\n {connectError.message || 'Error connecting wallet'}\n </p>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n","import { LogOut } from 'lucide-react';\nimport React from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport { useDerivedAccountStatus, useDerivedDisconnect } from '@openzeppelin/ui-react';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport { cn, getWalletAccountDisplaySizeProps, truncateMiddle } from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * A component that displays the connected account address and chain ID.\n * Also includes a disconnect button.\n */\nexport const CustomAccountDisplay: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n // Use the SafeWagmiComponent with null fallback\n return (\n <SafeWagmiComponent fallback={null}>\n <AccountDisplayContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner component that uses derived hooks\nconst AccountDisplayContent: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n const { isConnected, address, chainId } = useDerivedAccountStatus();\n const { disconnect } = useDerivedDisconnect();\n\n const sizeProps = getWalletAccountDisplaySizeProps(size);\n\n if (!isConnected || !address || !disconnect) {\n return null;\n }\n\n return (\n <div className={cn('flex items-center gap-2', fullWidth && 'w-full', className)}>\n <div className={cn('flex flex-col', fullWidth && 'flex-1')}>\n <span className={cn(sizeProps.textSize, 'font-medium')}>\n {truncateMiddle(address, 4, 4)}\n </span>\n <span className={cn(sizeProps.subTextSize, 'text-muted-foreground -mt-0.5')}>\n {chainId ? `Chain ID: ${chainId}` : 'Chain ID: N/A'}\n </span>\n </div>\n <Button\n onClick={() => disconnect()}\n variant={variant || 'ghost'}\n size=\"icon\"\n className={cn(sizeProps.iconButtonSize, 'p-0')}\n title=\"Disconnect wallet\"\n >\n <LogOut className={sizeProps.iconSize} />\n </Button>\n </div>\n );\n};\n","import { Loader2 } from 'lucide-react';\nimport type { Chain } from 'viem';\nimport React from 'react';\n\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@openzeppelin/ui-components';\nimport {\n useDerivedAccountStatus,\n useDerivedChainInfo,\n useDerivedSwitchChainStatus,\n} from '@openzeppelin/ui-react';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport {\n cn,\n getWalletNetworkSwitcherSizeProps,\n getWalletNetworkSwitcherVariantClassName,\n} from '@openzeppelin/ui-utils';\n\nimport { SafeWagmiComponent } from '../SafeWagmiComponent';\n\n/**\n * A component that displays the current network and allows switching to other networks.\n * Uses the chainId and switchChain hooks.\n */\nexport const CustomNetworkSwitcher: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n // Use the SafeWagmiComponent with null fallback\n return (\n <SafeWagmiComponent fallback={null}>\n <NetworkSwitcherContent\n className={className}\n size={size}\n variant={variant}\n fullWidth={fullWidth}\n />\n </SafeWagmiComponent>\n );\n};\n\n// Inner component that uses wagmi hooks\nconst NetworkSwitcherContent: React.FC<BaseComponentProps> = ({\n className,\n size,\n variant,\n fullWidth,\n}) => {\n const { isConnected } = useDerivedAccountStatus();\n const { currentChainId, availableChains: unknownChains } = useDerivedChainInfo();\n const { switchChain, isSwitching: isPending, error } = useDerivedSwitchChainStatus();\n\n const sizeProps = getWalletNetworkSwitcherSizeProps(size);\n const variantClassName = getWalletNetworkSwitcherVariantClassName(variant);\n\n // Cast to Chain[] for use within this component\n const typedAvailableChains = unknownChains as Chain[];\n\n if (!isConnected || !switchChain || typedAvailableChains.length === 0) {\n return null;\n }\n\n const handleNetworkChange = (chainId: number) => {\n if (chainId !== currentChainId) {\n switchChain({ chainId });\n }\n };\n\n const currentChain = typedAvailableChains.find((chain) => chain.id === currentChainId);\n const currentChainName = currentChain?.name || 'Network';\n\n return (\n <div className={cn('flex items-center', fullWidth && 'w-full', className)}>\n <Select\n value={currentChainId?.toString() ?? ''}\n onValueChange={(value: string) => handleNetworkChange(Number(value))}\n disabled={isPending || typedAvailableChains.length === 0}\n >\n <SelectTrigger\n className={cn(\n sizeProps.triggerClassName,\n variantClassName,\n fullWidth && 'w-full max-w-none'\n )}\n >\n <SelectValue placeholder=\"Network\">{currentChainName}</SelectValue>\n </SelectTrigger>\n <SelectContent\n position=\"popper\"\n sideOffset={5}\n align=\"start\"\n className=\"w-auto min-w-[160px] max-h-[300px]\"\n >\n {typedAvailableChains.map((chain) => (\n <SelectItem\n key={chain.id}\n value={chain.id.toString()}\n className={sizeProps.itemClassName}\n >\n {chain.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {isPending && (\n <span className=\"text-muted-foreground ml-2\">\n <Loader2 className={cn(sizeProps.loaderSize, 'animate-spin')} />\n </span>\n )}\n\n {error && <span className=\"text-xs text-red-500 ml-2\">!</span>}\n </div>\n );\n};\n","/**\n * Core Wallet Connection Utilities\n *\n * Provides shared wallet connection logic for EVM-compatible adapters.\n * Both adapter-evm and adapter-polkadot can use these core utilities.\n *\n * @module wallet/connection\n */\n\nimport type { GetAccountReturnType } from '@wagmi/core';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { EvmWalletConnectionResult, EvmWalletImplementation } from '../transaction/types';\n\n/**\n * Default wallet connection status when disconnected.\n * Use this constant when the wallet implementation is not ready or available.\n */\nexport const DEFAULT_DISCONNECTED_STATUS: GetAccountReturnType = {\n isConnected: false,\n isConnecting: false,\n isDisconnected: true,\n isReconnecting: false,\n status: 'disconnected',\n address: undefined,\n addresses: undefined,\n chainId: undefined,\n chain: undefined,\n connector: undefined,\n};\n\n/**\n * Core implementation of connect and ensure correct network logic.\n *\n * This function handles the common pattern of:\n * 1. Connect to wallet using the specified connector\n * 2. Check if connected to the target chain\n * 3. If not, attempt to switch networks\n * 4. If switch fails, disconnect and return error\n *\n * @param impl - The wallet implementation to use\n * @param connectorId - The ID of the connector to use\n * @param targetChainId - The desired chain ID to switch to after connection\n * @param logSystem - The log system identifier for logging\n * @returns An object containing connection status, address, and any error\n */\nexport async function connectAndEnsureCorrectNetworkCore(\n impl: EvmWalletImplementation,\n connectorId: string,\n targetChainId: number,\n logSystem: string\n): Promise<EvmWalletConnectionResult> {\n const connectionResult = await impl.connect(connectorId);\n if (!connectionResult.connected || !connectionResult.address || !connectionResult.chainId) {\n return { connected: false, error: connectionResult.error || 'Connection failed' };\n }\n\n if (connectionResult.chainId !== targetChainId) {\n logger.info(\n logSystem,\n `Connected to chain ${connectionResult.chainId}, but target is ${targetChainId}. Attempting switch.`\n );\n try {\n await impl.switchNetwork(targetChainId);\n const postSwitchStatus = impl.getWalletConnectionStatus();\n if (postSwitchStatus.chainId !== targetChainId) {\n const switchError = `Failed to switch to target network ${targetChainId}. Current: ${postSwitchStatus.chainId}`;\n logger.error(logSystem, switchError);\n // Attempt to disconnect to leave a clean state if switch fails\n try {\n await impl.disconnect();\n } catch (e) {\n logger.warn(logSystem, 'Failed to disconnect after network switch failure.', e);\n }\n return { connected: false, error: switchError };\n }\n logger.info(logSystem, `Successfully switched to target chain ${targetChainId}.`);\n return { ...connectionResult, chainId: postSwitchStatus.chainId }; // Return updated chainId\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(logSystem, 'Network switch failed:', errorMessage);\n // Attempt to disconnect to leave a clean state if switch fails\n try {\n await impl.disconnect();\n } catch (e) {\n logger.warn(logSystem, 'Failed to disconnect after network switch failure.', e);\n }\n return { connected: false, error: `Network switch failed: ${errorMessage}` };\n }\n }\n return connectionResult;\n}\n","/**\n * Core Wagmi implementation for EVM wallet connection\n *\n * This file contains the shared implementation of Wagmi and Viem for wallet connection.\n * It's designed to be used by both EVM and Polkadot adapters with full feature parity.\n *\n * Features:\n * - RPC override logic with user configuration support\n * - Dynamic RPC change listener for config invalidation\n * - Chain ID to network ID mapping\n * - Explicit connector setup (injected, metaMask, safe, walletConnect)\n * - Sophisticated config caching with invalidation\n * - UI kit configuration methods for RainbowKit integration\n */\nimport { injected, metaMask, safe, walletConnect } from '@wagmi/connectors';\nimport {\n connect,\n createConfig,\n disconnect,\n getAccount,\n getPublicClient as getWagmiCorePublicClient,\n getWalletClient as getWagmiWalletClient,\n switchChain,\n watchAccount,\n type Config,\n type GetAccountReturnType,\n type CreateConnectorFn as WagmiCreateConnectorFn,\n} from '@wagmi/core';\nimport { http, type Chain, type PublicClient, type WalletClient } from 'viem';\n\nimport type { Connector, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\nimport { getUserRpcUrl } from '../configuration';\nimport type { EvmWalletImplementation } from '../transaction/types';\nimport type { WagmiConfigChains, WagmiWalletConfig, WalletNetworkConfig } from './types';\n\n/**\n * Generates the supported chains from network configurations.\n * Only includes networks that have a viemChain property (ensuring wagmi compatibility).\n */\nfunction getSupportedChainsFromNetworks(\n networkConfigs: WalletNetworkConfig[],\n logSystem: string\n): readonly Chain[] {\n const chains = networkConfigs\n .filter((network) => network.viemChain)\n .map((network) => network.viemChain!)\n .filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index); // Remove duplicates\n\n logger.info(\n logSystem,\n `Generated supported chains from network configurations: ${chains.length} chains`,\n chains.map((c) => ({ id: c.id, name: c.name }))\n );\n\n return chains;\n}\n\n/**\n * Generates the mapping from Viem chain IDs to application network IDs.\n * This mapping is auto-generated from the network configurations.\n */\nfunction getChainIdToNetworkIdMapping(\n networkConfigs: WalletNetworkConfig[],\n logSystem: string\n): Record<number, string> {\n const mapping = networkConfigs\n .filter((network) => network.viemChain)\n .reduce(\n (acc, network) => {\n acc[network.chainId] = network.id;\n return acc;\n },\n {} as Record<number, string>\n );\n\n logger.info(\n logSystem,\n 'Generated chain ID to network ID mapping from network configurations:',\n mapping\n );\n\n return mapping;\n}\n\n/**\n * Type for RainbowKit config retrieval function.\n * This allows adapters to provide their own RainbowKit config service.\n */\nexport type GetWagmiConfigForRainbowKitFn = (\n uiKitConfiguration: UiKitConfiguration,\n chains: WagmiConfigChains,\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n) => Promise<Config | null>;\n\n/**\n * Class responsible for encapsulating Wagmi core logic for wallet interactions.\n * This class should not be used directly by UI components. The adapters\n * expose a standardized interface for wallet operations.\n * It manages Wagmi Config instances and provides methods for wallet actions.\n *\n * Implements EvmWalletImplementation interface for use with shared execution strategies.\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * const walletImpl = new WagmiWalletImplementation({\n * chains: evmChains,\n * networkConfigs: evmNetworks,\n * walletConnectProjectId: 'your-project-id',\n * });\n *\n * // In adapter-polkadot:\n * const walletImpl = new WagmiWalletImplementation({\n * chains: polkadotChains,\n * networkConfigs: polkadotNetworks,\n * });\n * ```\n */\nexport class WagmiWalletImplementation implements EvmWalletImplementation {\n private defaultInstanceConfig: Config | null = null;\n private activeWagmiConfig: Config | null = null;\n private unsubscribe?: ReturnType<typeof watchAccount>;\n private initialized: boolean = false;\n private walletConnectProjectId?: string;\n private rpcConfigUnsubscribe?: () => void;\n\n // Configuration from constructor\n private readonly supportedChains: readonly Chain[];\n private readonly chainIdToNetworkId: Record<number, string>;\n private readonly logSystem: string;\n\n // Optional RainbowKit config function (can be injected by adapters)\n private rainbowKitConfigFn?: GetWagmiConfigForRainbowKitFn;\n\n /**\n * Constructs the WagmiWalletImplementation.\n * Configuration for Wagmi is deferred until actually needed or set externally.\n *\n * @param config - Configuration options for the wallet implementation\n */\n constructor(config: WagmiWalletConfig) {\n this.logSystem = config.logSystem ?? 'WagmiWalletImplementation';\n this.walletConnectProjectId = config.walletConnectProjectId;\n\n // Generate chains and mapping from network configs\n this.supportedChains =\n config.chains.length > 0\n ? config.chains\n : getSupportedChainsFromNetworks(config.networkConfigs, this.logSystem);\n this.chainIdToNetworkId = getChainIdToNetworkIdMapping(config.networkConfigs, this.logSystem);\n\n logger.info(\n this.logSystem,\n 'Constructor called. Initial anticipated kitName:',\n config.initialUiKitConfig?.kitName\n );\n\n this.initialized = true;\n logger.info(\n this.logSystem,\n 'WagmiWalletImplementation instance initialized (Wagmi config creation deferred).'\n );\n\n // Subscribe to RPC configuration changes to invalidate cached config\n this.setupRpcConfigListener();\n }\n\n /**\n * Sets the RainbowKit config retrieval function.\n * This allows adapters to inject their own RainbowKit integration.\n *\n * @param fn - Function to get RainbowKit wagmi config\n */\n public setRainbowKitConfigFn(fn: GetWagmiConfigForRainbowKitFn): void {\n this.rainbowKitConfigFn = fn;\n }\n\n /**\n * Gets the supported chains for this implementation.\n */\n public getSupportedChains(): readonly Chain[] {\n return this.supportedChains;\n }\n\n /**\n * Gets the chain ID to network ID mapping.\n */\n public getChainIdToNetworkIdMapping(): Record<number, string> {\n return this.chainIdToNetworkId;\n }\n\n /**\n * Sets up a listener for RPC configuration changes to invalidate the cached Wagmi config\n * when user changes RPC settings.\n */\n private setupRpcConfigListener(): void {\n // Import dynamically to avoid circular dependencies\n import('@openzeppelin/ui-utils')\n .then(({ userRpcConfigService }) => {\n // Subscribe to all RPC config changes\n this.rpcConfigUnsubscribe = userRpcConfigService.subscribe('*', (event) => {\n if (event.type === 'rpc-config-changed' || event.type === 'rpc-config-cleared') {\n logger.info(\n this.logSystem,\n `RPC config changed for network ${event.networkId}. Invalidating cached Wagmi config.`\n );\n // Invalidate the cached config to force recreation with new RPC settings\n this.defaultInstanceConfig = null;\n }\n });\n })\n .catch((error) => {\n logger.error(this.logSystem, 'Failed to setup RPC config listener:', error);\n });\n }\n\n /**\n * Cleanup method to unsubscribe from RPC config changes\n */\n public cleanup(): void {\n if (this.rpcConfigUnsubscribe) {\n this.rpcConfigUnsubscribe();\n this.rpcConfigUnsubscribe = undefined;\n }\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = undefined;\n }\n }\n\n /**\n * Sets the externally determined, currently active WagmiConfig instance.\n * This is typically called by UiKitManager after it has resolved the appropriate\n * config for the selected UI kit (e.g., RainbowKit's config or a default custom config).\n *\n * @param config - The Wagmi Config object to set as active, or null to clear it.\n */\n public setActiveWagmiConfig(config: Config | null): void {\n logger.info(\n this.logSystem,\n 'setActiveWagmiConfig called with config:',\n config ? 'Valid Config' : 'Null'\n );\n this.activeWagmiConfig = config;\n\n if (this.unsubscribe) {\n logger.warn(\n this.logSystem,\n 'setActiveWagmiConfig: Active WagmiConfig instance has changed. Existing direct watchAccount subscription (via onWalletConnectionChange) may be stale and operating on an old config instance.'\n );\n }\n }\n\n /**\n * Checks if an active wagmi config has been set.\n * Subclasses can use this to determine if the wallet is ready for operations.\n *\n * @returns true if an active wagmi config is set\n */\n protected hasActiveConfig(): boolean {\n return this.activeWagmiConfig !== null;\n }\n\n /**\n * Creates a default WagmiConfig instance on demand.\n * This configuration includes standard connectors (injected, MetaMask, Safe)\n * and WalletConnect if a project ID is available.\n * Used as a fallback or for 'custom' UI kit mode.\n *\n * @returns A Wagmi Config object.\n */\n private createDefaultConfig(): Config {\n const baseConnectors: WagmiCreateConnectorFn[] = [injected(), metaMask(), safe()];\n if (this.walletConnectProjectId?.trim()) {\n baseConnectors.push(walletConnect({ projectId: this.walletConnectProjectId }));\n logger.info(this.logSystem, 'WalletConnect connector added to DEFAULT config.');\n } else {\n logger.warn(\n this.logSystem,\n 'WalletConnect Project ID not provided; WC connector unavailable for DEFAULT config.'\n );\n }\n\n const transportsConfig = this.supportedChains.reduce(\n (acc, chainDefinition) => {\n let rpcUrlToUse: string | undefined = chainDefinition.rpcUrls.default?.http?.[0];\n const appNetworkIdString = this.chainIdToNetworkId[chainDefinition.id];\n\n if (appNetworkIdString) {\n // Prefer user-configured RPC from generic service\n let httpRpcOverride: string | undefined = getUserRpcUrl(appNetworkIdString);\n\n // Fallback to AppConfigService override if no user config\n if (!httpRpcOverride) {\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(appNetworkIdString);\n if (typeof rpcOverrideSetting === 'string') {\n httpRpcOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object') {\n // Handle both RpcEndpointConfig and UserRpcProviderConfig\n if ('http' in rpcOverrideSetting && rpcOverrideSetting.http) {\n httpRpcOverride = rpcOverrideSetting.http;\n } else if ('url' in rpcOverrideSetting && rpcOverrideSetting.url) {\n httpRpcOverride = rpcOverrideSetting.url;\n }\n }\n }\n\n if (httpRpcOverride) {\n logger.info(\n this.logSystem,\n `Using overridden RPC for chain ${chainDefinition.name} (default config): ${httpRpcOverride}`\n );\n rpcUrlToUse = httpRpcOverride;\n }\n }\n\n acc[chainDefinition.id] = http(rpcUrlToUse);\n return acc;\n },\n {} as Record<number, ReturnType<typeof http>>\n );\n\n try {\n const defaultConfig = createConfig({\n chains: this.supportedChains as unknown as WagmiConfigChains,\n connectors: baseConnectors,\n transports: transportsConfig,\n });\n logger.info(this.logSystem, 'Default Wagmi config created successfully on demand.');\n return defaultConfig;\n } catch (error) {\n logger.error(this.logSystem, 'Error creating default Wagmi config on demand:', error);\n return createConfig({\n chains: [this.supportedChains[0]] as unknown as WagmiConfigChains,\n connectors: [injected()],\n transports: { [this.supportedChains[0].id]: http() },\n });\n }\n }\n\n /**\n * Wrapper function to convert AppConfigService RPC overrides to the format expected by RainbowKit.\n *\n * @param networkId - The network ID to get RPC override for\n * @returns RPC configuration in the format expected by RainbowKit\n */\n public getRpcOverrideForRainbowKit(\n networkId: string\n ): string | { http?: string; ws?: string } | undefined {\n // Prefer user-configured RPC from generic service first\n const userRpcUrl = getUserRpcUrl(networkId);\n if (userRpcUrl) {\n return { http: userRpcUrl };\n }\n\n const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(networkId);\n\n if (typeof rpcOverrideSetting === 'string') {\n return rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting !== null) {\n // Check for UserRpcProviderConfig first\n if ('url' in rpcOverrideSetting && typeof rpcOverrideSetting.url === 'string') {\n // It's a UserRpcProviderConfig - convert url to http\n return {\n http: rpcOverrideSetting.url,\n };\n } else if ('http' in rpcOverrideSetting || 'ws' in rpcOverrideSetting) {\n // It's an RpcEndpointConfig\n const config = rpcOverrideSetting as { http?: string; ws?: string };\n return {\n http: config.http,\n ws: config.ws,\n };\n }\n }\n\n return undefined;\n }\n\n /**\n * Retrieves or creates the WagmiConfig specifically for RainbowKit.\n * This delegates to the injected RainbowKit config function if available.\n *\n * @param currentAdapterUiKitConfig - The fully resolved UI kit configuration for the adapter.\n * @returns A Promise resolving to the RainbowKit-specific Wagmi Config object, or null if creation fails or not RainbowKit.\n */\n public async getConfigForRainbowKit(\n currentAdapterUiKitConfig: UiKitConfiguration\n ): Promise<Config | null> {\n if (!this.initialized) {\n logger.error(\n this.logSystem,\n 'getConfigForRainbowKit called before implementation initialization.'\n );\n return null;\n }\n\n if (currentAdapterUiKitConfig?.kitName !== 'rainbowkit') {\n logger.warn(\n this.logSystem,\n 'getConfigForRainbowKit called, but kitName is not rainbowkit. Returning null.'\n );\n return null;\n }\n\n logger.info(\n this.logSystem,\n 'getConfigForRainbowKit: Kit is RainbowKit. Proceeding to create/get config. CurrentAdapterUiKitConfig:',\n currentAdapterUiKitConfig\n );\n\n // Use injected RainbowKit config function if available\n if (this.rainbowKitConfigFn) {\n const rainbowKitWagmiConfig = await this.rainbowKitConfigFn(\n currentAdapterUiKitConfig,\n this.supportedChains as WagmiConfigChains,\n this.chainIdToNetworkId,\n this.getRpcOverrideForRainbowKit.bind(this)\n );\n\n if (rainbowKitWagmiConfig) {\n logger.info(this.logSystem, 'Returning RainbowKit-specific Wagmi config for provider.');\n return rainbowKitWagmiConfig;\n }\n }\n\n logger.warn(this.logSystem, 'RainbowKit specific Wagmi config creation failed.');\n return null;\n }\n\n /**\n * Determines and returns the WagmiConfig to be used by UiKitManager during its configuration process.\n * If RainbowKit is specified in the passed uiKitConfig, it attempts to get its specific config.\n * Otherwise, it falls back to creating/returning a default instance config.\n *\n * @param uiKitConfig - The fully resolved UiKitConfiguration that the manager is currently processing.\n * @returns A Promise resolving to the determined Wagmi Config object.\n */\n public async getActiveConfigForManager(uiKitConfig: UiKitConfiguration): Promise<Config> {\n if (!this.initialized) {\n logger.error(\n this.logSystem,\n 'getActiveConfigForManager called before initialization! Creating fallback.'\n );\n return createConfig({\n chains: [this.supportedChains[0]] as unknown as WagmiConfigChains,\n transports: { [this.supportedChains[0].id]: http() },\n });\n }\n\n if (uiKitConfig?.kitName === 'rainbowkit') {\n const rkConfig = await this.getConfigForRainbowKit(uiKitConfig);\n if (rkConfig) return rkConfig;\n logger.warn(\n this.logSystem,\n 'getActiveConfigForManager: RainbowKit config failed, falling back to default.'\n );\n }\n\n // Reuse existing default config if available, only create if needed\n // This ensures wallet connection state is preserved across network switches\n // Config is automatically invalidated when RPC settings change via setupRpcConfigListener()\n if (!this.defaultInstanceConfig) {\n this.defaultInstanceConfig = this.createDefaultConfig();\n }\n return this.defaultInstanceConfig;\n }\n\n /**\n * @deprecated Prefer using methods that rely on the externally set `activeWagmiConfig`\n * or methods that determine contextually appropriate config like `getActiveConfigForManager` (for manager use)\n * or ensure `activeWagmiConfig` is set before calling wagmi actions.\n * This method returns the internally cached default config or the active one if set.\n *\n * @returns The current default or active Wagmi Config object.\n */\n public getConfig(): Config {\n logger.warn(\n this.logSystem,\n 'getConfig() is deprecated. Internal calls should use activeWagmiConfig if set, or ensure default is created.'\n );\n if (this.activeWagmiConfig) return this.activeWagmiConfig;\n if (!this.defaultInstanceConfig) {\n this.defaultInstanceConfig = this.createDefaultConfig();\n }\n return this.defaultInstanceConfig!;\n }\n\n /**\n * Gets the current wallet connection status (isConnected, address, chainId, etc.).\n * This is a synchronous operation and uses the `activeWagmiConfig` if set by `UiKitManager`,\n * otherwise falls back to the default instance config (created on demand).\n *\n * @returns The current account status from Wagmi.\n */\n public getWalletConnectionStatus(): GetAccountReturnType {\n logger.debug(this.logSystem, 'getWalletConnectionStatus called.');\n const configToUse =\n this.activeWagmiConfig ||\n this.defaultInstanceConfig ||\n (this.defaultInstanceConfig = this.createDefaultConfig());\n\n if (!configToUse) {\n logger.error(this.logSystem, 'No config available for getWalletConnectionStatus!');\n // Return a valid GetAccountReturnType for a disconnected state\n return {\n isConnected: false,\n isConnecting: false,\n isDisconnected: true,\n isReconnecting: false,\n status: 'disconnected',\n address: undefined,\n addresses: undefined,\n chainId: undefined,\n chain: undefined,\n connector: undefined,\n };\n }\n return getAccount(configToUse);\n }\n\n /**\n * Subscribes to account and connection status changes from Wagmi.\n * The subscription is bound to the `activeWagmiConfig` if available at the time of call,\n * otherwise to the default instance config.\n *\n * @param callback - Function to call when connection status changes.\n * @returns A function to unsubscribe from the changes.\n */\n public onWalletConnectionChange(\n callback: (status: GetAccountReturnType, prevStatus: GetAccountReturnType) => void\n ): () => void {\n if (!this.initialized) {\n logger.warn(this.logSystem, 'onWalletConnectionChange called before initialization. No-op.');\n return () => {};\n }\n if (this.unsubscribe) {\n this.unsubscribe();\n logger.debug(this.logSystem, 'Previous watchAccount unsubscribed.');\n }\n\n const configToUse =\n this.activeWagmiConfig ||\n this.defaultInstanceConfig ||\n (this.defaultInstanceConfig = this.createDefaultConfig());\n\n if (!configToUse) {\n logger.error(\n this.logSystem,\n 'No config available for onWalletConnectionChange! Subscription not set.'\n );\n return () => {};\n }\n\n this.unsubscribe = watchAccount(configToUse, { onChange: callback });\n logger.info(\n this.logSystem,\n 'watchAccount subscription established/re-established using config:',\n configToUse === this.activeWagmiConfig ? 'activeExternal' : 'defaultInstance'\n );\n return this.unsubscribe;\n }\n\n /**\n * Gets the Viem Wallet Client for the currently connected account and chain.\n *\n * @returns A Promise resolving to the Viem WalletClient or null if not connected.\n */\n public async getWalletClient(): Promise<WalletClient | null> {\n if (!this.initialized || !this.activeWagmiConfig) {\n logger.warn(\n this.logSystem,\n 'getWalletClient: Not initialized or no activeWagmiConfig. Returning null.'\n );\n return null;\n }\n\n const accountStatus = getAccount(this.activeWagmiConfig);\n if (!accountStatus.isConnected || !accountStatus.chainId || !accountStatus.address) {\n return null;\n }\n\n return getWagmiWalletClient(this.activeWagmiConfig, {\n chainId: accountStatus.chainId,\n account: accountStatus.address,\n });\n }\n\n /**\n * Gets the Viem Public Client for the currently connected chain.\n *\n * @returns A Promise resolving to the Viem PublicClient or null.\n */\n public async getPublicClient(): Promise<PublicClient | null> {\n if (!this.initialized || !this.activeWagmiConfig) {\n logger.warn(\n this.logSystem,\n 'getPublicClient: Not initialized or no activeWagmiConfig. Returning null.'\n );\n return null;\n }\n\n const accountStatus = getAccount(this.activeWagmiConfig);\n const currentChainId = accountStatus.chainId;\n\n if (!currentChainId) {\n logger.warn(\n this.logSystem,\n 'getPublicClient: No connected chainId available from accountStatus. Returning null.'\n );\n return null;\n }\n\n try {\n const publicClient = getWagmiCorePublicClient(this.activeWagmiConfig, {\n chainId: currentChainId,\n });\n\n if (publicClient) {\n logger.info(\n this.logSystem,\n `getPublicClient: Successfully retrieved public client for chainId ${currentChainId}.`\n );\n return publicClient;\n }\n\n logger.warn(\n this.logSystem,\n `getPublicClient: getWagmiCorePublicClient returned undefined/null for chainId ${currentChainId}.`\n );\n return null;\n } catch (error) {\n logger.error(this.logSystem, 'Error getting public client from wagmi/core:', error);\n return null;\n }\n }\n\n /**\n * Gets the list of available wallet connectors from the active Wagmi config.\n *\n * @returns A Promise resolving to an array of available connectors.\n */\n public async getAvailableConnectors(): Promise<Connector[]> {\n if (!this.initialized || !this.activeWagmiConfig) return [];\n return this.activeWagmiConfig.connectors.map((co) => ({ id: co.uid, name: co.name }));\n }\n\n /**\n * Initiates the connection process for a specific connector.\n *\n * @param connectorId - The ID of the connector to use.\n * @returns A Promise with connection result including address and chainId if successful.\n */\n public async connect(\n connectorId: string\n ): Promise<{ connected: boolean; address?: string; chainId?: number; error?: string }> {\n if (!this.initialized || !this.activeWagmiConfig) {\n throw new Error('Wallet not initialized or no active config');\n }\n\n const connectorToUse = this.activeWagmiConfig.connectors.find(\n (cn) => cn.id === connectorId || cn.uid === connectorId\n );\n\n if (!connectorToUse) {\n throw new Error(`Connector ${connectorId} not found`);\n }\n\n const res = await connect(this.activeWagmiConfig, { connector: connectorToUse });\n return { connected: true, address: res.accounts[0], chainId: res.chainId };\n }\n\n /**\n * Disconnects the currently connected wallet.\n *\n * @returns A Promise with disconnection result.\n */\n public async disconnect(): Promise<{ disconnected: boolean; error?: string }> {\n if (!this.initialized || !this.activeWagmiConfig) {\n return { disconnected: false, error: 'Wallet not initialized or no active config' };\n }\n await disconnect(this.activeWagmiConfig);\n return { disconnected: true };\n }\n\n /**\n * Prompts the user to switch to the specified network.\n *\n * @param chainId - The target chain ID to switch to.\n * @returns A Promise that resolves if the switch is successful, or rejects with an error.\n */\n public async switchNetwork(chainId: number): Promise<void> {\n if (!this.initialized || !this.activeWagmiConfig) {\n throw new Error('Wallet not initialized or no active config');\n }\n await switchChain(this.activeWagmiConfig, { chainId });\n }\n}\n","/**\n * Access Control Indexer URL resolution for EVM-compatible networks.\n *\n * Follows the same resolution pattern as `rpc.ts`:\n * 1. User-configured URL from UserNetworkServiceConfigService\n * 2. Default URL from network configuration\n *\n * @module configuration/access-control-indexer\n */\n\nimport { isValidUrl, logger, userNetworkServiceConfigService } from '@openzeppelin/ui-utils';\n\nimport type { EvmCompatibleNetworkConfig } from '../types/network';\n\nconst LOG_SYSTEM = 'AccessControlIndexerResolver';\n\n/**\n * Extracts the user-configured access control indexer URL from UserNetworkServiceConfigService.\n *\n * @param networkId - The network ID to get the access control indexer URL for\n * @returns The access control indexer URL string if configured, undefined otherwise\n */\nexport function getUserAccessControlIndexerUrl(networkId: string): string | undefined {\n const svcCfg = userNetworkServiceConfigService.get(networkId, 'access-control-indexer');\n if (svcCfg && typeof svcCfg === 'object' && 'accessControlIndexerUrl' in svcCfg) {\n return (svcCfg as Record<string, unknown>).accessControlIndexerUrl as string;\n }\n return undefined;\n}\n\n/**\n * Resolves the access control indexer URL for a given EVM network configuration.\n *\n * Priority order:\n * 1. User-configured access control indexer URL (from Network Settings dialog)\n * 2. Default `accessControlIndexerUrl` from the network configuration\n *\n * Unlike RPC resolution, the access control indexer is optional — returns `undefined`\n * instead of throwing when no URL is available.\n *\n * @param networkConfig - EVM-compatible network configuration\n * @returns The resolved access control indexer URL string, or undefined if not configured\n */\nexport function resolveAccessControlIndexerUrl(\n networkConfig: EvmCompatibleNetworkConfig\n): string | undefined {\n const networkId = networkConfig.id;\n\n // First priority: User-configured access control indexer URL\n const userUrl = getUserAccessControlIndexerUrl(networkId);\n if (userUrl) {\n if (isValidUrl(userUrl)) {\n logger.info(\n LOG_SYSTEM,\n `Using user-configured access control indexer URL for network ${networkId}`\n );\n return userUrl;\n } else {\n logger.warn(\n LOG_SYSTEM,\n `User-configured access control indexer URL for ${networkId} is invalid: ${userUrl}. Falling back.`\n );\n }\n }\n\n // Second priority: Default from network config\n if (networkConfig.accessControlIndexerUrl) {\n if (isValidUrl(networkConfig.accessControlIndexerUrl)) {\n logger.debug(\n LOG_SYSTEM,\n `Using default access control indexer URL for network ${networkId}: ${networkConfig.accessControlIndexerUrl}`\n );\n return networkConfig.accessControlIndexerUrl;\n } else {\n logger.warn(\n LOG_SYSTEM,\n `Default access control indexer URL for ${networkId} is invalid: ${networkConfig.accessControlIndexerUrl}`\n );\n }\n }\n\n logger.info(LOG_SYSTEM, `No access control indexer configured for network ${networkId}`);\n return undefined;\n}\n","/**\n * Network Service Configuration for EVM-compatible networks.\n *\n * Provides validation and connection testing for network services (RPC, Explorer, Contract Definitions).\n * These are ecosystem-agnostic and can be used by any EVM-compatible adapter.\n *\n * @module configuration/network-services\n */\n\nimport type { UserExplorerConfig, UserRpcProviderConfig } from '@openzeppelin/ui-types';\nimport { isValidUrl } from '@openzeppelin/ui-utils';\n\nimport { isEvmProviderKey } from '../types';\nimport type { EvmCompatibleNetworkConfig } from '../types';\nimport { testEvmExplorerConnection, validateEvmExplorerConfig } from './explorer';\nimport { testEvmRpcConnection, validateEvmRpcEndpoint } from './rpc';\n\n/**\n * Validates a network service configuration for EVM-compatible networks.\n *\n * @param serviceId - The service identifier ('rpc', 'explorer', or 'contract-definitions')\n * @param values - The form values to validate\n * @returns True if valid, false otherwise\n */\nexport async function validateEvmNetworkServiceConfig(\n serviceId: string,\n values: Record<string, unknown>\n): Promise<boolean> {\n if (serviceId === 'rpc') {\n const cfg = { url: String(values.rpcUrl || ''), isCustom: true } as UserRpcProviderConfig;\n return validateEvmRpcEndpoint(cfg);\n }\n if (serviceId === 'explorer') {\n const cfg = {\n explorerUrl: values.explorerUrl ? String(values.explorerUrl) : undefined,\n apiUrl: values.apiUrl ? String(values.apiUrl) : undefined,\n apiKey: values.apiKey ? String(values.apiKey) : undefined,\n isCustom: true,\n applyToAllNetworks: Boolean(values.applyToAllNetworks),\n } as UserExplorerConfig;\n return validateEvmExplorerConfig(cfg);\n }\n if (serviceId === 'access-control-indexer') {\n // Access control indexer URL is optional — validate format only if provided\n if (\n values.accessControlIndexerUrl !== undefined &&\n values.accessControlIndexerUrl !== null &&\n values.accessControlIndexerUrl !== ''\n ) {\n return isValidUrl(String(values.accessControlIndexerUrl));\n }\n return true;\n }\n if (serviceId === 'contract-definitions') {\n const raw = values.defaultProvider;\n if (raw === undefined || raw === null || raw === '') return true;\n return isEvmProviderKey(raw);\n }\n return true;\n}\n\n/**\n * Tests a network service connection for EVM-compatible networks.\n *\n * @param serviceId - The service identifier ('rpc', 'explorer', or 'contract-definitions')\n * @param values - The form values containing connection details\n * @param networkConfig - The network configuration (ecosystem-agnostic)\n * @returns Connection test result with success status, latency, and optional error\n */\nexport async function testEvmNetworkServiceConnection(\n serviceId: string,\n values: Record<string, unknown>,\n networkConfig: EvmCompatibleNetworkConfig\n): Promise<{ success: boolean; latency?: number; error?: string }> {\n if (serviceId === 'rpc') {\n const cfg = { url: String(values.rpcUrl || ''), isCustom: true } as UserRpcProviderConfig;\n return testEvmRpcConnection(cfg);\n }\n if (serviceId === 'explorer') {\n const cfg = {\n explorerUrl: values.explorerUrl ? String(values.explorerUrl) : undefined,\n apiUrl: values.apiUrl ? String(values.apiUrl) : undefined,\n apiKey: values.apiKey ? String(values.apiKey) : undefined,\n isCustom: true,\n applyToAllNetworks: Boolean(values.applyToAllNetworks),\n } as UserExplorerConfig;\n return testEvmExplorerConnection(cfg, networkConfig);\n }\n if (serviceId === 'access-control-indexer') {\n const accessControlIndexerUrl = values.accessControlIndexerUrl;\n\n // If no indexer URL is provided, indexer is optional — return success\n if (\n !accessControlIndexerUrl ||\n typeof accessControlIndexerUrl !== 'string' ||\n accessControlIndexerUrl.trim() === ''\n ) {\n return { success: true };\n }\n\n if (!isValidUrl(accessControlIndexerUrl)) {\n return { success: false, error: 'Invalid access control indexer URL format' };\n }\n\n try {\n const startTime = Date.now();\n // Perform a lightweight GraphQL health check\n const response = await fetch(accessControlIndexerUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ query: '{ __typename }' }),\n });\n\n const latency = Date.now() - startTime;\n\n if (!response.ok) {\n return {\n success: false,\n latency,\n error: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n\n const data = await response.json();\n if (data.errors) {\n return {\n success: false,\n latency,\n error: `GraphQL errors: ${JSON.stringify(data.errors)}`,\n };\n }\n\n return { success: true, latency };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n return { success: true };\n}\n","/**\n * Types Module\n *\n * Internal TypeScript types for EVM core functionality.\n * Re-exports commonly used types from dependencies.\n *\n * @module types\n */\n\n// Contract artifacts types\nexport { type EvmContractArtifacts, isEvmContractArtifacts } from './artifacts';\n\n// Provider types\nexport {\n EvmProviderKeys,\n type EvmContractDefinitionProviderKey,\n EVM_PROVIDER_ORDER_DEFAULT,\n isEvmProviderKey,\n} from './providers';\n\n// Network configuration types\nexport { type EvmCompatibleNetworkConfig, type TypedEvmNetworkConfig } from './network';\n\n// ABI types\nexport { type AbiItem, type WriteContractParameters } from './abi';\n\n// ABI load result type\nexport type EvmAbiLoadResult = {\n abi: unknown[];\n name?: string;\n source?: string;\n};\n\n// Proxy info type\nexport type EvmProxyInfo = {\n isProxy: boolean;\n implementation?: string;\n proxyType?: string;\n};\n\n// Transaction data type\nexport type EvmTransactionData = {\n to: string;\n data: string;\n value?: bigint;\n};\n","/**\n * RainbowKit Configuration Generator\n *\n * Generates the content for a `rainbowkit.config.ts` file for exported projects.\n * Shared by all EVM-compatible adapters (EVM, Polkadot parachains, etc.).\n */\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\n\nexport interface RainbowKitConfigOptions {\n /** Default app name if not provided in config */\n defaultAppName?: string;\n /** Header comment for the generated file */\n headerComment?: string;\n}\n\nconst DEFAULT_OPTIONS: RainbowKitConfigOptions = {\n defaultAppName: 'My RainbowKit App',\n headerComment: `// RainbowKit configuration for your exported application\n// This file is used ONLY in the exported app, not in the builder app preview`,\n};\n\n/**\n * Generates the content for a `rainbowkit.config.ts` file for an exported project.\n * It merges the user-provided configuration with the necessary boilerplate to ensure\n * the config is valid for RainbowKit's `getDefaultConfig`.\n *\n * @param userConfig - The user-provided configuration from the builder app.\n * @param options - Optional customization for the generated file.\n * @returns A string containing the formatted TypeScript code for the config file.\n */\nexport function generateRainbowKitConfigFile(\n userConfig: UiKitConfiguration['kitConfig'],\n options: RainbowKitConfigOptions = {}\n): string {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const config = (userConfig || {}) as Record<string, unknown>;\n const appName = (config.appName as string) || opts.defaultAppName;\n const learnMoreUrl = (config.learnMoreUrl as string) || 'https://openzeppelin.com';\n // We provide a default projectId as it's required by RainbowKit for WalletConnect.\n const projectId = (config.projectId as string) || 'YOUR_PROJECT_ID';\n\n // Build the appInfo part conditionally\n const appInfoLines = [`appName: '${appName}'`];\n if (learnMoreUrl) {\n appInfoLines.push(`learnMoreUrl: '${learnMoreUrl}'`);\n }\n const appInfoContent = appInfoLines.join(',\\n ');\n\n const fileContent = `${opts.headerComment}\n\n// Uncomment imports as needed:\n// import { darkTheme, lightTheme } from '@rainbow-me/rainbowkit';\n\nconst rainbowKitAppConfig = {\n wagmiParams: {\n appName: '${appName}',\n projectId: '${projectId}', // Get yours at https://cloud.walletconnect.com\n \n // Additional options:\n // ssr: true,\n // wallets: [...],\n },\n providerProps: {\n appInfo: {\n ${appInfoContent}\n },\n \n // UI customization - all features work in exported apps:\n // theme: darkTheme(),\n // modalSize: 'compact',\n // showRecentTransactions: true,\n // coolMode: true,\n },\n};\n\nexport default rainbowKitAppConfig;`;\n\n return fileContent;\n}\n\n/**\n * Generates the specific configuration file for RainbowKit during project export.\n *\n * @param uiKitConfig The full UI kit configuration object from the builder.\n * @param options - Optional customization for the generated file.\n * @returns A record containing the file path and its generated content.\n */\nexport function generateRainbowKitExportables(\n uiKitConfig: UiKitConfiguration,\n options: RainbowKitConfigOptions = {}\n): Record<string, string> {\n const filePath = 'src/config/wallet/rainbowkit.config.ts';\n const content =\n uiKitConfig.customCode || generateRainbowKitConfigFile(uiKitConfig.kitConfig, options);\n\n return { [filePath]: content };\n}\n","/**\n * Custom RainbowKit configuration types for enhanced UI control\n */\n/**\n * Re-export RainbowKit's native types for ConnectButton props\n * This ensures we use the exact same types that RainbowKit expects,\n * reducing maintenance burden and letting RainbowKit handle type validation\n */\n// Import RainbowKit's native ConnectButton types\nimport type { ConnectButton, RainbowKitProvider } from '@rainbow-me/rainbowkit';\n\n/**\n * Extract the `AppInfo` type from the RainbowKitProvider's props.\n * This is the canonical way to get the type for the `appInfo` object.\n */\nexport type AppInfo = React.ComponentProps<typeof RainbowKitProvider>['appInfo'];\n\n/**\n * Extract the props type from RainbowKit's ConnectButton component\n * This gives us the exact same types that RainbowKit uses internally\n */\nexport type RainbowKitConnectButtonProps = React.ComponentProps<typeof ConnectButton>;\n\n/**\n * Represents the props expected by the RainbowKitProvider component.\n * It uses a nested `appInfo` object.\n */\nexport interface RainbowKitProviderProps {\n appInfo?: AppInfo;\n [key: string]: unknown;\n}\n\n/**\n * Represents the shape of the `kitConfig` object we use internally when the\n * selected kit is RainbowKit. It has a flat structure for `appName` and `learnMoreUrl`\n * for easier handling in our builder app, and can also contain pre-existing providerProps.\n */\nexport type RainbowKitKitConfig = Partial<AppInfo> & {\n providerProps?: RainbowKitProviderProps;\n [key: string]: unknown;\n};\n\n/**\n * Custom UI configuration that uses RainbowKit's native types\n * This extends our configuration system while leveraging RainbowKit's own type definitions\n */\nexport interface RainbowKitCustomizations {\n /**\n * Configuration for the RainbowKit ConnectButton component\n * Uses RainbowKit's native prop types for type safety and compatibility\n */\n connectButton?: Partial<RainbowKitConnectButtonProps>;\n}\n\n/**\n * Type guard to check if an object contains RainbowKit customizations\n */\nexport function isRainbowKitCustomizations(obj: unknown): obj is RainbowKitCustomizations {\n return typeof obj === 'object' && obj !== null && 'connectButton' in obj;\n}\n\n/**\n * Utility to extract RainbowKit customizations from a kit config\n */\nexport function extractRainbowKitCustomizations(\n kitConfig: Record<string, unknown> | undefined\n): RainbowKitCustomizations | undefined {\n if (!kitConfig || !kitConfig.customizations) {\n return undefined;\n }\n\n const customizations = kitConfig.customizations;\n return isRainbowKitCustomizations(customizations) ? customizations : undefined;\n}\n","import type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * RainbowKit configuration options definition\n */\n\n/**\n * Validates the RainbowKit configuration to ensure required fields are present.\n *\n * @param kitConfig - The RainbowKit configuration object\n * @returns Object containing the validation result and any missing fields or error message\n */\nexport function validateRainbowKitConfig(kitConfig?: UiKitConfiguration['kitConfig']): {\n isValid: boolean;\n missingFields?: string[];\n error?: string;\n} {\n // Detailed log to inspect the received kitConfig\n logger.debug(\n 'validateRainbowKitConfig',\n 'Received kitConfig for validation:',\n JSON.stringify(kitConfig)\n );\n\n if (!kitConfig) {\n logger.warn('validateRainbowKitConfig', 'Validation failed: No kitConfig provided.');\n return { isValid: false, error: 'No kitConfig provided for RainbowKit' };\n }\n\n // kitConfig is the fully resolved configuration object which should contain wagmiParams and providerProps.\n // Access wagmiParams from within kitConfig.\n const wagmiParamsFromKitConfig = (kitConfig as Record<string, unknown>).wagmiParams as\n | Record<string, unknown>\n | undefined;\n\n if (\n !wagmiParamsFromKitConfig ||\n typeof wagmiParamsFromKitConfig !== 'object' ||\n wagmiParamsFromKitConfig === null\n ) {\n logger.warn(\n 'validateRainbowKitConfig',\n 'Validation failed: kitConfig.wagmiParams is missing or invalid.',\n { wagmiParamsFromKitConfig }\n );\n return { isValid: false, error: 'kitConfig.wagmiParams is missing or not a valid object' };\n }\n\n const missingFields: string[] = [];\n if (\n !('appName' in wagmiParamsFromKitConfig) ||\n typeof wagmiParamsFromKitConfig.appName !== 'string'\n ) {\n missingFields.push('wagmiParams.appName');\n }\n if (\n !('projectId' in wagmiParamsFromKitConfig) ||\n typeof wagmiParamsFromKitConfig.projectId !== 'string'\n ) {\n missingFields.push('wagmiParams.projectId');\n }\n\n if (missingFields.length > 0) {\n const errorMsg = `Missing or invalid required fields in wagmiParams: ${missingFields.join(', ')}`;\n logger.warn('validateRainbowKitConfig', 'Validation failed:', errorMsg, { missingFields });\n return {\n isValid: false,\n missingFields,\n error: errorMsg,\n };\n }\n logger.debug('validateRainbowKitConfig', 'Validation successful.');\n return { isValid: true };\n}\n\n/**\n * Extracts and type-guards a RainbowKit configuration from a UiKitConfiguration\n *\n * @param config The UI kit configuration\n * @returns The raw kitConfig Record<string, unknown> or undefined.\n */\nexport function getRawUserNativeConfig(\n config: UiKitConfiguration\n): Record<string, unknown> | undefined {\n if (config.kitName !== 'rainbowkit' || !config.kitConfig) {\n return undefined;\n }\n // kitConfig is already expected to be Record<string, unknown> or undefined by UiKitConfiguration type.\n // We just ensure it's not null and is an object here for safety if it were `any` somewhere up the chain.\n if (typeof config.kitConfig === 'object' && config.kitConfig !== null) {\n return config.kitConfig as Record<string, unknown>;\n }\n logger.warn('rainbowkit/utils', 'kitConfig for RainbowKit is not a valid object.');\n return undefined;\n}\n","import { Loader2 } from 'lucide-react';\nimport React, { useContext, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\nimport { cn, getWalletButtonSizeProps, logger } from '@openzeppelin/ui-utils';\n\nimport { CustomConnectButton } from '../components';\nimport { WagmiProviderInitializedContext } from '../context';\nimport type { UiKitManager } from '../uiKitManager';\nimport { extractRainbowKitCustomizations } from './types';\n\nconst MIN_COMPONENT_LOADING_DISPLAY_MS = 1000; // 1 second artificial delay\n\n/**\n * Props for the RainbowKitConnectButton component created by the factory.\n */\nexport type RainbowKitConnectButtonProps = BaseComponentProps;\n\n/**\n * Creates a RainbowKitConnectButton component that uses the provided UI kit manager.\n * This factory pattern allows adapters to inject their specific UI kit manager instance.\n *\n * @param uiKitManager - The UI kit manager instance to use for state management\n * @returns A React component that renders the RainbowKit ConnectButton\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * import { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { evmUiKitManager } from './evmUiKitManager';\n *\n * export const RainbowKitConnectButton = createRainbowKitConnectButton(evmUiKitManager);\n *\n * // In adapter-polkadot:\n * import { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { polkadotUiKitManager } from './polkadotUiKitManager';\n *\n * export const RainbowKitConnectButton = createRainbowKitConnectButton(polkadotUiKitManager);\n * ```\n */\nexport function createRainbowKitConnectButton(\n uiKitManager: UiKitManager\n): React.FC<RainbowKitConnectButtonProps> {\n const RainbowKitConnectButtonComponent: React.FC<RainbowKitConnectButtonProps> = (props) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [Component, setComponent] = useState<React.ComponentType<any> | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const [isLoadingComponent, setIsLoadingComponent] = useState(true);\n const [showComponentLoadingOverride, setShowComponentLoadingOverride] = useState(false);\n const componentLoadingTimerRef = useRef<NodeJS.Timeout | null>(null);\n const [managerState, setManagerState] = useState(uiKitManager.getState());\n\n const isWagmiProviderReady = useContext(WagmiProviderInitializedContext);\n\n // Subscribe to UI kit manager state changes\n useEffect(() => {\n const unsubscribe = uiKitManager.subscribe(() => {\n setManagerState(uiKitManager.getState());\n });\n return unsubscribe;\n }, []);\n\n useEffect(() => {\n let isMounted = true;\n setIsLoadingComponent(true);\n setShowComponentLoadingOverride(true); // Start showing override immediately\n\n if (componentLoadingTimerRef.current) {\n clearTimeout(componentLoadingTimerRef.current);\n }\n componentLoadingTimerRef.current = setTimeout(() => {\n if (isMounted) {\n setShowComponentLoadingOverride(false);\n }\n componentLoadingTimerRef.current = null;\n }, MIN_COMPONENT_LOADING_DISPLAY_MS);\n\n const loadComponent = async () => {\n try {\n const rainbowKit = await import('@rainbow-me/rainbowkit');\n if (isMounted) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setComponent(() => rainbowKit.ConnectButton as React.ComponentType<any>);\n // Actual component loading is done, but override might still be active\n setIsLoadingComponent(false);\n }\n } catch (err) {\n if (isMounted) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoadingComponent(false); // Finished loading (with an error)\n logger.error(\n 'RainbowKitConnectButton',\n 'Failed to load RainbowKit ConnectButton:',\n err\n );\n }\n }\n };\n\n loadComponent();\n\n return () => {\n isMounted = false;\n if (componentLoadingTimerRef.current) {\n clearTimeout(componentLoadingTimerRef.current);\n }\n };\n }, []); // Effect for dynamic import runs once\n\n const sizeProps = getWalletButtonSizeProps(props.size);\n\n const renderLoadingPlaceholder = (message: string) => (\n <Button\n disabled={true}\n variant={props.variant || 'outline'}\n size={sizeProps.size}\n className={cn(sizeProps.className, props.fullWidth && 'w-full', props.className)}\n >\n <Loader2 className={cn(sizeProps.iconSize, 'animate-spin mr-1.5')} />\n {message}\n </Button>\n );\n\n if (error) {\n logger.warn(\n 'RainbowKitConnectButton',\n 'Error loading RainbowKit ConnectButton. Displaying fallback CustomConnectButton.'\n );\n return <CustomConnectButton {...props} />;\n }\n\n // Show \"Loading Wallet...\" if component is still factually loading OR if the override is active\n if (isLoadingComponent || showComponentLoadingOverride) {\n return renderLoadingPlaceholder('Loading Wallet...');\n }\n // At this point, component import has finished (successfully or not handled by error state)\n // AND the minimum display time for \"Loading Wallet...\" has passed.\n\n // Now check if the provider context is ready\n if (!isWagmiProviderReady) {\n // No separate delay for this message; it appears if context isn't ready after component load delay.\n return renderLoadingPlaceholder('Initializing Provider...');\n }\n\n // Component should be non-null here if no error and not isLoadingComponent\n if (!Component) {\n // This case should ideally not be hit if logic is correct, but as a safeguard:\n logger.warn(\n 'RainbowKitConnectButton',\n 'Component is null after loading phase, falling back.'\n );\n return <CustomConnectButton {...props} />;\n }\n\n // Extract custom configuration from the manager state\n const kitConfig = managerState.currentFullUiKitConfig?.kitConfig;\n const customizations = extractRainbowKitCustomizations(kitConfig);\n const connectButtonConfig = customizations?.connectButton;\n\n // Merge props: base props + custom configuration + any overrides from props\n // This allows the config to set defaults while still allowing prop overrides\n const finalProps = {\n ...connectButtonConfig, // Apply custom configuration from config\n ...props, // Allow props to override configuration\n };\n\n logger.debug('RainbowKitConnectButton', 'Rendering with configuration:', {\n configFromFile: connectButtonConfig,\n finalProps: finalProps,\n });\n\n return <Component {...finalProps} />;\n };\n\n // Set display name for debugging\n RainbowKitConnectButtonComponent.displayName = 'RainbowKitConnectButton';\n\n return RainbowKitConnectButtonComponent;\n}\n","import type { BaseComponentProps, EcosystemWalletComponents } from '@openzeppelin/ui-types';\n\n/**\n * Creates the complete set of RainbowKit wallet components.\n *\n * This factory function accepts a RainbowKitConnectButton component that has been\n * created with an adapter-specific UI kit manager. This allows different adapters\n * to use their own manager instance while sharing the component creation logic.\n *\n * @param RainbowKitConnectButton - The connect button component created via createRainbowKitConnectButton\n * @returns An object containing all RainbowKit wallet components\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * import { createRainbowKitConnectButton, createRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { evmUiKitManager } from './evmUiKitManager';\n *\n * const RainbowKitConnectButton = createRainbowKitConnectButton(evmUiKitManager);\n * const components = createRainbowKitComponents(RainbowKitConnectButton);\n *\n * // In adapter-polkadot:\n * import { createRainbowKitConnectButton, createRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n * import { polkadotUiKitManager } from './polkadotUiKitManager';\n *\n * const RainbowKitConnectButton = createRainbowKitConnectButton(polkadotUiKitManager);\n * const components = createRainbowKitComponents(RainbowKitConnectButton);\n * ```\n */\nexport function createRainbowKitComponents(\n RainbowKitConnectButton: React.ComponentType<BaseComponentProps>\n): EcosystemWalletComponents {\n return {\n ConnectButton: RainbowKitConnectButton,\n // RainbowKit's ConnectButton is comprehensive and typically includes account display\n // So we don't provide separate AccountDisplay or NetworkSwitcher components\n };\n}\n","/**\n * RainbowKit Config Service\n *\n * Creates Wagmi configuration for RainbowKit. This is shared between\n * EVM and Polkadot adapters to avoid code duplication.\n */\nimport { Config, http } from '@wagmi/core';\nimport { type Chain } from 'viem';\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WagmiConfigChains } from '../types';\n\nconst LOG_PREFIX = 'rainbowkit/config-service';\n\n/**\n * Creates a Wagmi configuration for RainbowKit using getDefaultConfig\n *\n * @param userFullNativeConfig The full native configuration object. This object IS the result of merging\n * AppConfigService settings, user's native rainbowkit.config.ts, and programmatic overrides.\n * It is expected to contain a `wagmiParams` object for RainbowKit's getDefaultConfig\n * and potentially a `providerProps` object for RainbowKitProvider.\n * @param chains Array of viem Chain objects - will be safely cast to wagmi's expected chain type\n * @param chainIdToNetworkIdMap Mapping of chain IDs to network IDs for RPC override lookups\n * @param getRpcEndpointOverride Function to get RPC endpoint overrides\n * @returns Wagmi configuration for RainbowKit or null if creation fails\n */\nexport async function createRainbowKitWagmiConfig(\n userFullNativeConfig: Record<string, unknown> | undefined | null, // This is the fully resolved kitConfig\n chains: readonly Chain[],\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcEndpointOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n): Promise<Config | null> {\n try {\n const { getDefaultConfig } = await import('@rainbow-me/rainbowkit');\n if (!getDefaultConfig) {\n logger.error(LOG_PREFIX, 'Failed to import getDefaultConfig from RainbowKit');\n return null;\n }\n\n // userFullNativeConfig *is* the kitConfig here. Its wagmiParams are what we need.\n const wagmiParams = userFullNativeConfig?.wagmiParams as Record<string, unknown> | undefined;\n\n if (!wagmiParams) {\n logger.warn(\n LOG_PREFIX,\n 'Resolved kitConfig does not contain a `wagmiParams` object. Cannot create RainbowKit Wagmi config.'\n );\n return null;\n }\n\n // Ensure essential appName and projectId are present in user's wagmiParams\n if (typeof wagmiParams.appName !== 'string' || !wagmiParams.appName) {\n logger.warn(LOG_PREFIX, 'kitConfig.wagmiParams is missing or has invalid `appName`.');\n return null;\n }\n if (typeof wagmiParams.projectId !== 'string' || !wagmiParams.projectId) {\n logger.warn(LOG_PREFIX, 'kitConfig.wagmiParams is missing or has invalid `projectId`.');\n return null;\n }\n\n // Build transport configuration with RPC overrides as needed.\n // This iterates over the adapter-determined chains and creates a transport\n // for each, applying any RPC overrides specified via AppConfigService.\n const transportsConfig = chains.reduce(\n (acc, chainDefinition) => {\n let rpcUrlToUse: string | undefined = chainDefinition.rpcUrls.default?.http?.[0];\n const appNetworkIdString = chainIdToNetworkIdMap[chainDefinition.id];\n\n if (appNetworkIdString) {\n const rpcOverrideSetting = getRpcEndpointOverride(appNetworkIdString);\n let httpRpcOverride: string | undefined;\n\n // Extract HTTP RPC URL from override setting\n if (typeof rpcOverrideSetting === 'string') {\n httpRpcOverride = rpcOverrideSetting;\n } else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting) {\n // Handle both RpcEndpointConfig and UserRpcProviderConfig\n if ('http' in rpcOverrideSetting && rpcOverrideSetting.http) {\n httpRpcOverride = rpcOverrideSetting.http;\n } else if ('url' in rpcOverrideSetting && rpcOverrideSetting.url) {\n // Handle UserRpcProviderConfig\n httpRpcOverride = rpcOverrideSetting.url as string;\n }\n }\n\n if (httpRpcOverride) {\n logger.info(\n LOG_PREFIX,\n `Using overridden RPC for chain ${chainDefinition.name}: ${httpRpcOverride}`\n );\n rpcUrlToUse = httpRpcOverride;\n }\n }\n\n acc[chainDefinition.id] = http(rpcUrlToUse);\n return acc;\n },\n {} as Record<number, ReturnType<typeof http>>\n );\n\n // Spread all user-provided wagmiParams, then override chains and transports\n const finalConfigOptions = {\n ...wagmiParams, // User's native params (appName, projectId, wallets, ssr, etc.)\n chains: chains as WagmiConfigChains, // Adapter controls this\n transports: transportsConfig, // Adapter controls this\n };\n\n // The `wallets` property from user config is of type `unknown` on our side if accessed directly from wagmiParams.\n // RainbowKit's `getDefaultConfig` expects a specific `WalletList` type for `wallets`.\n // By spreading `wagmiParams`, we pass whatever structure the user provided.\n // We use `eslint-disable-next-line @typescript-eslint/no-explicit-any` here to pass through\n // the user-provided structure directly, relying on RainbowKit to perform its own validation or type checking internally.\n // This aligns with our principle of not mimicking complex third-party types for pass-through configuration.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const config = getDefaultConfig(finalConfigOptions as any);\n\n logger.info(LOG_PREFIX, 'Successfully created RainbowKit Wagmi config object.', config);\n return config;\n } catch (error) {\n logger.error(LOG_PREFIX, 'Error creating RainbowKit Wagmi config:', error);\n return null;\n }\n}\n\n/**\n * Gets the Wagmi configuration for RainbowKit based on the global UI kit settings.\n * This function is intended to be called by WagmiWalletImplementation.\n *\n * @param uiKitConfiguration The UI kit configuration object from UiKitManager (contains the resolved kitConfig).\n * @param chains Array of viem Chain objects to use with RainbowKit\n * @param chainIdToNetworkIdMap Mapping of chain IDs to network IDs for RPC override lookups\n * @param getRpcEndpointOverride Function to get RPC endpoint overrides\n * @returns The wagmi Config object or null if invalid or not RainbowKit\n */\nexport async function getWagmiConfigForRainbowKit(\n uiKitConfiguration: UiKitConfiguration | undefined,\n chains: readonly Chain[],\n chainIdToNetworkIdMap: Record<number, string>,\n getRpcEndpointOverride: (networkId: string) => string | { http?: string; ws?: string } | undefined\n): Promise<Config | null> {\n if (\n !uiKitConfiguration ||\n uiKitConfiguration.kitName !== 'rainbowkit' ||\n !uiKitConfiguration.kitConfig // kitConfig is the fully resolved config here\n ) {\n logger.debug(\n LOG_PREFIX,\n 'Not configured for RainbowKit or kitConfig (resolved native + programmatic) is missing.'\n );\n return null;\n }\n\n // userFullNativeConfig for createRainbowKitWagmiConfig IS uiKitConfiguration.kitConfig\n const resolvedKitConfig = uiKitConfiguration.kitConfig as Record<string, unknown>;\n\n return createRainbowKitWagmiConfig(\n resolvedKitConfig, // Pass the resolved kitConfig\n chains,\n chainIdToNetworkIdMap,\n getRpcEndpointOverride\n );\n}\n","/**\n * UI Kit Manager Factory\n *\n * Provides a factory function to create UI kit managers for EVM-compatible adapters.\n * This shared implementation handles state management, subscriptions, and configuration\n * for UI kits like RainbowKit.\n *\n * @module wallet/uiKitManager\n */\n\nimport type { Config as WagmiConfig } from '@wagmi/core';\nimport type React from 'react';\n\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { WagmiWalletImplementation } from './wagmi-implementation';\n\n/**\n * State interface for UI Kit Manager.\n * Tracks the current UI kit configuration, wagmi config, and loading states.\n */\nexport interface UiKitManagerState {\n /** The current full UI kit configuration */\n currentFullUiKitConfig: UiKitConfiguration | null;\n /** The active wagmi configuration */\n wagmiConfig: WagmiConfig | null;\n /** The UI kit provider component (e.g., RainbowKitProvider) */\n kitProviderComponent: React.ComponentType<React.PropsWithChildren<unknown>> | null;\n /** Whether the UI kit assets have been loaded */\n isKitAssetsLoaded: boolean;\n /** Whether the manager is currently initializing */\n isInitializing: boolean;\n /** Any error that occurred during configuration */\n error: Error | null;\n}\n\n/**\n * Result type for loading RainbowKit assets.\n */\nexport interface RainbowKitAssetsResult {\n /** The provider component to wrap the app, or null if loading failed */\n ProviderComponent: React.ComponentType<React.PropsWithChildren<unknown>> | null;\n /** Whether CSS was loaded successfully */\n cssLoaded: boolean;\n}\n\n/**\n * Dependencies required by the UI Kit Manager factory.\n */\nexport interface UiKitManagerDependencies {\n /**\n * Function to get the wallet implementation.\n * Can be sync or async to support both EVM (async) and Polkadot (sync) patterns.\n */\n getWalletImplementation: () => WagmiWalletImplementation | Promise<WagmiWalletImplementation>;\n\n /**\n * Function to load RainbowKit assets (provider component and CSS).\n */\n loadRainbowKitAssets: () => Promise<RainbowKitAssetsResult>;\n\n /**\n * Log prefix for identifying the adapter in logs.\n */\n logPrefix: string;\n}\n\n/**\n * Interface for the UI Kit Manager returned by the factory.\n */\nexport interface UiKitManager {\n /** Get the current state */\n getState: () => UiKitManagerState;\n /** Subscribe to state changes */\n subscribe: (listener: () => void) => () => void;\n /** Configure the UI kit with new settings */\n configure: (newFullUiKitConfig: UiKitConfiguration) => Promise<void>;\n}\n\n/**\n * Creates a UI Kit Manager instance with the provided dependencies.\n *\n * @param deps - The dependencies for the UI Kit Manager\n * @returns A UI Kit Manager instance with getState, subscribe, and configure methods\n *\n * @example\n * ```typescript\n * // In adapter-evm:\n * const evmUiKitManager = createUiKitManager({\n * getWalletImplementation: getEvmWalletImplementation,\n * loadRainbowKitAssets: async () => {\n * const { ensureRainbowKitAssetsLoaded } = await import('./rainbowkit/rainbowkitAssetManager');\n * return ensureRainbowKitAssetsLoaded();\n * },\n * logPrefix: 'EvmUiKitManager',\n * });\n *\n * // In adapter-polkadot:\n * const polkadotUiKitManager = createUiKitManager({\n * getWalletImplementation: () => getPolkadotWalletImplementation(),\n * loadRainbowKitAssets: async () => {\n * const { ensureRainbowKitAssetsLoaded } = await import('./rainbowkit/rainbowkitAssetManager');\n * return ensureRainbowKitAssetsLoaded();\n * },\n * logPrefix: 'PolkadotUiKitManager',\n * });\n * ```\n */\nexport function createUiKitManager(deps: UiKitManagerDependencies): UiKitManager {\n const { getWalletImplementation, loadRainbowKitAssets, logPrefix } = deps;\n\n const initialState: UiKitManagerState = {\n currentFullUiKitConfig: null,\n wagmiConfig: null,\n kitProviderComponent: null,\n isKitAssetsLoaded: false,\n isInitializing: false,\n error: null,\n };\n\n let state: UiKitManagerState = { ...initialState };\n const listeners: Set<() => void> = new Set();\n\n function notifyListeners(): void {\n listeners.forEach((listener) => {\n try {\n listener();\n } catch (error) {\n logger.error(logPrefix, 'Error in listener:', error);\n }\n });\n }\n\n function subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function getState(): UiKitManagerState {\n return { ...state }; // Return a copy to prevent direct mutation\n }\n\n async function configure(newFullUiKitConfig: UiKitConfiguration): Promise<void> {\n logger.info(`${logPrefix}:configure`, 'Configuring UI kit. New config:', newFullUiKitConfig);\n\n const oldKitName = state.currentFullUiKitConfig?.kitName;\n const newKitName = newFullUiKitConfig.kitName;\n const kitChanged = oldKitName !== newKitName;\n\n state = {\n ...state,\n isInitializing: true,\n error: null,\n currentFullUiKitConfig: newFullUiKitConfig,\n kitProviderComponent: kitChanged ? null : state.kitProviderComponent,\n isKitAssetsLoaded: kitChanged ? false : state.isKitAssetsLoaded,\n };\n notifyListeners();\n\n let newWagmiConfigAttempt: WagmiConfig | null = null;\n const walletImpl = await Promise.resolve(getWalletImplementation());\n\n try {\n if (newKitName === 'rainbowkit') {\n if (kitChanged || !state.kitProviderComponent || !state.isKitAssetsLoaded) {\n logger.info(`${logPrefix}:configure`, 'Ensuring RainbowKit assets are loaded...');\n const rkAssets = await loadRainbowKitAssets();\n state.kitProviderComponent = rkAssets.ProviderComponent;\n state.isKitAssetsLoaded = rkAssets.cssLoaded && !!rkAssets.ProviderComponent;\n if (!state.isKitAssetsLoaded) {\n throw new Error('Failed to load critical RainbowKit assets.');\n }\n }\n newWagmiConfigAttempt = await walletImpl.getConfigForRainbowKit(newFullUiKitConfig);\n logger.info(`${logPrefix}:configure`, 'WagmiConfig for RainbowKit obtained.');\n } else if (newKitName === 'custom' || !newKitName) {\n newWagmiConfigAttempt = await walletImpl.getActiveConfigForManager(newFullUiKitConfig);\n logger.info(`${logPrefix}:configure`, 'ActiveConfig for custom/default obtained.');\n if (kitChanged) {\n state.kitProviderComponent = null;\n state.isKitAssetsLoaded = false;\n }\n } else {\n logger.warn(`${logPrefix}:configure`, `Unsupported kitName: ${newKitName}.`);\n state.kitProviderComponent = null;\n state.isKitAssetsLoaded = false;\n }\n\n state.wagmiConfig = newWagmiConfigAttempt;\n walletImpl.setActiveWagmiConfig(state.wagmiConfig);\n state.error = null;\n if (\n !newWagmiConfigAttempt &&\n newKitName &&\n newKitName !== 'none' &&\n newKitName !== 'custom'\n ) {\n state.error = new Error(`Failed to obtain WagmiConfig for ${newKitName}`);\n logger.error(`${logPrefix}:configure`, state.error.message);\n }\n } catch (err) {\n logger.error(`${logPrefix}:configure`, 'Error during UI kit configuration process:', err);\n state.error = err instanceof Error ? err : new Error(String(err));\n state.wagmiConfig = null;\n walletImpl.setActiveWagmiConfig(null);\n } finally {\n state.isInitializing = false;\n logger.info(\n `${logPrefix}:configure`,\n 'Configuration attempt finished. Final wagmiConfig:',\n state.wagmiConfig ? 'Set' : 'Null',\n 'Kit Provider Component:',\n state.kitProviderComponent ? 'Set' : 'Null',\n 'Kit Assets Loaded:',\n state.isKitAssetsLoaded,\n 'Error state:',\n state.error ? state.error.message : 'None'\n );\n notifyListeners();\n }\n }\n\n return {\n getState,\n subscribe,\n configure,\n };\n}\n","/**\n * RainbowKit Asset Manager\n *\n * Ensures RainbowKit provider component and CSS are loaded dynamically.\n * This module provides shared asset loading functionality for all EVM-compatible adapters.\n *\n * Having the cache in core means RainbowKit assets only load once even if multiple adapters\n * (e.g., both EVM and Polkadot) are used - this is the desired behavior for optimal performance.\n *\n * @module wallet/rainbowkitAssetManager\n */\n\nimport type React from 'react';\n\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport type { RainbowKitAssetsResult } from './uiKitManager';\n\n// Re-export the type for convenience\nexport type { RainbowKitAssetsResult };\n\n// Module-level cache for loaded assets\nlet loadedAssets: RainbowKitAssetsResult | null = null;\n\n// Promises to ensure assets are loaded only once\nlet providerPromise: Promise<React.ComponentType<React.PropsWithChildren<unknown>> | null> | null =\n null;\nlet cssPromise: Promise<boolean> | null = null;\n\nconst LOG_PREFIX = 'RainbowKitAssetManager';\n\n/**\n * Ensures RainbowKit provider component and CSS are loaded.\n * Loads them dynamically only once and caches the result.\n *\n * @returns A promise resolving to an object containing the ProviderComponent and cssLoaded status.\n */\nexport async function ensureRainbowKitAssetsLoaded(): Promise<RainbowKitAssetsResult> {\n if (loadedAssets) {\n logger.debug(LOG_PREFIX, 'Assets already loaded, returning cached.');\n return loadedAssets;\n }\n\n if (!providerPromise) {\n providerPromise = import('@rainbow-me/rainbowkit')\n .then((module) => {\n const component = module.RainbowKitProvider as React.ComponentType<\n React.PropsWithChildren<unknown>\n >;\n logger.info(LOG_PREFIX, 'RainbowKitProvider module loaded.');\n return component;\n })\n .catch((err) => {\n logger.error(LOG_PREFIX, 'Failed to load RainbowKitProvider module:', err);\n return null; // Resolve with null on error to allow Promise.all to complete\n });\n }\n\n if (!cssPromise) {\n cssPromise = import('@rainbow-me/rainbowkit/styles.css')\n .then(() => {\n logger.info(LOG_PREFIX, 'RainbowKit CSS loaded successfully.');\n return true;\n })\n .catch((err) => {\n logger.error(LOG_PREFIX, 'Failed to load RainbowKit CSS:', err);\n return false; // Resolve with false on error\n });\n }\n\n try {\n const [ProviderComponent, cssLoadedSuccess] = await Promise.all([providerPromise, cssPromise]);\n\n loadedAssets = { ProviderComponent, cssLoaded: cssLoadedSuccess };\n if (!ProviderComponent || !cssLoadedSuccess) {\n logger.warn(LOG_PREFIX, 'One or more RainbowKit assets failed to load.', loadedAssets);\n // Potentially throw here if assets are critical, or let caller decide based on null/false\n }\n return loadedAssets;\n } catch (error) {\n // This catch is for Promise.all failing, though individual catches should handle module errors.\n logger.error(LOG_PREFIX, 'Error in Promise.all for asset loading:', error);\n loadedAssets = { ProviderComponent: null, cssLoaded: false }; // Ensure loadedAssets is set\n return loadedAssets;\n }\n}\n","/**\n * Configuration Resolution Module\n *\n * Provides utilities for resolving and merging UI kit configurations\n * from various sources (native config files, programmatic overrides, app service).\n *\n * @module configResolution\n */\n\nimport type { NativeConfigLoader, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nconst LOG_PREFIX = 'ConfigResolutionService';\n\n/**\n * Resolves and initializes the kit-specific configuration.\n * This function acts as a manager to call the appropriate kit's configuration initializer.\n *\n * @param kitName The name of the UI kit (e.g., 'rainbowkit').\n * @param programmaticKitConfig Optional base/programmatic config passed to the kit initializer.\n * @param loadConfigModule Optional generic callback to load configuration modules by path.\n * @returns A Promise resolving to the final kitConfig (Record<string, unknown>) for the specified kit, or null.\n */\nexport async function resolveAndInitializeKitConfig(\n kitName?: string, // kitName is used to construct the path to the conventional config file\n programmaticKitConfig?: Record<string, unknown>,\n loadConfigModule?: NativeConfigLoader\n): Promise<Record<string, unknown> | null> {\n logger.debug(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `Resolving native config for kit: ${kitName || 'none'}`,\n {\n hasProgrammaticKitConfig: !!programmaticKitConfig,\n hasLoadConfigModule: !!loadConfigModule,\n }\n );\n\n let userNativeConfig: Record<string, unknown> | null = null;\n\n // Only attempt to load a native config if a kitName is provided and a loader function exists.\n // And the kitName is not 'custom' or 'none' as those typically don't have dedicated native config files.\n if (kitName && kitName !== 'custom' && kitName !== 'none' && loadConfigModule) {\n const conventionalConfigPath = `./config/wallet/${kitName}.config.ts`;\n\n try {\n userNativeConfig = await loadConfigModule(conventionalConfigPath);\n } catch (error) {\n logger.warn(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `Call to load native config for ${kitName} from ${conventionalConfigPath} failed. Error:`,\n error\n );\n }\n }\n\n // Merge the loaded user native config with the programmatically passed kitConfig.\n // Programmatic config can override or augment the native file's settings.\n if (userNativeConfig && programmaticKitConfig) {\n const mergedConfig = { ...userNativeConfig, ...programmaticKitConfig };\n return mergedConfig;\n } else if (userNativeConfig) {\n return userNativeConfig;\n } else if (programmaticKitConfig) {\n return programmaticKitConfig;\n }\n\n logger.debug(\n `${LOG_PREFIX}:resolveAndInitializeKitConfig`,\n `No native or programmatic kitConfig provided for ${kitName || 'none'}. Returning null.`\n );\n return null;\n}\n\n/**\n * Resolves the final, complete UiKitConfiguration by merging various sources.\n *\n * @param programmaticOverrides - Overrides passed directly to the configureUiKit call.\n * @param initialAppServiceKitName - The kitName noted from AppConfigService when the adapter instance was constructed.\n * @param currentAppServiceConfig - The full UiKitConfiguration from AppConfigService, re-fetched at the time of the call.\n * @param options - Options, including the callback to load user's native config file.\n * @returns A Promise resolving to the final UiKitConfiguration.\n */\nexport async function resolveFullUiKitConfiguration(\n programmaticOverrides: Partial<UiKitConfiguration>,\n initialAppServiceKitName: UiKitConfiguration['kitName'],\n currentAppServiceConfig: UiKitConfiguration, // This is the result of loadInitialConfigFromAppService()\n options?: {\n loadUiKitNativeConfig?: NativeConfigLoader;\n }\n): Promise<UiKitConfiguration> {\n logger.debug(`${LOG_PREFIX}:resolveFullUiKitConfiguration`, 'Starting resolution with:', {\n programmaticOverrides,\n initialAppServiceKitName,\n currentAppServiceConfig,\n hasLoadNativeCallback: !!options?.loadUiKitNativeConfig,\n hasCustomCode: !!programmaticOverrides.customCode,\n });\n\n const effectiveKitName: UiKitConfiguration['kitName'] =\n programmaticOverrides.kitName ||\n initialAppServiceKitName ||\n currentAppServiceConfig.kitName ||\n 'custom';\n\n // Resolve from native config file (if loader is provided)\n const resolvedUserNativeAndProgrammaticKitConfig = await resolveAndInitializeKitConfig(\n effectiveKitName,\n programmaticOverrides.kitConfig,\n options?.loadUiKitNativeConfig\n );\n\n const finalFullConfig: UiKitConfiguration = {\n kitName: effectiveKitName,\n kitConfig: {\n ...(currentAppServiceConfig.kitConfig || {}),\n ...(resolvedUserNativeAndProgrammaticKitConfig || {}),\n // customCode is NOT applied to runtime config\n },\n // Pass through customCode for export purposes only\n customCode: programmaticOverrides.customCode,\n };\n\n logger.debug(\n `${LOG_PREFIX}:resolveFullUiKitConfiguration`,\n 'Resolved finalFullConfig:',\n finalFullConfig\n );\n return finalFullConfig;\n}\n","import type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { ECOSYSTEM_WALLET_COMPONENT_KEYS } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Filters a set of wallet components based on an exclusion list.\n *\n * @param allPossibleComponents - An object containing all potential components for a kit.\n * @param exclusions - An array of component keys to exclude.\n * @param kitName - The name of the kit being filtered (for logging purposes).\n * @returns The filtered EcosystemWalletComponents object, or undefined if all components are excluded.\n */\nexport function filterWalletComponents(\n allPossibleComponents: EcosystemWalletComponents,\n exclusions: Array<keyof EcosystemWalletComponents>,\n kitName: string = 'custom' // Default to custom for logging context\n): EcosystemWalletComponents | undefined {\n logger.debug(\n 'filterWalletComponents',\n `Filtering components for kit: ${kitName}. Exclusions: ${exclusions.join(', ')}.`\n );\n if (!allPossibleComponents || Object.keys(allPossibleComponents).length === 0) {\n logger.debug('filterWalletComponents', `No components provided to filter for kit: ${kitName}.`);\n return undefined;\n }\n\n if (exclusions.length === 0) {\n logger.debug(\n 'filterWalletComponents',\n `Providing all components for kit: ${kitName}.`,\n allPossibleComponents\n );\n return allPossibleComponents;\n }\n\n const filteredComponents: Partial<EcosystemWalletComponents> = {};\n let componentCount = 0;\n for (const key in allPossibleComponents) {\n const componentKey = key as keyof EcosystemWalletComponents;\n if (!exclusions.includes(componentKey)) {\n if (allPossibleComponents[componentKey]) {\n // Ensure the component actually exists before adding\n filteredComponents[componentKey] = allPossibleComponents[componentKey];\n componentCount++;\n }\n }\n }\n\n if (componentCount > 0) {\n logger.debug(\n 'filterWalletComponents',\n `Providing filtered components for kit: ${kitName} after exclusions (${exclusions.join(', ')}).`,\n filteredComponents\n );\n return filteredComponents as EcosystemWalletComponents;\n }\n\n logger.debug('filterWalletComponents', `All components were excluded for kit: ${kitName}.`);\n return undefined;\n}\n\n/**\n * Extracts the component exclusion list from a UI kit configuration object.\n *\n * @param kitConfig - The `kitConfig` object from `UiKitConfiguration`.\n * @returns An array of component keys to exclude, or an empty array if none are specified or config is invalid.\n */\nexport function getComponentExclusionsFromConfig(\n kitConfig: UiKitConfiguration['kitConfig']\n): Array<keyof EcosystemWalletComponents> {\n if (kitConfig && typeof kitConfig === 'object' && 'components' in kitConfig) {\n const componentsCfg = kitConfig.components;\n if (\n componentsCfg &&\n typeof componentsCfg === 'object' &&\n 'exclude' in componentsCfg &&\n Array.isArray(componentsCfg.exclude)\n ) {\n // Ensure all elements are valid keys of EcosystemWalletComponents\n // This provides a bit more type safety at runtime if the config comes from an untyped source\n return componentsCfg.exclude.filter(\n (key): key is keyof EcosystemWalletComponents =>\n typeof key === 'string' &&\n (ECOSYSTEM_WALLET_COMPONENT_KEYS as readonly string[]).includes(key)\n ) as Array<keyof EcosystemWalletComponents>;\n }\n }\n return [];\n}\n","/**\n * Validation Module\n *\n * Execution configuration validation for EVM transactions.\n *\n * @module validation\n */\n\nexport { validateEoaConfig, validateEvmEoaConfig, type EvmWalletStatus } from './eoa';\nexport { validateRelayerConfig, validateEvmRelayerConfig } from './relayer';\nexport { validateEvmExecutionConfig } from './execution';\n\n// Re-export address validation from utils for convenience\nexport { isValidEvmAddress } from '../utils/validation';\n","import type { RelayerExecutionConfig } from '@openzeppelin/ui-types';\n\n/**\n * Validates a relayer execution configuration.\n *\n * @param config The relayer execution config to validate\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateRelayerConfig(\n config: RelayerExecutionConfig\n): Promise<true | string> {\n if (!config.serviceUrl) {\n return 'Relayer execution selected, but no service URL was provided.';\n }\n if (!config.relayer?.relayerId) {\n return 'Relayer execution selected, but no relayer was chosen from the list.';\n }\n return true;\n}\n\n/**\n * Simple validation of relayer config.\n * Useful for static validation before execution.\n */\nexport function validateEvmRelayerConfig(config: RelayerExecutionConfig): boolean {\n if (!config.serviceUrl) {\n return false;\n }\n if (!config.relayer?.relayerId) {\n return false;\n }\n return true;\n}\n","/**\n * Execution Configuration Validation\n *\n * Central validation router for EVM execution configurations.\n * Delegates to specific validators based on execution method type.\n */\n\nimport type {\n EoaExecutionConfig,\n ExecutionConfig,\n RelayerExecutionConfig,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { validateEoaConfig, type EvmWalletStatus } from './eoa';\nimport { validateRelayerConfig } from './relayer';\n\nconst SYSTEM_LOG_TAG = 'evm-execution-config';\n\n/**\n * Validates the complete execution configuration object against the\n * requirements and capabilities of EVM-compatible adapters.\n *\n * @param config The execution configuration to validate\n * @param walletStatus The wallet connection status for validation\n * @returns true if valid, or an error message string if invalid\n */\nexport async function validateEvmExecutionConfig(\n config: ExecutionConfig,\n walletStatus: EvmWalletStatus\n): Promise<true | string> {\n logger.info(SYSTEM_LOG_TAG, 'Validating EVM execution config:', { config, walletStatus });\n\n switch (config.method) {\n case 'eoa':\n return validateEoaConfig(config as EoaExecutionConfig, walletStatus);\n case 'relayer':\n return validateRelayerConfig(config as RelayerExecutionConfig);\n case 'multisig':\n return 'Multisig execution is not yet supported';\n default: {\n const unknownMethod = (config as ExecutionConfig).method;\n logger.warn(SYSTEM_LOG_TAG, `Unsupported execution method type: ${unknownMethod}`);\n return `Unsupported execution method: ${unknownMethod}`;\n }\n }\n}\n","/**\n * @openzeppelin/ui-builder-adapter-evm-core\n *\n * Core EVM blockchain adapter functionality extracted from adapter-evm.\n * This package provides reusable, stateless modules for EVM-compatible adapters.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// ABI Module - ABI loading, transformation, and comparison\n// ============================================================================\nexport {\n // Transformation\n transformAbiToSchema,\n createAbiFunctionItem,\n // Loading\n loadEvmContract,\n loadAbiFromEtherscan,\n loadAbiFromEtherscanV1,\n loadAbiFromEtherscanV2,\n loadAbiFromSourcify,\n getSourcifyContractAppUrl,\n shouldUseV2Api,\n testEtherscanV2Connection,\n // Convenience wrappers\n loadContractSchema,\n loadContractWithFullMetadata,\n compareContractDefinitions,\n validateContractDefinition,\n hashContractDefinition,\n // Comparison\n AbiComparisonService,\n abiComparisonService,\n // Types\n type EvmContractLoadResult,\n type ContractLoadOptions,\n type EtherscanAbiResult,\n type SourcifyAbiResult,\n type AbiComparisonResult,\n type AbiDifference,\n type AbiValidationResult,\n isValidAbiArray,\n isValidAbiItem,\n} from './abi';\n\n// ============================================================================\n// Mapping Module - Type mapping and form field generation\n// ============================================================================\nexport {\n // Type mapping\n mapEvmParamTypeToFieldType,\n getEvmCompatibleFieldTypes,\n EVM_TYPE_TO_FIELD_TYPE,\n getEvmTypeMappingInfo,\n // Field generation\n generateEvmDefaultField,\n} from './mapping';\n\n// ============================================================================\n// Transform Module - Input parsing and output formatting\n// ============================================================================\nexport { parseEvmInput, formatEvmFunctionResult } from './transform';\n\n// ============================================================================\n// Query Module - View function querying\n// ============================================================================\nexport { queryEvmViewFunction, isEvmViewFunction } from './query';\n\n// ============================================================================\n// Transaction Module - Transaction formatting, execution strategies, and sending\n// ============================================================================\nexport {\n // Formatting\n formatEvmTransactionData,\n // Execution strategy interface\n type AdapterExecutionStrategy,\n // Execution strategies\n EoaExecutionStrategy,\n RelayerExecutionStrategy,\n type EvmRelayerTransactionOptions,\n // Transaction functions\n executeEvmTransaction,\n signAndBroadcastEvmTransaction,\n waitForEvmTransactionConfirmation,\n // Types\n type EvmWalletImplementation,\n type EvmWalletConnectionStatus,\n type EvmWalletConnectionResult,\n type EvmWalletDisconnectResult,\n} from './transaction';\n\n// ============================================================================\n// Wallet Module - Wallet implementation and UI configuration utilities\n// ============================================================================\nexport {\n // Wagmi provider context\n WagmiProviderInitializedContext,\n // Wagmi hooks\n useIsWagmiProviderInitialized,\n // Wagmi components\n SafeWagmiComponent,\n // Wallet UI components\n CustomConnectButton,\n ConnectorDialog,\n CustomAccountDisplay,\n CustomNetworkSwitcher,\n type ConnectButtonProps,\n // Core connection utilities\n connectAndEnsureCorrectNetworkCore,\n DEFAULT_DISCONNECTED_STATUS,\n // Wallet implementation\n WagmiWalletImplementation,\n type GetWagmiConfigForRainbowKitFn,\n // Wallet types\n type WagmiWalletConfig,\n type WagmiConfigChains,\n type WalletNetworkConfig,\n // RainbowKit utilities\n generateRainbowKitConfigFile,\n generateRainbowKitExportables,\n type RainbowKitConfigOptions,\n // RainbowKit types\n type AppInfo,\n type RainbowKitConnectButtonProps,\n type RainbowKitProviderProps,\n type RainbowKitKitConfig,\n type RainbowKitCustomizations,\n isRainbowKitCustomizations,\n extractRainbowKitCustomizations,\n // RainbowKit utility functions\n validateRainbowKitConfig,\n getRawUserNativeConfig,\n // RainbowKit component factories\n createRainbowKitConnectButton,\n createRainbowKitComponents,\n // RainbowKit config service\n createRainbowKitWagmiConfig,\n getWagmiConfigForRainbowKit,\n // UI Kit Manager factory\n createUiKitManager,\n type UiKitManagerState,\n type UiKitManagerDependencies,\n type UiKitManager,\n type RainbowKitAssetsResult,\n // RainbowKit Asset Manager\n ensureRainbowKitAssetsLoaded,\n // Configuration Resolution\n resolveAndInitializeKitConfig,\n resolveFullUiKitConfiguration,\n // Wallet component filtering utilities\n filterWalletComponents,\n getComponentExclusionsFromConfig,\n} from './wallet';\n\n// ============================================================================\n// Configuration Module - RPC, Explorer, and Access Control Indexer configuration\n// ============================================================================\nexport {\n // RPC\n buildRpcUrl,\n getUserRpcUrl,\n resolveRpcUrl,\n validateEvmRpcEndpoint,\n testEvmRpcConnection,\n getEvmCurrentBlock,\n // Explorer\n resolveExplorerConfig,\n resolveExplorerApiKeyFromAppConfig,\n getEvmExplorerAddressUrl,\n getEvmExplorerTxUrl,\n validateEvmExplorerConfig,\n testEvmExplorerConnection,\n // Access control indexer\n getUserAccessControlIndexerUrl,\n resolveAccessControlIndexerUrl,\n // Network service configuration\n validateEvmNetworkServiceConfig,\n testEvmNetworkServiceConnection,\n} from './configuration';\n\n// ============================================================================\n// Proxy Module - Proxy detection and implementation resolution\n// ============================================================================\nexport {\n detectProxyFromAbi,\n getImplementationAddress,\n getAdminAddress,\n type ProxyDetectionResult,\n} from './proxy';\n\n// ============================================================================\n// Validation Module - Execution configuration validation\n// ============================================================================\nexport {\n validateEoaConfig,\n validateEvmEoaConfig,\n validateRelayerConfig,\n validateEvmRelayerConfig,\n validateEvmExecutionConfig,\n isValidEvmAddress,\n type EvmWalletStatus,\n} from './validation';\n\n// ============================================================================\n// Utils Module - Utility functions\n// ============================================================================\nexport {\n // JSON utilities\n stringifyWithBigInt,\n // Formatting\n formatMethodName,\n formatInputName,\n // Gas utilities\n weiToGwei,\n gweiToWei,\n // Artifacts\n validateAndConvertEvmArtifacts,\n} from './utils';\n\n// ============================================================================\n// Access Control Module - Access control detection, reads, writes, and history\n// ============================================================================\nexport {\n // Service\n createEvmAccessControlService,\n EvmAccessControlService,\n // Actions\n assembleAcceptAdminTransferAction,\n assembleAcceptOwnershipAction,\n assembleBeginAdminTransferAction,\n assembleCancelAdminTransferAction,\n assembleChangeAdminDelayAction,\n assembleGrantRoleAction,\n assembleRenounceOwnershipAction,\n assembleRenounceRoleAction,\n assembleRevokeRoleAction,\n assembleRollbackAdminDelayAction,\n assembleTransferOwnershipAction,\n // Feature Detection\n detectAccessControlCapabilities,\n validateAccessControlSupport,\n // Indexer Client\n createIndexerClient,\n EvmIndexerClient,\n // On-Chain Reader\n getAdmin,\n getCurrentBlock,\n readCurrentRoles,\n readOwnership,\n // Validation\n validateAddress,\n validateRoleId,\n validateRoleIds,\n // Constants\n DEFAULT_ADMIN_ROLE,\n DEFAULT_ADMIN_ROLE_LABEL,\n ZERO_ADDRESS,\n // Types\n type EvmAccessControlContext,\n type EvmTransactionExecutor,\n} from './access-control';\n\n// ============================================================================\n// Types Module - TypeScript type definitions\n// ============================================================================\nexport {\n // Contract artifacts\n type EvmContractArtifacts,\n isEvmContractArtifacts,\n // Provider types\n EvmProviderKeys,\n type EvmContractDefinitionProviderKey,\n EVM_PROVIDER_ORDER_DEFAULT,\n isEvmProviderKey,\n // Network and ABI types\n type EvmCompatibleNetworkConfig,\n type TypedEvmNetworkConfig,\n type AbiItem,\n type WriteContractParameters,\n // Result types\n type EvmAbiLoadResult,\n type EvmProxyInfo,\n type EvmTransactionData,\n} from './types';\n","/**\n * EVM Access Control ABI Fragments\n *\n * Single-function ABI fragments for all access control operations.\n * Used by the on-chain reader (read operations) and actions module (write operations).\n *\n * Each constant is a minimal ABI array containing exactly one function definition,\n * suitable for use with viem's `readContract()` and `writeContract()`.\n *\n * @module access-control/abis\n */\n\nimport type { Abi } from 'viem';\n\n// ---------------------------------------------------------------------------\n// Ownable\n// ---------------------------------------------------------------------------\n\n/** ABI for `owner() → address` */\nexport const OWNER_ABI: Abi = [\n {\n type: 'function',\n name: 'owner',\n inputs: [],\n outputs: [{ name: '', type: 'address' }],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `transferOwnership(address newOwner)` */\nexport const TRANSFER_OWNERSHIP_ABI: Abi = [\n {\n type: 'function',\n name: 'transferOwnership',\n inputs: [{ name: 'newOwner', type: 'address' }],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `renounceOwnership()` */\nexport const RENOUNCE_OWNERSHIP_ABI: Abi = [\n {\n type: 'function',\n name: 'renounceOwnership',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Ownable2Step\n// ---------------------------------------------------------------------------\n\n/** ABI for `pendingOwner() → address` */\nexport const PENDING_OWNER_ABI: Abi = [\n {\n type: 'function',\n name: 'pendingOwner',\n inputs: [],\n outputs: [{ name: '', type: 'address' }],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `acceptOwnership()` */\nexport const ACCEPT_OWNERSHIP_ABI: Abi = [\n {\n type: 'function',\n name: 'acceptOwnership',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// AccessControl\n// ---------------------------------------------------------------------------\n\n/** ABI for `hasRole(bytes32 role, address account) → bool` */\nexport const HAS_ROLE_ABI: Abi = [\n {\n type: 'function',\n name: 'hasRole',\n inputs: [\n { name: 'role', type: 'bytes32' },\n { name: 'account', type: 'address' },\n ],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `getRoleAdmin(bytes32 role) → bytes32` */\nexport const GET_ROLE_ADMIN_ABI: Abi = [\n {\n type: 'function',\n name: 'getRoleAdmin',\n inputs: [{ name: 'role', type: 'bytes32' }],\n outputs: [{ name: '', type: 'bytes32' }],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `grantRole(bytes32 role, address account)` */\nexport const GRANT_ROLE_ABI: Abi = [\n {\n type: 'function',\n name: 'grantRole',\n inputs: [\n { name: 'role', type: 'bytes32' },\n { name: 'account', type: 'address' },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `revokeRole(bytes32 role, address account)` */\nexport const REVOKE_ROLE_ABI: Abi = [\n {\n type: 'function',\n name: 'revokeRole',\n inputs: [\n { name: 'role', type: 'bytes32' },\n { name: 'account', type: 'address' },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `renounceRole(bytes32 role, address callerConfirmation)` */\nexport const RENOUNCE_ROLE_ABI: Abi = [\n {\n type: 'function',\n name: 'renounceRole',\n inputs: [\n { name: 'role', type: 'bytes32' },\n { name: 'callerConfirmation', type: 'address' },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// AccessControlEnumerable\n// ---------------------------------------------------------------------------\n\n/** ABI for `getRoleMemberCount(bytes32 role) → uint256` */\nexport const GET_ROLE_MEMBER_COUNT_ABI: Abi = [\n {\n type: 'function',\n name: 'getRoleMemberCount',\n inputs: [{ name: 'role', type: 'bytes32' }],\n outputs: [{ name: '', type: 'uint256' }],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `getRoleMember(bytes32 role, uint256 index) → address` */\nexport const GET_ROLE_MEMBER_ABI: Abi = [\n {\n type: 'function',\n name: 'getRoleMember',\n inputs: [\n { name: 'role', type: 'bytes32' },\n { name: 'index', type: 'uint256' },\n ],\n outputs: [{ name: '', type: 'address' }],\n stateMutability: 'view',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// AccessControlDefaultAdminRules\n// ---------------------------------------------------------------------------\n\n/** ABI for `defaultAdmin() → address` */\nexport const DEFAULT_ADMIN_ABI: Abi = [\n {\n type: 'function',\n name: 'defaultAdmin',\n inputs: [],\n outputs: [{ name: '', type: 'address' }],\n stateMutability: 'view',\n },\n] as const;\n\n/**\n * ABI for `pendingDefaultAdmin() → (address newAdmin, uint48 schedule)`\n *\n * Returns a tuple of the pending new admin address and the UNIX timestamp\n * (in seconds) at which the transfer can be accepted.\n */\nexport const PENDING_DEFAULT_ADMIN_ABI: Abi = [\n {\n type: 'function',\n name: 'pendingDefaultAdmin',\n inputs: [],\n outputs: [\n { name: 'newAdmin', type: 'address' },\n { name: 'schedule', type: 'uint48' },\n ],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `defaultAdminDelay() → uint48` */\nexport const DEFAULT_ADMIN_DELAY_ABI: Abi = [\n {\n type: 'function',\n name: 'defaultAdminDelay',\n inputs: [],\n outputs: [{ name: '', type: 'uint48' }],\n stateMutability: 'view',\n },\n] as const;\n\n/**\n * ABI for `pendingDefaultAdminDelay() → (uint48 newDelay, uint48 schedule)`\n *\n * Returns a tuple of the pending new admin delay (in seconds) and the UNIX\n * timestamp at which the delay change takes effect. Returns (0, 0) when no\n * delay change is scheduled.\n */\nexport const PENDING_DEFAULT_ADMIN_DELAY_ABI: Abi = [\n {\n type: 'function',\n name: 'pendingDefaultAdminDelay',\n inputs: [],\n outputs: [\n { name: 'newDelay', type: 'uint48' },\n { name: 'schedule', type: 'uint48' },\n ],\n stateMutability: 'view',\n },\n] as const;\n\n/** ABI for `beginDefaultAdminTransfer(address newAdmin)` */\nexport const BEGIN_DEFAULT_ADMIN_TRANSFER_ABI: Abi = [\n {\n type: 'function',\n name: 'beginDefaultAdminTransfer',\n inputs: [{ name: 'newAdmin', type: 'address' }],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `acceptDefaultAdminTransfer()` */\nexport const ACCEPT_DEFAULT_ADMIN_TRANSFER_ABI: Abi = [\n {\n type: 'function',\n name: 'acceptDefaultAdminTransfer',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `cancelDefaultAdminTransfer()` */\nexport const CANCEL_DEFAULT_ADMIN_TRANSFER_ABI: Abi = [\n {\n type: 'function',\n name: 'cancelDefaultAdminTransfer',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Admin Delay Change Operations\n// ---------------------------------------------------------------------------\n\n/** ABI for `changeDefaultAdminDelay(uint48 newDelay)` */\nexport const CHANGE_DEFAULT_ADMIN_DELAY_ABI: Abi = [\n {\n type: 'function',\n name: 'changeDefaultAdminDelay',\n inputs: [{ name: 'newDelay', type: 'uint48' }],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n/** ABI for `rollbackDefaultAdminDelay()` */\nexport const ROLLBACK_DEFAULT_ADMIN_DELAY_ABI: Abi = [\n {\n type: 'function',\n name: 'rollbackDefaultAdminDelay',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// ERC-165 (optional on-chain verification)\n// ---------------------------------------------------------------------------\n\n/** ABI for `supportsInterface(bytes4 interfaceId) → bool` */\nexport const SUPPORTS_INTERFACE_ABI: Abi = [\n {\n type: 'function',\n name: 'supportsInterface',\n inputs: [{ name: 'interfaceId', type: 'bytes4' }],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Feature Detection Signature Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Function signature descriptors for ABI-based capability detection.\n * Used by `feature-detection.ts` to match function names AND parameter types\n * against the contract's ABI, avoiding false positives from similarly-named functions.\n *\n * @see contracts/feature-detection.ts for the full detection matrix\n */\n\n/** Functions required for Ownable detection */\nexport const OWNABLE_SIGNATURES = [\n { name: 'owner', inputs: [] as string[] },\n { name: 'transferOwnership', inputs: ['address'] },\n] as const;\n\n/** Additional functions for Ownable2Step detection */\nexport const OWNABLE_TWO_STEP_SIGNATURES = [\n { name: 'pendingOwner', inputs: [] as string[] },\n { name: 'acceptOwnership', inputs: [] as string[] },\n] as const;\n\n/** Functions required for AccessControl detection */\nexport const ACCESS_CONTROL_SIGNATURES = [\n { name: 'hasRole', inputs: ['bytes32', 'address'] },\n { name: 'grantRole', inputs: ['bytes32', 'address'] },\n { name: 'revokeRole', inputs: ['bytes32', 'address'] },\n { name: 'getRoleAdmin', inputs: ['bytes32'] },\n] as const;\n\n/** Additional functions for AccessControlEnumerable detection */\nexport const ENUMERABLE_SIGNATURES = [\n { name: 'getRoleMemberCount', inputs: ['bytes32'] },\n { name: 'getRoleMember', inputs: ['bytes32', 'uint256'] },\n] as const;\n\n/** Additional functions for AccessControlDefaultAdminRules detection */\nexport const DEFAULT_ADMIN_RULES_SIGNATURES = [\n { name: 'defaultAdmin', inputs: [] as string[] },\n { name: 'pendingDefaultAdmin', inputs: [] as string[] },\n { name: 'beginDefaultAdminTransfer', inputs: ['address'] },\n { name: 'acceptDefaultAdminTransfer', inputs: [] as string[] },\n { name: 'cancelDefaultAdminTransfer', inputs: [] as string[] },\n] as const;\n\n/** Additional functions for admin delay change operations */\nexport const ADMIN_DELAY_CHANGE_SIGNATURES = [\n { name: 'changeDefaultAdminDelay', inputs: ['uint48'] },\n { name: 'rollbackDefaultAdminDelay', inputs: [] as string[] },\n] as const;\n\n// ---------------------------------------------------------------------------\n// ERC-165 Interface IDs (for optional on-chain verification)\n// ---------------------------------------------------------------------------\n\n/**\n * Well-known ERC-165 interface identifiers for OpenZeppelin access control contracts.\n * Can be used with `supportsInterface()` for on-chain verification.\n */\nexport const ERC165_INTERFACE_IDS = {\n /** IAccessControl: 0x7965db0b */\n ACCESS_CONTROL: '0x7965db0b',\n /** IAccessControlEnumerable: 0x5a05180f */\n ACCESS_CONTROL_ENUMERABLE: '0x5a05180f',\n /** IAccessControlDefaultAdminRules: 0x31498786 (OZ v5) */\n ACCESS_CONTROL_DEFAULT_ADMIN_RULES: '0x31498786',\n} as const;\n","/**\n * EVM Access Control Actions Module\n *\n * Assembles transaction data for access control write operations on EVM-compatible\n * contracts. Each function returns a `WriteContractParameters` object containing:\n * - `address`: The target contract address\n * - `abi`: A single-function ABI fragment\n * - `functionName`: The Solidity function name\n * - `args`: The encoded arguments\n *\n * The service layer delegates execution to the caller-provided `executeTransaction`\n * callback, keeping this module purely responsible for data assembly.\n *\n * @module access-control/actions\n * @see quickstart.md §Step 5\n * @see research.md §R2 — Transaction Assembly Strategy\n */\n\nimport type { WriteContractParameters } from '../types';\nimport {\n ACCEPT_DEFAULT_ADMIN_TRANSFER_ABI,\n ACCEPT_OWNERSHIP_ABI,\n BEGIN_DEFAULT_ADMIN_TRANSFER_ABI,\n CANCEL_DEFAULT_ADMIN_TRANSFER_ABI,\n CHANGE_DEFAULT_ADMIN_DELAY_ABI,\n GRANT_ROLE_ABI,\n RENOUNCE_OWNERSHIP_ABI,\n RENOUNCE_ROLE_ABI,\n REVOKE_ROLE_ABI,\n ROLLBACK_DEFAULT_ADMIN_DELAY_ABI,\n TRANSFER_OWNERSHIP_ABI,\n} from './abis';\n\n// ---------------------------------------------------------------------------\n// Ownership Actions (Phase 6 — US4)\n// ---------------------------------------------------------------------------\n\n/**\n * Assembles a `transferOwnership(address newOwner)` transaction.\n *\n * Works with both Ownable (single-step) and Ownable2Step (sets pendingOwner).\n * The contract determines the behavior — same function signature for both patterns.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param newOwner - The new owner address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleTransferOwnershipAction(\n contractAddress: string,\n newOwner: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: TRANSFER_OWNERSHIP_ABI,\n functionName: 'transferOwnership',\n args: [newOwner],\n };\n}\n\n/**\n * Assembles an `acceptOwnership()` transaction (Ownable2Step only).\n *\n * Must be called by the pending owner to complete a two-step transfer.\n * No arguments — the caller is implicitly the pending owner.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleAcceptOwnershipAction(contractAddress: string): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: ACCEPT_OWNERSHIP_ABI,\n functionName: 'acceptOwnership',\n args: [],\n };\n}\n\n/**\n * Assembles a `renounceOwnership()` transaction (Ownable).\n *\n * Permanently renounces ownership — after execution, `owner()` returns the zero address.\n * This is an EVM-specific operation not present in the Stellar adapter.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleRenounceOwnershipAction(contractAddress: string): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: RENOUNCE_OWNERSHIP_ABI,\n functionName: 'renounceOwnership',\n args: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Admin Actions (Phase 7 — US5)\n// ---------------------------------------------------------------------------\n\n/**\n * Assembles a `beginDefaultAdminTransfer(address newAdmin)` transaction.\n *\n * Initiates a two-step admin transfer on an AccessControlDefaultAdminRules contract.\n * The transfer can be accepted after the contract's built-in delay period.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param newAdmin - The new admin address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleBeginAdminTransferAction(\n contractAddress: string,\n newAdmin: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: BEGIN_DEFAULT_ADMIN_TRANSFER_ABI,\n functionName: 'beginDefaultAdminTransfer',\n args: [newAdmin],\n };\n}\n\n/**\n * Assembles an `acceptDefaultAdminTransfer()` transaction.\n *\n * Must be called by the pending admin after the accept schedule timestamp\n * has passed. No arguments — the caller is implicitly the pending admin.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleAcceptAdminTransferAction(\n contractAddress: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: ACCEPT_DEFAULT_ADMIN_TRANSFER_ABI,\n functionName: 'acceptDefaultAdminTransfer',\n args: [],\n };\n}\n\n/**\n * Assembles a `cancelDefaultAdminTransfer()` transaction.\n *\n * Cancels a pending admin transfer. Must be called by the current default admin.\n * EVM-specific operation — Stellar has no cancel mechanism.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleCancelAdminTransferAction(\n contractAddress: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: CANCEL_DEFAULT_ADMIN_TRANSFER_ABI,\n functionName: 'cancelDefaultAdminTransfer',\n args: [],\n };\n}\n\n/**\n * Assembles a `changeDefaultAdminDelay(uint48 newDelay)` transaction.\n *\n * Schedules a change to the admin transfer delay. The delay change itself\n * has a delay before it takes effect.\n * EVM-specific operation — Stellar has no delay mechanism.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param newDelay - The new delay in seconds (uint48)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleChangeAdminDelayAction(\n contractAddress: string,\n newDelay: number\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: CHANGE_DEFAULT_ADMIN_DELAY_ABI,\n functionName: 'changeDefaultAdminDelay',\n args: [newDelay],\n };\n}\n\n/**\n * Assembles a `rollbackDefaultAdminDelay()` transaction.\n *\n * Rolls back a pending admin delay change. Must be called by the current\n * default admin before the delay change takes effect.\n * EVM-specific operation — Stellar has no delay mechanism.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleRollbackAdminDelayAction(contractAddress: string): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: ROLLBACK_DEFAULT_ADMIN_DELAY_ABI,\n functionName: 'rollbackDefaultAdminDelay',\n args: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Role Actions (Phase 8 — US6)\n// ---------------------------------------------------------------------------\n\n/**\n * Assembles a `grantRole(bytes32 role, address account)` transaction.\n *\n * Grants a role to an account. Must be called by an account with the role's\n * admin role (typically DEFAULT_ADMIN_ROLE for newly created roles).\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param roleId - The bytes32 role identifier\n * @param account - The account to grant the role to (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleGrantRoleAction(\n contractAddress: string,\n roleId: string,\n account: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: GRANT_ROLE_ABI,\n functionName: 'grantRole',\n args: [roleId, account],\n };\n}\n\n/**\n * Assembles a `revokeRole(bytes32 role, address account)` transaction.\n *\n * Revokes a role from an account. Must be called by an account with the\n * role's admin role.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param roleId - The bytes32 role identifier\n * @param account - The account to revoke the role from (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleRevokeRoleAction(\n contractAddress: string,\n roleId: string,\n account: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: REVOKE_ROLE_ABI,\n functionName: 'revokeRole',\n args: [roleId, account],\n };\n}\n\n/**\n * Assembles a `renounceRole(bytes32 role, address callerConfirmation)` transaction.\n *\n * Renounces a role from the caller's own account. The `callerConfirmation` parameter\n * must match the caller's address — this is an on-chain safety check to prevent\n * accidental renouncement.\n *\n * **EVM-specific extension** — Stellar uses `revokeRole` for self-revocation instead\n * of a separate `renounceRole` function.\n *\n * @param contractAddress - The target contract address (0x-prefixed)\n * @param roleId - The bytes32 role identifier\n * @param account - The caller's address for confirmation (0x-prefixed)\n * @returns WriteContractParameters ready for execution\n */\nexport function assembleRenounceRoleAction(\n contractAddress: string,\n roleId: string,\n account: string\n): WriteContractParameters {\n return {\n address: contractAddress as `0x${string}`,\n abi: RENOUNCE_ROLE_ABI,\n functionName: 'renounceRole',\n args: [roleId, account],\n };\n}\n","/**\n * EVM Access Control Constants\n *\n * Shared constants for the access control module.\n * These values match OpenZeppelin's Solidity AccessControl contract definitions.\n *\n * @module access-control/constants\n */\n\n/**\n * The bytes32 zero value used by OpenZeppelin AccessControl as the default admin role.\n * This is `keccak256(\"\")` equivalent — the admin role that governs all other roles by default.\n *\n * @see https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl-DEFAULT_ADMIN_ROLE--\n */\nexport const DEFAULT_ADMIN_ROLE =\n '0x0000000000000000000000000000000000000000000000000000000000000000' as const;\n\n/**\n * Human-readable label for the default admin role.\n * Used when displaying role information in the Role Manager UI.\n */\nexport const DEFAULT_ADMIN_ROLE_LABEL = 'DEFAULT_ADMIN_ROLE' as const;\n\n/**\n * The EVM zero address (20 bytes of zeros).\n * Indicates renounced ownership or admin when returned by `owner()` or `defaultAdmin()`.\n */\nexport const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' as const;\n\n/**\n * Well-known OpenZeppelin role hashes (pre-computed keccak256) mapped to human-readable labels.\n * Used for instant label resolution without on-chain calls.\n *\n * @see https://docs.openzeppelin.com/contracts/5.x/api/access\n */\nexport const WELL_KNOWN_ROLES: Record<string, string> = {\n [DEFAULT_ADMIN_ROLE]: DEFAULT_ADMIN_ROLE_LABEL,\n '0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6': 'MINTER_ROLE',\n '0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a': 'PAUSER_ROLE',\n '0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848': 'BURNER_ROLE',\n '0x189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3': 'UPGRADER_ROLE',\n};\n\n/**\n * Resolves a human-readable label for a role hash.\n * Checks the per-contract label map first (external + ABI labels),\n * then falls back to the well-known dictionary.\n *\n * @param roleId - bytes32 role identifier (0x-prefixed hex)\n * @param roleLabelMap - Optional per-contract map of hash -> label (external + ABI-extracted)\n * @returns Label string or undefined if not found\n */\nexport function resolveRoleLabel(\n roleId: string,\n roleLabelMap?: Map<string, string>\n): string | undefined {\n const normalized = roleId.toLowerCase();\n return roleLabelMap?.get(normalized) ?? WELL_KNOWN_ROLES[normalized];\n}\n","/**\n * EVM Access Control Feature Detection\n *\n * Detects access control capabilities by analyzing a contract's ABI (via ContractSchema).\n * Checks function names AND parameter types against known OpenZeppelin signatures to\n * avoid false positives from similarly-named functions.\n *\n * Supports detection of:\n * - Ownable / Ownable2Step\n * - AccessControl\n * - AccessControlEnumerable\n * - AccessControlDefaultAdminRules (including admin delay operations)\n *\n * @module access-control/feature-detection\n * @see research.md §R4 — Feature Detection via ABI Analysis\n * @see contracts/feature-detection.ts — Detection matrix\n */\n\nimport type { AccessControlCapabilities, ContractSchema } from '@openzeppelin/ui-types';\n\nimport {\n ACCESS_CONTROL_SIGNATURES,\n ADMIN_DELAY_CHANGE_SIGNATURES,\n DEFAULT_ADMIN_RULES_SIGNATURES,\n ENUMERABLE_SIGNATURES,\n OWNABLE_SIGNATURES,\n OWNABLE_TWO_STEP_SIGNATURES,\n} from './abis';\n\n// ---------------------------------------------------------------------------\n// Internal Types\n// ---------------------------------------------------------------------------\n\n/** Describes a function signature for matching against the ABI */\ninterface FunctionSignature {\n readonly name: string;\n readonly inputs: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Internal Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a lookup map from the contract schema's functions array.\n * Key is the function name; value is an array of input type arrays\n * (to handle overloaded functions with the same name but different params).\n */\nfunction buildFunctionLookup(contractSchema: ContractSchema): Map<string, string[][]> {\n const lookup = new Map<string, string[][]>();\n\n for (const fn of contractSchema.functions) {\n const inputTypes = fn.inputs.map((input) => input.type);\n const existing = lookup.get(fn.name);\n if (existing) {\n existing.push(inputTypes);\n } else {\n lookup.set(fn.name, [inputTypes]);\n }\n }\n\n return lookup;\n}\n\n/**\n * Checks whether a specific function signature exists in the lookup.\n * Matches both the function name and the parameter types.\n */\nfunction hasFunction(lookup: Map<string, string[][]>, sig: FunctionSignature): boolean {\n const overloads = lookup.get(sig.name);\n if (!overloads) return false;\n\n return overloads.some((inputTypes) => {\n if (inputTypes.length !== sig.inputs.length) return false;\n return inputTypes.every((type, i) => type === sig.inputs[i]);\n });\n}\n\n/**\n * Checks whether ALL signatures in a set are present in the lookup.\n */\nfunction hasAllFunctions(\n lookup: Map<string, string[][]>,\n signatures: readonly FunctionSignature[]\n): boolean {\n return signatures.every((sig) => hasFunction(lookup, sig));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Detect access control capabilities from a contract's ABI.\n *\n * Analyzes `ContractSchema.functions` for the presence of OpenZeppelin\n * access control function signatures, checking both function names AND\n * parameter types for accuracy.\n *\n * @param contractSchema - Parsed contract schema with functions array\n * @param indexerAvailable - Whether an indexer endpoint is configured and reachable\n * @returns Detected capabilities flags\n */\nexport function detectAccessControlCapabilities(\n contractSchema: ContractSchema,\n indexerAvailable = false\n): AccessControlCapabilities {\n const lookup = buildFunctionLookup(contractSchema);\n\n // ── Ownable Detection ─────────────────────────────────────────────\n const hasOwnable = hasAllFunctions(lookup, OWNABLE_SIGNATURES);\n\n // ── Ownable2Step Detection ────────────────────────────────────────\n const hasTwoStepOwnable = hasOwnable && hasAllFunctions(lookup, OWNABLE_TWO_STEP_SIGNATURES);\n\n // ── AccessControl Detection ───────────────────────────────────────\n const hasAccessControl = hasAllFunctions(lookup, ACCESS_CONTROL_SIGNATURES);\n\n // ── AccessControlEnumerable Detection ─────────────────────────────\n const hasEnumerableRoles = hasAccessControl && hasAllFunctions(lookup, ENUMERABLE_SIGNATURES);\n\n // ── AccessControlDefaultAdminRules Detection ──────────────────────\n const hasTwoStepAdmin =\n hasAccessControl && hasAllFunctions(lookup, DEFAULT_ADMIN_RULES_SIGNATURES);\n\n // ── Renounce Ownership Detection ─────────────────────────────────\n // renounceOwnership() is available on all Ownable contracts\n const hasRenounceOwnership =\n hasOwnable && hasFunction(lookup, { name: 'renounceOwnership', inputs: [] });\n\n // ── Renounce Role Detection ──────────────────────────────────────\n // renounceRole(bytes32, address) is available on all AccessControl contracts\n const hasRenounceRole =\n hasAccessControl &&\n hasFunction(lookup, { name: 'renounceRole', inputs: ['bytes32', 'address'] });\n\n // ── Cancel Admin Transfer Detection ──────────────────────────────\n // cancelDefaultAdminTransfer() is part of AccessControlDefaultAdminRules\n const hasCancelAdminTransfer =\n hasTwoStepAdmin && hasFunction(lookup, { name: 'cancelDefaultAdminTransfer', inputs: [] });\n\n // ── Admin Delay Management Detection ─────────────────────────────\n // changeDefaultAdminDelay(uint48) + rollbackDefaultAdminDelay() from AccessControlDefaultAdminRules\n const hasAdminDelayManagement =\n hasTwoStepAdmin && hasAllFunctions(lookup, ADMIN_DELAY_CHANGE_SIGNATURES);\n\n // ── History Support ───────────────────────────────────────────────\n const supportsHistory = indexerAvailable;\n\n // ── OZ Interface Verification ─────────────────────────────────────\n // For EVM, ABI-based detection is sufficient. Unlike Stellar, EVM does not\n // have \"optional\" functions in the same sense. If the required functions are\n // present with correct signatures, the contract conforms to the OZ interface.\n // We set verifiedAgainstOZInterfaces = true if at least one pattern is detected.\n const verifiedAgainstOZInterfaces = hasOwnable || hasAccessControl;\n\n // ── Notes ─────────────────────────────────────────────────────────\n const notes: string[] = [];\n\n if (hasOwnable) {\n if (hasTwoStepOwnable) {\n notes.push(\n 'OpenZeppelin Ownable2Step interface detected (with pendingOwner + acceptOwnership)'\n );\n } else {\n notes.push('OpenZeppelin Ownable interface detected');\n }\n }\n\n if (hasAccessControl) {\n if (hasTwoStepAdmin) {\n notes.push('OpenZeppelin AccessControlDefaultAdminRules interface detected');\n } else {\n notes.push('OpenZeppelin AccessControl interface detected');\n }\n\n if (hasEnumerableRoles) {\n notes.push('Role enumeration supported (getRoleMemberCount, getRoleMember)');\n } else {\n notes.push('Role enumeration not available — requires known role IDs or indexer discovery');\n }\n }\n\n if (!indexerAvailable && (hasOwnable || hasAccessControl)) {\n notes.push('History queries unavailable without indexer configuration');\n }\n\n if (!hasOwnable && !hasAccessControl) {\n notes.push('No OpenZeppelin access control interfaces detected');\n }\n\n return {\n hasOwnable,\n hasTwoStepOwnable,\n hasAccessControl,\n hasTwoStepAdmin,\n hasEnumerableRoles,\n supportsHistory,\n verifiedAgainstOZInterfaces,\n notes: notes.length > 0 ? notes : undefined,\n hasRenounceOwnership,\n hasRenounceRole,\n hasCancelAdminTransfer,\n hasAdminDelayManagement,\n };\n}\n\n/**\n * Validate that a contract has minimum viable access control support.\n *\n * Returns `true` if the contract has at least Ownable or AccessControl.\n * Unlike the Stellar adapter's version (which throws), this returns a boolean\n * for simpler integration — callers can decide how to handle unsupported contracts.\n *\n * @param capabilities - Previously detected capabilities\n * @returns true if the contract has at least Ownable or AccessControl\n */\nexport function validateAccessControlSupport(capabilities: AccessControlCapabilities): boolean {\n return capabilities.hasOwnable || capabilities.hasAccessControl;\n}\n","/**\n * EVM Access Control Indexer Client\n *\n * Provides access to historical access control events via a GraphQL indexer.\n * Uses `fetch()` for GraphQL POST requests (available in both browser and Node.js).\n *\n * Endpoint resolution precedence:\n * 1. User-configured indexer URL (from UserNetworkServiceConfigService)\n * 2. `networkConfig.accessControlIndexerUrl`\n *\n * Graceful degradation: catches network errors, returns null/empty results\n * with appropriate logging. The service layer handles unavailability transparently.\n *\n * **Reorg handling**: Chain reorganizations are the indexer's responsibility.\n * This client treats all indexer responses as best-effort historical data.\n *\n * @module access-control/indexer-client\n * @see quickstart.md §Step 4\n * @see contracts/indexer-queries.graphql\n * @see research.md §R3 — GraphQL Indexer Client\n */\n\nimport type {\n HistoryChangeType,\n HistoryEntry,\n HistoryQueryOptions,\n PageInfo,\n PaginatedHistoryResult,\n RoleIdentifier,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { resolveAccessControlIndexerUrl } from '../configuration';\nimport type { EvmCompatibleNetworkConfig } from '../types';\nimport { DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_ROLE_LABEL, resolveRoleLabel } from './constants';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nconst LOG_SYSTEM = 'EvmIndexerClient';\n\n/** Pending ownership transfer enrichment data from the indexer */\nexport interface PendingOwnershipTransferData {\n /** Address of the pending new owner */\n pendingOwner: string;\n /** ISO8601 timestamp of the initiation event */\n initiatedAt: string;\n /** Transaction hash of the initiation event */\n initiatedTxId: string;\n /** Block number of the initiation event */\n initiatedBlock: number;\n}\n\n/** Pending admin transfer enrichment data from the indexer */\nexport interface PendingAdminTransferData {\n /** Address of the pending new admin */\n pendingAdmin: string;\n /** UNIX timestamp (seconds) at which the transfer can be accepted */\n acceptSchedule: number;\n /** ISO8601 timestamp of the initiation event */\n initiatedAt: string;\n /** Transaction hash of the initiation event */\n initiatedTxId: string;\n /** Block number of the initiation event */\n initiatedBlock: number;\n}\n\n/** Grant info data returned from queryLatestGrants */\nexport interface GrantInfo {\n /** The account address */\n account: string;\n /** The role ID */\n role: string;\n /** ISO8601 timestamp of the grant event */\n grantedAt: string;\n /** Transaction hash of the grant event */\n txHash: string;\n /** Who granted the role */\n grantedBy?: string;\n}\n\n/**\n * Build the composite key used for grant map lookups.\n *\n * Keys on `role:account` (both lowercased) so that an account holding\n * multiple roles gets a distinct entry per role, avoiding stale grant\n * metadata cross-contamination.\n *\n * @param roleId - The bytes32 role identifier\n * @param account - The account address\n * @returns A composite key in the form `roleId:account` (lowercased)\n */\nexport function grantMapKey(roleId: string, account: string): string {\n return `${roleId.toLowerCase()}:${account.toLowerCase()}`;\n}\n\n/** Internal GraphQL response shape for access control events */\ninterface IndexerEventNode {\n id: string;\n eventType: string;\n blockNumber: string;\n timestamp: string;\n txHash: string;\n newOwner?: string;\n newAdmin?: string;\n acceptSchedule?: string;\n role?: string;\n account?: string;\n}\n\n/** Internal GraphQL response shape for role membership nodes */\ninterface RoleMembershipNode {\n role: string;\n account: string;\n grantedAt: string;\n grantedBy?: string;\n txHash: string;\n}\n\ninterface IndexerEventsResponse {\n data?: {\n accessControlEvents?: {\n nodes: IndexerEventNode[];\n totalCount?: number;\n pageInfo?: {\n hasNextPage: boolean;\n hasPreviousPage?: boolean;\n endCursor?: string;\n };\n };\n };\n errors?: Array<{ message: string }>;\n}\n\ninterface IndexerDiscoverRolesResponse {\n data?: {\n accessControlEvents?: {\n nodes: Array<{ role?: string | null }>;\n };\n };\n errors?: Array<{ message: string }>;\n}\n\ninterface IndexerRoleMembershipsResponse {\n data?: {\n roleMemberships?: {\n nodes: RoleMembershipNode[];\n };\n };\n errors?: Array<{ message: string }>;\n}\n\n// ---------------------------------------------------------------------------\n// GraphQL Queries\n// ---------------------------------------------------------------------------\n\nconst HEALTH_CHECK_QUERY = '{ __typename }';\n\nconst PENDING_OWNERSHIP_TRANSFER_QUERY = `\n query GetPendingOwnershipTransfer($network: String!, $contract: String!) {\n accessControlEvents(\n filter: {\n network: { equalTo: $network }\n contract: { equalTo: $contract }\n eventType: { equalTo: OWNERSHIP_TRANSFER_STARTED }\n }\n first: 1\n orderBy: TIMESTAMP_DESC\n ) {\n nodes {\n id\n eventType\n blockNumber\n timestamp\n txHash\n newOwner\n }\n }\n }\n`;\n\nconst ROLE_MEMBERSHIPS_QUERY = `\n query GetRoleMembers($network: String!, $contract: String!, $roles: [String!]) {\n roleMemberships(\n filter: {\n network: { equalTo: $network }\n contract: { equalTo: $contract }\n role: { in: $roles }\n }\n orderBy: GRANTED_AT_DESC\n ) {\n nodes {\n role\n account\n grantedAt\n grantedBy\n txHash\n }\n }\n }\n`;\n\nconst DISCOVER_ROLES_QUERY = `\n query DiscoverRoles($network: String!, $contract: String!) {\n accessControlEvents(\n filter: {\n network: { equalTo: $network }\n contract: { equalTo: $contract }\n }\n first: 1000\n orderBy: TIMESTAMP_DESC\n ) {\n nodes {\n role\n }\n }\n }\n`;\n\nconst PENDING_ADMIN_TRANSFER_QUERY = `\n query GetPendingAdminTransfer($network: String!, $contract: String!) {\n accessControlEvents(\n filter: {\n network: { equalTo: $network }\n contract: { equalTo: $contract }\n eventType: { in: [DEFAULT_ADMIN_TRANSFER_SCHEDULED, ADMIN_TRANSFER_INITIATED] }\n }\n first: 1\n orderBy: TIMESTAMP_DESC\n ) {\n nodes {\n id\n eventType\n blockNumber\n timestamp\n txHash\n newAdmin\n acceptSchedule\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// EVM Event Type → HistoryChangeType Mapping (research.md §R6)\n// ---------------------------------------------------------------------------\n\n/**\n * Maps all 13 EVM indexer event types to unified HistoryChangeType values.\n *\n * 10 types map directly. 3 EVM-specific types (DEFAULT_ADMIN_TRANSFER_CANCELED,\n * DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED, DEFAULT_ADMIN_DELAY_CHANGE_CANCELED)\n * map to their PR-2 variants (ADMIN_TRANSFER_CANCELED, ADMIN_DELAY_CHANGE_SCHEDULED,\n * ADMIN_DELAY_CHANGE_CANCELED) which are now available in @openzeppelin/ui-types@1.7.0.\n *\n * DEFAULT_ADMIN_TRANSFER_SCHEDULED is an EVM-specific alias for ADMIN_TRANSFER_INITIATED.\n */\nconst EVM_EVENT_TYPE_TO_CHANGE_TYPE: Record<string, HistoryChangeType> = {\n ROLE_GRANTED: 'GRANTED',\n ROLE_REVOKED: 'REVOKED',\n ROLE_ADMIN_CHANGED: 'ROLE_ADMIN_CHANGED',\n OWNERSHIP_TRANSFER_STARTED: 'OWNERSHIP_TRANSFER_STARTED',\n OWNERSHIP_TRANSFER_COMPLETED: 'OWNERSHIP_TRANSFER_COMPLETED',\n OWNERSHIP_RENOUNCED: 'OWNERSHIP_RENOUNCED',\n ADMIN_TRANSFER_INITIATED: 'ADMIN_TRANSFER_INITIATED',\n ADMIN_TRANSFER_COMPLETED: 'ADMIN_TRANSFER_COMPLETED',\n ADMIN_RENOUNCED: 'ADMIN_RENOUNCED',\n // EVM-specific aliases\n DEFAULT_ADMIN_TRANSFER_SCHEDULED: 'ADMIN_TRANSFER_INITIATED',\n DEFAULT_ADMIN_TRANSFER_CANCELED: 'ADMIN_TRANSFER_CANCELED',\n DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED: 'ADMIN_DELAY_CHANGE_SCHEDULED',\n DEFAULT_ADMIN_DELAY_CHANGE_CANCELED: 'ADMIN_DELAY_CHANGE_CANCELED',\n};\n\n/**\n * Reverse mapping: HistoryChangeType → EVM indexer GraphQL enum value.\n * Used to filter by event type in history queries.\n */\nconst CHANGE_TYPE_TO_EVENT_TYPE: Record<HistoryChangeType, string> = {\n GRANTED: 'ROLE_GRANTED',\n REVOKED: 'ROLE_REVOKED',\n ROLE_ADMIN_CHANGED: 'ROLE_ADMIN_CHANGED',\n OWNERSHIP_TRANSFER_STARTED: 'OWNERSHIP_TRANSFER_STARTED',\n OWNERSHIP_TRANSFER_COMPLETED: 'OWNERSHIP_TRANSFER_COMPLETED',\n OWNERSHIP_RENOUNCED: 'OWNERSHIP_RENOUNCED',\n ADMIN_TRANSFER_INITIATED: 'ADMIN_TRANSFER_INITIATED',\n ADMIN_TRANSFER_COMPLETED: 'ADMIN_TRANSFER_COMPLETED',\n ADMIN_TRANSFER_CANCELED: 'DEFAULT_ADMIN_TRANSFER_CANCELED',\n ADMIN_RENOUNCED: 'ADMIN_RENOUNCED',\n ADMIN_DELAY_CHANGE_SCHEDULED: 'DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED',\n ADMIN_DELAY_CHANGE_CANCELED: 'DEFAULT_ADMIN_DELAY_CHANGE_CANCELED',\n UNKNOWN: 'UNKNOWN',\n};\n\n// ---------------------------------------------------------------------------\n// Client Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * EVM Indexer Client\n *\n * Handles GraphQL queries to the configured indexer for historical access control data.\n * The client is designed for graceful degradation — all query methods return null\n * instead of throwing when the indexer is unavailable.\n */\nexport class EvmIndexerClient {\n private readonly networkConfig: EvmCompatibleNetworkConfig;\n private readonly endpoint: string | undefined;\n private availabilityChecked = false;\n private available = false;\n\n constructor(networkConfig: EvmCompatibleNetworkConfig) {\n this.networkConfig = networkConfig;\n this.endpoint = resolveAccessControlIndexerUrl(networkConfig);\n }\n\n // ── Availability ──────────────────────────────────────────────────────\n\n /**\n * Check if the indexer is available and configured.\n *\n * Performs a lightweight health check (`{ __typename }`) on the first call,\n * then caches the result for subsequent calls.\n *\n * @returns true if the indexer endpoint is configured and responds to health checks\n */\n async isAvailable(): Promise<boolean> {\n if (this.availabilityChecked) {\n return this.available;\n }\n\n if (!this.endpoint) {\n logger.info(LOG_SYSTEM, `No indexer configured for network ${this.networkConfig.id}`);\n this.availabilityChecked = true;\n this.available = false;\n return false;\n }\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ query: HEALTH_CHECK_QUERY }),\n });\n\n if (response.ok) {\n logger.info(\n LOG_SYSTEM,\n `Indexer available for network ${this.networkConfig.id} at ${this.endpoint}`\n );\n this.available = true;\n } else {\n logger.warn(\n LOG_SYSTEM,\n `Indexer endpoint ${this.endpoint} returned status ${response.status}`\n );\n this.available = false;\n }\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to connect to indexer at ${this.endpoint}: ${error instanceof Error ? error.message : String(error)}`\n );\n this.available = false;\n }\n\n this.availabilityChecked = true;\n return this.available;\n }\n\n // ── Pending Ownership Transfer ────────────────────────────────────────\n\n /**\n * Query the indexer for the latest pending ownership transfer event.\n *\n * Queries for `OWNERSHIP_TRANSFER_STARTED` events, ordered by timestamp descending.\n * Returns the most recent event if found, or null if no pending transfer exists.\n *\n * Graceful degradation: returns null if the indexer is unavailable or the query fails.\n *\n * @param contractAddress - The contract address to query\n * @returns Pending transfer data or null\n */\n async queryPendingOwnershipTransfer(\n contractAddress: string\n ): Promise<PendingOwnershipTransferData | null> {\n const isUp = await this.isAvailable();\n if (!isUp || !this.endpoint) {\n return null;\n }\n\n logger.info(LOG_SYSTEM, `Querying pending ownership transfer for ${contractAddress}`);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: PENDING_OWNERSHIP_TRANSFER_QUERY,\n variables: {\n network: this.networkConfig.id,\n contract: contractAddress,\n },\n }),\n });\n\n if (!response.ok) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query failed with status ${response.status} for ownership transfer`\n );\n return null;\n }\n\n const result = (await response.json()) as IndexerEventsResponse;\n\n if (result.errors && result.errors.length > 0) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query errors: ${result.errors.map((e) => e.message).join('; ')}`\n );\n return null;\n }\n\n const nodes = result.data?.accessControlEvents?.nodes;\n if (!nodes || nodes.length === 0) {\n logger.debug(LOG_SYSTEM, `No pending ownership transfer found for ${contractAddress}`);\n return null;\n }\n\n const event = nodes[0];\n\n if (!event.newOwner) {\n logger.warn(\n LOG_SYSTEM,\n `OWNERSHIP_TRANSFER_STARTED event missing newOwner for ${contractAddress}`\n );\n return null;\n }\n\n return {\n pendingOwner: event.newOwner,\n initiatedAt: event.timestamp,\n initiatedTxId: event.txHash,\n initiatedBlock: parseInt(event.blockNumber, 10),\n };\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to query pending ownership transfer: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n\n // ── Pending Admin Transfer ────────────────────────────────────────────\n\n /**\n * Query the indexer for the latest pending admin transfer event.\n *\n * Queries for `DEFAULT_ADMIN_TRANSFER_SCHEDULED` or `ADMIN_TRANSFER_INITIATED` events,\n * ordered by timestamp descending. Returns the most recent event if found,\n * or null if no pending transfer exists.\n *\n * Graceful degradation: returns null if the indexer is unavailable or the query fails.\n *\n * @param contractAddress - The contract address to query\n * @returns Pending admin transfer data or null\n */\n async queryPendingAdminTransfer(\n contractAddress: string\n ): Promise<PendingAdminTransferData | null> {\n const isUp = await this.isAvailable();\n if (!isUp || !this.endpoint) {\n return null;\n }\n\n logger.info(LOG_SYSTEM, `Querying pending admin transfer for ${contractAddress}`);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: PENDING_ADMIN_TRANSFER_QUERY,\n variables: {\n network: this.networkConfig.id,\n contract: contractAddress,\n },\n }),\n });\n\n if (!response.ok) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query failed with status ${response.status} for admin transfer`\n );\n return null;\n }\n\n const result = (await response.json()) as IndexerEventsResponse;\n\n if (result.errors && result.errors.length > 0) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query errors: ${result.errors.map((e) => e.message).join('; ')}`\n );\n return null;\n }\n\n const nodes = result.data?.accessControlEvents?.nodes;\n if (!nodes || nodes.length === 0) {\n logger.debug(LOG_SYSTEM, `No pending admin transfer found for ${contractAddress}`);\n return null;\n }\n\n const event = nodes[0];\n\n if (!event.newAdmin) {\n logger.warn(LOG_SYSTEM, `Admin transfer event missing newAdmin for ${contractAddress}`);\n return null;\n }\n\n return {\n pendingAdmin: event.newAdmin,\n acceptSchedule: event.acceptSchedule ? parseInt(event.acceptSchedule, 10) : 0,\n initiatedAt: event.timestamp,\n initiatedTxId: event.txHash,\n initiatedBlock: parseInt(event.blockNumber, 10),\n };\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to query pending admin transfer: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n\n // ── Role Membership Queries (Phase 5 — US3) ────────────────────────────\n\n /**\n * Query the indexer for current role membership grant data.\n *\n * Queries `roleMemberships` for the specified roles, returning a map of\n * `role:account → GrantInfo` for enrichment of role assignments. The composite\n * key ensures that an account holding multiple roles retains distinct grant\n * metadata per role. Use {@link grantMapKey} to build lookup keys.\n *\n * Returns an empty Map if roleIds is empty. Returns null if the indexer\n * is unavailable or the query fails (graceful degradation).\n *\n * @param contractAddress - The contract address to query\n * @param roleIds - Array of bytes32 role IDs to query\n * @returns Map of `role:account` composite key to GrantInfo, or null on failure\n */\n async queryLatestGrants(\n contractAddress: string,\n roleIds: string[]\n ): Promise<Map<string, GrantInfo> | null> {\n if (roleIds.length === 0) {\n return new Map();\n }\n\n const isUp = await this.isAvailable();\n if (!isUp || !this.endpoint) {\n return null;\n }\n\n logger.info(\n LOG_SYSTEM,\n `Querying latest grants for ${roleIds.length} role(s) on ${contractAddress}`\n );\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: ROLE_MEMBERSHIPS_QUERY,\n variables: {\n network: this.networkConfig.id,\n contract: contractAddress,\n roles: roleIds,\n },\n }),\n });\n\n if (!response.ok) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query failed with status ${response.status} for role memberships`\n );\n return null;\n }\n\n const result = (await response.json()) as IndexerRoleMembershipsResponse;\n\n if (result.errors && result.errors.length > 0) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query errors: ${result.errors.map((e) => e.message).join('; ')}`\n );\n return null;\n }\n\n const nodes = result.data?.roleMemberships?.nodes;\n if (!nodes || nodes.length === 0) {\n logger.debug(LOG_SYSTEM, `No role membership data found for ${contractAddress}`);\n return new Map();\n }\n\n // Build map of role:account → GrantInfo (composite key prevents\n // cross-role contamination when an account holds multiple roles)\n const grantMap = new Map<string, GrantInfo>();\n for (const node of nodes) {\n const key = grantMapKey(node.role, node.account);\n // Keep only the first (most recent) grant per role+account since ordered by GRANTED_AT_DESC\n if (!grantMap.has(key)) {\n grantMap.set(key, {\n account: node.account,\n role: node.role,\n grantedAt: node.grantedAt,\n txHash: node.txHash,\n grantedBy: node.grantedBy,\n });\n }\n }\n\n logger.debug(\n LOG_SYSTEM,\n `Found grant info for ${grantMap.size} member(s) across ${roleIds.length} role(s)`\n );\n\n return grantMap;\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to query latest grants: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n\n // ── Role Discovery (Phase 11 — US9) ────────────────────────────────────\n\n /**\n * Discover all unique role identifiers for a contract by querying historical events.\n *\n * Queries all `accessControlEvents` for the contract and extracts unique, non-empty\n * `role` values. This enables role enumeration even when `knownRoleIds` are not\n * provided at registration.\n *\n * Graceful degradation: returns null if the indexer is unavailable or the query fails.\n *\n * @param contractAddress - The contract address to discover roles for\n * @returns Array of unique role identifiers, or null on failure\n */\n async discoverRoleIds(contractAddress: string): Promise<string[] | null> {\n const isUp = await this.isAvailable();\n if (!isUp || !this.endpoint) {\n return null;\n }\n\n logger.info(LOG_SYSTEM, `Discovering role IDs for ${contractAddress}`);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: DISCOVER_ROLES_QUERY,\n variables: {\n network: this.networkConfig.id,\n contract: contractAddress,\n },\n }),\n });\n\n if (!response.ok) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query failed with status ${response.status} for role discovery`\n );\n return null;\n }\n\n const result = (await response.json()) as IndexerDiscoverRolesResponse;\n\n if (result.errors && result.errors.length > 0) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query errors: ${result.errors.map((e) => e.message).join('; ')}`\n );\n return null;\n }\n\n const nodes = result.data?.accessControlEvents?.nodes;\n if (!nodes || nodes.length === 0) {\n logger.debug(LOG_SYSTEM, `No events found for role discovery on ${contractAddress}`);\n return [];\n }\n\n // Extract unique, non-empty role values\n const uniqueRoles = [...new Set(nodes.map((n) => n.role).filter((r): r is string => !!r))];\n\n logger.debug(\n LOG_SYSTEM,\n `Discovered ${uniqueRoles.length} unique role(s) for ${contractAddress}`\n );\n\n return uniqueRoles;\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to discover role IDs: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n\n // ── History Queries (Phase 9 — US7) ────────────────────────────────────\n\n /**\n * Query historical access control events with filtering and pagination.\n *\n * Queries `accessControlEvents` with the specified filters. All 13 EVM event types\n * are mapped to `HistoryChangeType` values per research.md §R6.\n *\n * Graceful degradation: returns null if the indexer is unavailable or the query fails.\n *\n * @param contractAddress - The contract address to query\n * @param options - Optional filtering and pagination options\n * @returns Paginated history result, or null on failure\n */\n async queryHistory(\n contractAddress: string,\n options?: HistoryQueryOptions,\n roleLabelMap?: Map<string, string>\n ): Promise<PaginatedHistoryResult | null> {\n const isUp = await this.isAvailable();\n if (!isUp || !this.endpoint) {\n return null;\n }\n\n logger.info(LOG_SYSTEM, `Querying history for ${contractAddress}`);\n\n const query = this.buildHistoryQuery(options);\n const variables = this.buildHistoryVariables(contractAddress, options);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ query, variables }),\n });\n\n if (!response.ok) {\n logger.warn(LOG_SYSTEM, `Indexer query failed with status ${response.status} for history`);\n return null;\n }\n\n const result = (await response.json()) as IndexerEventsResponse;\n\n if (result.errors && result.errors.length > 0) {\n logger.warn(\n LOG_SYSTEM,\n `Indexer query errors: ${result.errors.map((e) => e.message).join('; ')}`\n );\n return null;\n }\n\n const nodes = result.data?.accessControlEvents?.nodes;\n if (!nodes || nodes.length === 0) {\n logger.debug(LOG_SYSTEM, `No history events found for ${contractAddress}`);\n return {\n items: [],\n pageInfo: { hasNextPage: false },\n };\n }\n\n const items = this.transformToHistoryEntries(nodes, roleLabelMap);\n const pageInfo: PageInfo = {\n hasNextPage: result.data?.accessControlEvents?.pageInfo?.hasNextPage ?? false,\n endCursor: result.data?.accessControlEvents?.pageInfo?.endCursor,\n };\n\n logger.debug(LOG_SYSTEM, `Retrieved ${items.length} history event(s) for ${contractAddress}`);\n\n return { items, pageInfo };\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to query history: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n\n // ── Private Helpers ────────────────────────────────────────────────────\n\n /**\n * Builds the dynamic GraphQL history query with conditional filter clauses.\n *\n * Filter conditions are added only when the corresponding option is present.\n * EventType filter uses inline GraphQL enum values (not quoted strings).\n */\n private buildHistoryQuery(options?: HistoryQueryOptions): string {\n const roleFilter = options?.roleId ? ', role: { equalTo: $role }' : '';\n const accountFilter = options?.account ? ', account: { equalTo: $account }' : '';\n const typeFilter = options?.changeType\n ? `, eventType: { equalTo: ${CHANGE_TYPE_TO_EVENT_TYPE[options.changeType]} }`\n : '';\n const txFilter = options?.txId ? ', txHash: { equalTo: $txHash }' : '';\n\n // Build combined timestamp filter\n const timestampConditions: string[] = [];\n if (options?.timestampFrom) {\n timestampConditions.push('greaterThanOrEqualTo: $timestampFrom');\n }\n if (options?.timestampTo) {\n timestampConditions.push('lessThanOrEqualTo: $timestampTo');\n }\n const timestampFilter =\n timestampConditions.length > 0 ? `, timestamp: { ${timestampConditions.join(', ')} }` : '';\n\n const ledgerFilter = options?.ledger ? ', blockNumber: { equalTo: $blockNumber }' : '';\n const limitClause = options?.limit ? ', first: $limit' : '';\n const cursorClause = options?.cursor ? ', after: $cursor' : '';\n\n // Build variable declarations\n const varDeclarations = [\n '$network: String!',\n '$contract: String!',\n options?.roleId ? '$role: String' : '',\n options?.account ? '$account: String' : '',\n options?.txId ? '$txHash: String' : '',\n options?.timestampFrom ? '$timestampFrom: Datetime' : '',\n options?.timestampTo ? '$timestampTo: Datetime' : '',\n options?.ledger ? '$blockNumber: BigFloat' : '',\n options?.limit ? '$limit: Int' : '',\n options?.cursor ? '$cursor: Cursor' : '',\n ]\n .filter(Boolean)\n .join(', ');\n\n return `\n query GetHistory(${varDeclarations}) {\n accessControlEvents(\n filter: {\n network: { equalTo: $network }\n contract: { equalTo: $contract }${roleFilter}${accountFilter}${typeFilter}${txFilter}${timestampFilter}${ledgerFilter}\n }\n orderBy: TIMESTAMP_DESC${limitClause}${cursorClause}\n ) {\n nodes {\n id\n eventType\n blockNumber\n timestamp\n txHash\n role\n account\n newOwner\n newAdmin\n acceptSchedule\n }\n totalCount\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n `;\n }\n\n /**\n * Builds query variables for history queries, mapping options to GraphQL variables.\n */\n private buildHistoryVariables(\n contractAddress: string,\n options?: HistoryQueryOptions\n ): Record<string, unknown> {\n const variables: Record<string, unknown> = {\n network: this.networkConfig.id,\n contract: contractAddress,\n };\n\n if (options?.roleId) variables.role = options.roleId;\n if (options?.account) variables.account = options.account;\n if (options?.txId) variables.txHash = options.txId;\n if (options?.timestampFrom) variables.timestampFrom = options.timestampFrom;\n if (options?.timestampTo) variables.timestampTo = options.timestampTo;\n if (options?.ledger) variables.blockNumber = String(options.ledger);\n if (options?.limit) variables.limit = options.limit;\n if (options?.cursor) variables.cursor = options.cursor;\n\n return variables;\n }\n\n /**\n * Transforms indexer event nodes to unified HistoryEntry format.\n *\n * Maps EVM event types to HistoryChangeType, normalizes account field\n * based on event type (role → account, ownership → newOwner, admin → newAdmin),\n * and resolves the role identifier using event-type-aware logic so that\n * `role.id` is always a valid bytes32 hex string in the EVM context.\n */\n private transformToHistoryEntries(\n nodes: IndexerEventNode[],\n roleLabelMap?: Map<string, string>\n ): HistoryEntry[] {\n return nodes.map((node) => {\n const role = this.resolveRoleFromEvent(node, roleLabelMap);\n const changeType = this.mapEventTypeToChangeType(node.eventType);\n const account = this.normalizeAccountFromEvent(node);\n\n return {\n role,\n account,\n changeType,\n txId: node.txHash,\n timestamp: node.timestamp,\n ledger: parseInt(node.blockNumber, 10),\n };\n });\n }\n\n /**\n * Resolves the RoleIdentifier from an indexer event node based on event type.\n *\n * - **Role events** (ROLE_GRANTED, ROLE_REVOKED, ROLE_ADMIN_CHANGED): Use the\n * actual `node.role` bytes32 value from the indexed event; label from\n * roleLabelMap or well-known dictionary.\n * - **Ownership events** (OWNERSHIP_*): The Ownable pattern has no AccessControl\n * role, so we use `DEFAULT_ADMIN_ROLE` (bytes32 zero) as a canonical sentinel\n * with `label: 'OWNER'` for display context.\n * - **Admin events** (ADMIN_*, DEFAULT_ADMIN_*): These events concern the default\n * admin role, so we use `DEFAULT_ADMIN_ROLE` with its standard label.\n *\n * This ensures `role.id` is always a valid bytes32 hex string, maintaining\n * consistency with EVM's address/role format conventions. Consumers can use\n * `role.label` to distinguish ownership vs. admin events.\n */\n private resolveRoleFromEvent(\n node: IndexerEventNode,\n roleLabelMap?: Map<string, string>\n ): RoleIdentifier {\n const roleId = node.role || DEFAULT_ADMIN_ROLE;\n switch (node.eventType) {\n // Role events — use the actual bytes32 role from the indexed event\n case 'ROLE_GRANTED':\n case 'ROLE_REVOKED':\n case 'ROLE_ADMIN_CHANGED':\n return {\n id: roleId,\n label: resolveRoleLabel(roleId, roleLabelMap),\n };\n\n // Ownership events — no AccessControl role; use bytes32 zero as sentinel\n case 'OWNERSHIP_TRANSFER_STARTED':\n case 'OWNERSHIP_TRANSFER_COMPLETED':\n case 'OWNERSHIP_RENOUNCED':\n return {\n id: DEFAULT_ADMIN_ROLE,\n label: 'OWNER',\n };\n\n // Admin events — semantically about the default admin role\n case 'ADMIN_TRANSFER_INITIATED':\n case 'ADMIN_TRANSFER_COMPLETED':\n case 'ADMIN_RENOUNCED':\n case 'DEFAULT_ADMIN_TRANSFER_SCHEDULED':\n case 'DEFAULT_ADMIN_TRANSFER_CANCELED':\n case 'DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED':\n case 'DEFAULT_ADMIN_DELAY_CHANGE_CANCELED':\n return {\n id: DEFAULT_ADMIN_ROLE,\n label: DEFAULT_ADMIN_ROLE_LABEL,\n };\n\n // Fallback for unknown event types — preserve node.role if available\n default:\n return {\n id: roleId,\n label: resolveRoleLabel(roleId, roleLabelMap),\n };\n }\n }\n\n /**\n * Maps an EVM indexer event type string to the unified HistoryChangeType.\n * Returns 'UNKNOWN' for unrecognized event types.\n */\n private mapEventTypeToChangeType(eventType: string): HistoryChangeType {\n const mapped = EVM_EVENT_TYPE_TO_CHANGE_TYPE[eventType];\n if (mapped) {\n return mapped;\n }\n\n logger.warn(LOG_SYSTEM, `Unknown event type: ${eventType}, assigning changeType to UNKNOWN`);\n return 'UNKNOWN';\n }\n\n /**\n * Normalizes the account field from an indexer event node.\n *\n * Different event types store the relevant account in different fields:\n * - Role events (ROLE_GRANTED, ROLE_REVOKED, ROLE_ADMIN_CHANGED): `account`\n * - Ownership events: `newOwner`\n * - Admin events: `newAdmin`\n * - Fallback: `account` or empty string\n */\n private normalizeAccountFromEvent(node: IndexerEventNode): string {\n switch (node.eventType) {\n case 'ROLE_GRANTED':\n case 'ROLE_REVOKED':\n case 'ROLE_ADMIN_CHANGED':\n return node.account || '';\n\n case 'OWNERSHIP_TRANSFER_STARTED':\n case 'OWNERSHIP_TRANSFER_COMPLETED':\n case 'OWNERSHIP_RENOUNCED':\n return node.newOwner || '';\n\n case 'ADMIN_TRANSFER_INITIATED':\n case 'ADMIN_TRANSFER_COMPLETED':\n case 'ADMIN_RENOUNCED':\n case 'DEFAULT_ADMIN_TRANSFER_SCHEDULED':\n case 'DEFAULT_ADMIN_TRANSFER_CANCELED':\n case 'DEFAULT_ADMIN_DELAY_CHANGE_SCHEDULED':\n case 'DEFAULT_ADMIN_DELAY_CHANGE_CANCELED':\n return node.newAdmin || '';\n\n default:\n return node.account || '';\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an EvmIndexerClient instance for a network configuration.\n *\n * @param networkConfig - EVM network configuration (includes indexer URL)\n * @returns A new EvmIndexerClient instance\n */\nexport function createIndexerClient(networkConfig: EvmCompatibleNetworkConfig): EvmIndexerClient {\n return new EvmIndexerClient(networkConfig);\n}\n","/**\n * EVM Access Control On-Chain Reader\n *\n * Reads current access control state (ownership and admin) from EVM-compatible contracts\n * using viem public client. Each function creates a stateless viem `publicClient` per call,\n * consistent with the existing query handler pattern in `adapter-evm-core/src/query/handler.ts`.\n *\n * Supports:\n * - Ownable: `owner()` read\n * - Ownable2Step: `owner()` + `pendingOwner()` reads\n * - AccessControlDefaultAdminRules: `defaultAdmin()`, `pendingDefaultAdmin()`, `defaultAdminDelay()`\n * - AccessControl: `hasRole()`, `getRoleAdmin()`\n * - AccessControlEnumerable: `getRoleMemberCount()`, `getRoleMember()`\n * - Utility: `getCurrentBlock()`\n *\n * @module access-control/onchain-reader\n * @see quickstart.md §Step 3\n * @see research.md §R1 — On-Chain Read Strategy\n */\n\nimport type { Chain } from 'viem';\n\nimport type { RoleAssignment, RoleIdentifier } from '@openzeppelin/ui-types';\nimport { OperationFailed } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createEvmPublicClient } from '../utils/public-client';\nimport {\n DEFAULT_ADMIN_ABI,\n DEFAULT_ADMIN_DELAY_ABI,\n GET_ROLE_ADMIN_ABI,\n GET_ROLE_MEMBER_ABI,\n GET_ROLE_MEMBER_COUNT_ABI,\n HAS_ROLE_ABI,\n OWNER_ABI,\n PENDING_DEFAULT_ADMIN_ABI,\n PENDING_DEFAULT_ADMIN_DELAY_ABI,\n PENDING_OWNER_ABI,\n} from './abis';\nimport { resolveRoleLabel, ZERO_ADDRESS } from './constants';\n\n// ---------------------------------------------------------------------------\n// Internal Types\n// ---------------------------------------------------------------------------\n\n/** Result of readOwnership — raw on-chain data before state classification */\nexport interface OwnershipReadResult {\n /** Owner address, or null if zero address (renounced) */\n owner: string | null;\n /** Pending owner address (Ownable2Step), or undefined if not available */\n pendingOwner?: string;\n}\n\n/** Result of getAdmin — raw on-chain data for DefaultAdminRules */\nexport interface AdminReadResult {\n /** Default admin address, or null if zero address (renounced) */\n defaultAdmin: string | null;\n /** Pending new admin address, or undefined if no scheduled transfer */\n pendingDefaultAdmin?: string;\n /**\n * UNIX timestamp (seconds) at which the pending transfer can be accepted.\n * Only present when pendingDefaultAdmin is set.\n *\n * **Semantic note**: Despite the field name in the unified type (`expirationBlock`),\n * this is NOT a block number — it is a UNIX timestamp from the contract's\n * `pendingDefaultAdmin()` return value. See research.md §R5.\n */\n acceptSchedule?: number;\n /** Current admin delay in seconds */\n defaultAdminDelay?: number;\n /** Pending new admin delay in seconds (from `pendingDefaultAdminDelay()`) */\n pendingDefaultAdminDelay?: number;\n /** UNIX timestamp when the pending delay takes effect (from `pendingDefaultAdminDelay()`) */\n pendingDefaultAdminDelaySchedule?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal Helpers\n// ---------------------------------------------------------------------------\n\nconst LOG_SYSTEM = 'EvmOnChainReader';\n\n/** Alias for readability within this module */\nfunction createClient(rpcUrl: string, viemChain?: Chain) {\n return createEvmPublicClient(rpcUrl, viemChain);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Read the current ownership state from an Ownable / Ownable2Step contract.\n *\n * Calls `owner()` (required) and `pendingOwner()` (optional — only Ownable2Step).\n * If `pendingOwner()` reverts or returns the zero address, `pendingOwner` is undefined.\n * If `owner()` returns the zero address, `owner` is returned as `null` (renounced).\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address (0x-prefixed)\n * @param viemChain - Optional viem Chain object for the network\n * @returns Ownership read result with owner and optional pendingOwner\n * @throws OperationFailed if the `owner()` call fails\n */\nexport async function readOwnership(\n rpcUrl: string,\n contractAddress: string,\n viemChain?: Chain\n): Promise<OwnershipReadResult> {\n logger.info(LOG_SYSTEM, `Reading ownership for contract ${contractAddress}`);\n\n const client = createClient(rpcUrl, viemChain);\n const address = contractAddress as `0x${string}`;\n\n // ── owner() — required ────────────────────────────────────────────\n let ownerAddress: string;\n try {\n ownerAddress = (await client.readContract({\n address,\n abi: OWNER_ABI,\n functionName: 'owner',\n })) as string;\n } catch (error) {\n logger.error(LOG_SYSTEM, `Failed to read owner() for ${contractAddress}:`, error);\n throw new OperationFailed(\n `Failed to read ownership: ${(error as Error).message}`,\n contractAddress,\n 'readOwnership',\n error as Error\n );\n }\n\n // Normalize: zero address means renounced\n const owner = ownerAddress.toLowerCase() === ZERO_ADDRESS.toLowerCase() ? null : ownerAddress;\n\n // ── pendingOwner() — optional (Ownable2Step only) ─────────────────\n let pendingOwner: string | undefined;\n try {\n const pendingOwnerAddress = (await client.readContract({\n address,\n abi: PENDING_OWNER_ABI,\n functionName: 'pendingOwner',\n })) as string;\n\n // Zero address means no pending transfer\n if (pendingOwnerAddress.toLowerCase() !== ZERO_ADDRESS.toLowerCase()) {\n pendingOwner = pendingOwnerAddress;\n }\n } catch {\n // Contract doesn't have pendingOwner (basic Ownable) — this is expected\n logger.debug(LOG_SYSTEM, `No pendingOwner() on ${contractAddress} (basic Ownable)`);\n }\n\n logger.debug(LOG_SYSTEM, `Ownership for ${contractAddress}:`, {\n owner,\n pendingOwner: pendingOwner ?? 'none',\n });\n\n return { owner, pendingOwner };\n}\n\n/**\n * Read the current default admin state from an AccessControlDefaultAdminRules contract.\n *\n * Calls `defaultAdmin()`, `pendingDefaultAdmin()`, `defaultAdminDelay()`, and\n * `pendingDefaultAdminDelay()`.\n * If `defaultAdmin()` returns the zero address, `defaultAdmin` is returned as `null` (renounced).\n * If `pendingDefaultAdmin()` returns the zero address as the new admin, no pending transfer\n * is indicated.\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address (0x-prefixed)\n * @param viemChain - Optional viem Chain object for the network\n * @returns Admin read result with defaultAdmin, optional pendingDefaultAdmin and acceptSchedule\n * @throws OperationFailed if the `defaultAdmin()` call fails\n */\nexport async function getAdmin(\n rpcUrl: string,\n contractAddress: string,\n viemChain?: Chain\n): Promise<AdminReadResult> {\n logger.info(LOG_SYSTEM, `Reading admin info for contract ${contractAddress}`);\n\n const client = createClient(rpcUrl, viemChain);\n const address = contractAddress as `0x${string}`;\n\n // ── defaultAdmin() ────────────────────────────────────────────────\n let adminAddress: string;\n try {\n adminAddress = (await client.readContract({\n address,\n abi: DEFAULT_ADMIN_ABI,\n functionName: 'defaultAdmin',\n })) as string;\n } catch (error) {\n logger.error(LOG_SYSTEM, `Failed to read defaultAdmin() for ${contractAddress}:`, error);\n throw new OperationFailed(\n `Failed to read admin info: ${(error as Error).message}`,\n contractAddress,\n 'getAdmin',\n error as Error\n );\n }\n\n const defaultAdmin =\n adminAddress.toLowerCase() === ZERO_ADDRESS.toLowerCase() ? null : adminAddress;\n\n // ── pendingDefaultAdmin() → (address newAdmin, uint48 schedule) ──\n let pendingDefaultAdmin: string | undefined;\n let acceptSchedule: number | undefined;\n\n try {\n const result = (await client.readContract({\n address,\n abi: PENDING_DEFAULT_ADMIN_ABI,\n functionName: 'pendingDefaultAdmin',\n })) as [string, bigint];\n\n const [newAdmin, schedule] = result;\n\n // Zero address means no pending transfer\n if (newAdmin.toLowerCase() !== ZERO_ADDRESS.toLowerCase()) {\n pendingDefaultAdmin = newAdmin;\n acceptSchedule = Number(schedule);\n }\n } catch (error) {\n logger.warn(LOG_SYSTEM, `Failed to read pendingDefaultAdmin() for ${contractAddress}:`, error);\n }\n\n // ── defaultAdminDelay() → uint48 ────────────────────────────────\n let defaultAdminDelay: number | undefined;\n try {\n const delay = (await client.readContract({\n address,\n abi: DEFAULT_ADMIN_DELAY_ABI,\n functionName: 'defaultAdminDelay',\n })) as bigint;\n\n defaultAdminDelay = Number(delay);\n } catch (error) {\n logger.warn(LOG_SYSTEM, `Failed to read defaultAdminDelay() for ${contractAddress}:`, error);\n }\n\n // ── pendingDefaultAdminDelay() → (uint48 newDelay, uint48 schedule)\n let pendingDefaultAdminDelay: number | undefined;\n let pendingDefaultAdminDelaySchedule: number | undefined;\n try {\n const result = (await client.readContract({\n address,\n abi: PENDING_DEFAULT_ADMIN_DELAY_ABI,\n functionName: 'pendingDefaultAdminDelay',\n })) as [bigint, bigint];\n\n const [newDelay, schedule] = result;\n\n // (0, 0) means no pending delay change\n if (Number(schedule) !== 0) {\n pendingDefaultAdminDelay = Number(newDelay);\n pendingDefaultAdminDelaySchedule = Number(schedule);\n }\n } catch (error) {\n logger.warn(\n LOG_SYSTEM,\n `Failed to read pendingDefaultAdminDelay() for ${contractAddress}:`,\n error\n );\n }\n\n logger.debug(LOG_SYSTEM, `Admin info for ${contractAddress}:`, {\n defaultAdmin,\n pendingDefaultAdmin: pendingDefaultAdmin ?? 'none',\n acceptSchedule,\n defaultAdminDelay,\n pendingDefaultAdminDelay: pendingDefaultAdminDelay ?? 'none',\n pendingDefaultAdminDelaySchedule,\n });\n\n return {\n defaultAdmin,\n pendingDefaultAdmin,\n acceptSchedule,\n defaultAdminDelay,\n pendingDefaultAdminDelay,\n pendingDefaultAdminDelaySchedule,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Role Functions (Phase 5 — US3)\n// ---------------------------------------------------------------------------\n\n/**\n * Check if an account has a specific role on an AccessControl contract.\n *\n * Calls `hasRole(bytes32 role, address account)` and returns the boolean result.\n * Graceful degradation: returns `false` if the call reverts.\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address (0x-prefixed)\n * @param roleId - bytes32 role identifier\n * @param account - Account address to check\n * @param viemChain - Optional viem Chain object\n * @returns true if the account has the role, false otherwise\n */\nexport async function hasRole(\n rpcUrl: string,\n contractAddress: string,\n roleId: string,\n account: string,\n viemChain?: Chain\n): Promise<boolean> {\n logger.debug(LOG_SYSTEM, `Checking hasRole(${roleId}, ${account}) on ${contractAddress}`);\n\n const client = createClient(rpcUrl, viemChain);\n const address = contractAddress as `0x${string}`;\n\n try {\n const result = await client.readContract({\n address,\n abi: HAS_ROLE_ABI,\n functionName: 'hasRole',\n args: [roleId as `0x${string}`, account as `0x${string}`],\n });\n\n return result as boolean;\n } catch (error) {\n logger.debug(\n LOG_SYSTEM,\n `hasRole failed for ${roleId}/${account} on ${contractAddress}: ${(error as Error).message}`\n );\n return false;\n }\n}\n\n/**\n * Enumerate all members of a role using AccessControlEnumerable.\n *\n * Calls `getRoleMemberCount(role)` then `getRoleMember(role, index)` for each index.\n * Throws if `getRoleMemberCount` fails (contract may not be AccessControlEnumerable).\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address (0x-prefixed)\n * @param roleId - bytes32 role identifier\n * @param viemChain - Optional viem Chain object\n * @returns Array of member addresses\n * @throws OperationFailed if getRoleMemberCount fails\n */\nexport async function enumerateRoleMembers(\n rpcUrl: string,\n contractAddress: string,\n roleId: string,\n viemChain?: Chain\n): Promise<string[]> {\n logger.info(LOG_SYSTEM, `Enumerating members for role ${roleId} on ${contractAddress}`);\n\n const client = createClient(rpcUrl, viemChain);\n const address = contractAddress as `0x${string}`;\n\n // ── getRoleMemberCount ────────────────────────────────────────────\n let count: number;\n try {\n const rawCount = await client.readContract({\n address,\n abi: GET_ROLE_MEMBER_COUNT_ABI,\n functionName: 'getRoleMemberCount',\n args: [roleId as `0x${string}`],\n });\n count = Number(rawCount as bigint);\n } catch (error) {\n logger.error(LOG_SYSTEM, `Failed to get role member count for ${roleId}:`, error);\n throw new OperationFailed(\n `Failed to enumerate role members: ${(error as Error).message}`,\n contractAddress,\n 'enumerateRoleMembers',\n error as Error\n );\n }\n\n if (count === 0) {\n logger.debug(LOG_SYSTEM, `Role ${roleId} has 0 members`);\n return [];\n }\n\n // ── getRoleMember for each index ──────────────────────────────────\n const members: string[] = [];\n for (let i = 0; i < count; i++) {\n try {\n const member = await client.readContract({\n address,\n abi: GET_ROLE_MEMBER_ABI,\n functionName: 'getRoleMember',\n args: [roleId as `0x${string}`, BigInt(i)],\n });\n members.push(member as string);\n } catch (error) {\n logger.warn(LOG_SYSTEM, `Failed to get role member at index ${i} for ${roleId}:`, error);\n }\n }\n\n logger.debug(LOG_SYSTEM, `Role ${roleId}: ${members.length} of ${count} members retrieved`);\n return members;\n}\n\n/**\n * Read current role assignments for provided role IDs.\n *\n * For each role ID, enumerates members (if `hasEnumerableRoles` is true) or\n * returns the role with an empty members array (caller must check membership\n * via `hasRole` or indexer).\n *\n * Labels are resolved from the optional roleLabelMap (external + ABI-extracted),\n * then the well-known dictionary (DEFAULT_ADMIN_ROLE, MINTER_ROLE, etc.).\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address\n * @param roleIds - Array of bytes32 role identifiers\n * @param hasEnumerableRoles - Whether the contract supports AccessControlEnumerable\n * @param viemChain - Optional viem Chain object\n * @param roleLabelMap - Optional per-contract map of hash -> label for human-readable display\n * @returns Array of role assignments\n */\nexport async function readCurrentRoles(\n rpcUrl: string,\n contractAddress: string,\n roleIds: string[],\n hasEnumerableRoles: boolean,\n viemChain?: Chain,\n roleLabelMap?: Map<string, string>\n): Promise<RoleAssignment[]> {\n logger.info(\n LOG_SYSTEM,\n `Reading ${roleIds.length} role(s) for contract ${contractAddress} (enumerable: ${hasEnumerableRoles})`\n );\n\n if (roleIds.length === 0) {\n return [];\n }\n\n const assignments: RoleAssignment[] = await Promise.all(\n roleIds.map(async (roleId) => {\n const role: RoleIdentifier = {\n id: roleId,\n label: resolveRoleLabel(roleId, roleLabelMap),\n };\n\n if (!hasEnumerableRoles) {\n // Without enumeration, return role with empty members\n // (caller will use hasRole checks or indexer to discover members)\n return { role, members: [] };\n }\n\n try {\n const members = await enumerateRoleMembers(rpcUrl, contractAddress, roleId, viemChain);\n return { role, members };\n } catch (error) {\n logger.warn(LOG_SYSTEM, `Failed to enumerate role ${roleId}:`, error);\n return { role, members: [] };\n }\n })\n );\n\n logger.info(\n LOG_SYSTEM,\n `Completed reading ${assignments.length} role(s) with ${assignments.reduce((sum, a) => sum + a.members.length, 0)} total members`\n );\n\n return assignments;\n}\n\n/**\n * Get the admin role for a given role.\n *\n * Calls `getRoleAdmin(bytes32 role)` and returns the admin role ID.\n * Returns null if the call fails.\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address\n * @param roleId - bytes32 role identifier\n * @param viemChain - Optional viem Chain object\n * @returns The admin role ID (bytes32) or null if unavailable\n */\nexport async function getRoleAdmin(\n rpcUrl: string,\n contractAddress: string,\n roleId: string,\n viemChain?: Chain\n): Promise<string | null> {\n logger.debug(LOG_SYSTEM, `Getting admin role for ${roleId} on ${contractAddress}`);\n\n const client = createClient(rpcUrl, viemChain);\n const address = contractAddress as `0x${string}`;\n\n try {\n const result = await client.readContract({\n address,\n abi: GET_ROLE_ADMIN_ABI,\n functionName: 'getRoleAdmin',\n args: [roleId as `0x${string}`],\n });\n\n return result as string;\n } catch (error) {\n logger.warn(LOG_SYSTEM, `Failed to get admin role for ${roleId}:`, error);\n return null;\n }\n}\n\n/**\n * Get the current block number from the RPC endpoint.\n *\n * @param rpcUrl - RPC endpoint URL\n * @param viemChain - Optional viem Chain object\n * @returns The current block number\n * @throws OperationFailed if the call fails\n */\nexport async function getCurrentBlock(rpcUrl: string, viemChain?: Chain): Promise<number> {\n logger.info(LOG_SYSTEM, `Fetching current block from ${rpcUrl}`);\n\n const client = createClient(rpcUrl, viemChain);\n\n try {\n const blockNumber = await client.getBlockNumber();\n const block = Number(blockNumber);\n\n logger.debug(LOG_SYSTEM, `Current block: ${block}`);\n return block;\n } catch (error) {\n logger.error(LOG_SYSTEM, 'Failed to get current block:', error);\n throw new OperationFailed(\n `Failed to get current block: ${(error as Error).message}`,\n rpcUrl,\n 'getCurrentBlock',\n error as Error\n );\n }\n}\n","/**\n * EVM Access Control Role Discovery\n *\n * Scans contract ABI for role constant candidates (no inputs, single bytes32 output,\n * view/pure, name ending in _ROLE or Role) and calls them on-chain to build a\n * hash -> label map for human-readable role display.\n *\n * @module access-control/role-discovery\n */\n\nimport type { Abi, Chain } from 'viem';\n\nimport type { ContractFunction, ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createEvmPublicClient } from '../utils/public-client';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LOG_SYSTEM = 'EvmRoleDiscovery';\n\n/** Regex: function name ends with _ROLE or Role (OpenZeppelin role constant pattern) */\nconst ROLE_CONSTANT_NAME_PATTERN = /_ROLE$|Role$/;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Filters contract schema functions for role constant candidates.\n *\n * A candidate must have:\n * - No inputs\n * - Single bytes32 output\n * - stateMutability view or pure\n * - Name ending with _ROLE or Role\n *\n * @param contractSchema - Parsed contract schema with functions array\n * @returns Array of ContractFunction candidates\n */\nexport function findRoleConstantCandidates(contractSchema: ContractSchema): ContractFunction[] {\n return contractSchema.functions.filter((fn) => {\n if (fn.inputs.length !== 0) return false;\n const outputs = fn.outputs;\n if (!outputs || outputs.length !== 1 || outputs[0].type !== 'bytes32') return false;\n const mutability = fn.stateMutability?.toLowerCase();\n if (mutability !== 'view' && mutability !== 'pure') return false;\n return ROLE_CONSTANT_NAME_PATTERN.test(fn.name);\n });\n}\n\n/**\n * Discovers role labels by calling role constant candidates on-chain.\n *\n * For each candidate from findRoleConstantCandidates(), calls the function\n * on the contract and maps the returned bytes32 value to the function name.\n * Failed calls are skipped (graceful degradation).\n *\n * @param rpcUrl - RPC endpoint URL\n * @param contractAddress - The EVM contract address (0x-prefixed)\n * @param contractSchema - Parsed contract schema\n * @param viemChain - Optional viem Chain object\n * @returns Map of bytes32 hash (0x-prefixed, 64 hex chars) -> function name (label)\n */\nexport async function discoverRoleLabelsFromAbi(\n rpcUrl: string,\n contractAddress: string,\n contractSchema: ContractSchema,\n viemChain?: Chain\n): Promise<Map<string, string>> {\n const candidates = findRoleConstantCandidates(contractSchema);\n if (candidates.length === 0) {\n logger.debug(LOG_SYSTEM, `No role constant candidates for ${contractAddress}`);\n return new Map();\n }\n\n const client = createEvmPublicClient(rpcUrl, viemChain);\n\n const address = contractAddress as `0x${string}`;\n const result = new Map<string, string>();\n\n // Batch all RPC calls in parallel for reduced latency\n const callResults = await Promise.allSettled(\n candidates.map(async (fn) => {\n const abi: Abi = [\n {\n type: 'function',\n name: fn.name,\n inputs: [],\n outputs: [{ name: '', type: 'bytes32' }],\n stateMutability: (fn.stateMutability as 'view' | 'pure') || 'view',\n },\n ];\n\n const value = await client.readContract({\n address,\n abi,\n functionName: fn.name as string,\n args: [],\n });\n\n return { name: fn.name, value };\n })\n );\n\n for (const settled of callResults) {\n if (settled.status === 'rejected') {\n logger.debug(\n LOG_SYSTEM,\n `Skipping role constant on ${contractAddress}: ${(settled.reason as Error).message}`\n );\n continue;\n }\n\n const { name, value } = settled.value;\n\n // Normalize to 0x + 64 lowercase hex chars for consistent map keys.\n // viem returns bytes32 as a hex string, but we handle bigint defensively.\n const raw =\n typeof value === 'string'\n ? value.toLowerCase()\n : `0x${(value as bigint).toString(16).padStart(64, '0')}`;\n const normalizedHash = raw.startsWith('0x')\n ? `0x${raw.slice(2).padStart(64, '0')}`\n : `0x${raw.padStart(64, '0')}`;\n\n result.set(normalizedHash, name);\n logger.debug(LOG_SYSTEM, `Resolved role constant ${name} -> ${normalizedHash}`);\n }\n\n logger.info(\n LOG_SYSTEM,\n `Discovered ${result.size} role label(s) from ABI for ${contractAddress}`,\n { candidates: candidates.length }\n );\n\n return result;\n}\n","/**\n * EVM Access Control Service\n *\n * Implements the AccessControlService interface for EVM-compatible contracts.\n * Provides methods to inspect and manage access control (Ownable, Ownable2Step,\n * AccessControl, AccessControlDefaultAdminRules, AccessControlEnumerable) on contracts.\n *\n * The service assembles transaction data (as `WriteContractParameters`) and delegates\n * execution to a caller-provided `executeTransaction` callback, decoupling the service\n * from wallet/signing infrastructure.\n *\n * **Concurrency model (NFR-002)**: Single-consumer per instance. Concurrent reads for\n * different contracts are safe (each operates on independent Map entries). Concurrent\n * writes to the same contract context are not guarded — last write wins.\n *\n * @module access-control/service\n * @see contracts/access-control-service.ts — API contract\n * @see research.md §R9 — Service Lifecycle and Transaction Execution\n */\n\nimport type {\n AccessControlCapabilities,\n AccessControlService,\n AccessSnapshot,\n AdminInfo,\n ContractSchema,\n EnrichedRoleAssignment,\n EnrichedRoleMember,\n ExecutionConfig,\n ExpirationMetadata,\n HistoryQueryOptions,\n OperationResult,\n OwnershipInfo,\n PaginatedHistoryResult,\n PendingAdminTransfer,\n PendingOwnershipTransfer,\n RoleAssignment,\n TransactionStatusUpdate,\n TxStatus,\n} from '@openzeppelin/ui-types';\nimport { ConfigurationInvalid, OperationFailed } from '@openzeppelin/ui-types';\nimport { logger, validateSnapshot } from '@openzeppelin/ui-utils';\n\nimport { resolveRpcUrl } from '../configuration/rpc';\nimport type { EvmCompatibleNetworkConfig, WriteContractParameters } from '../types';\nimport {\n assembleAcceptAdminTransferAction,\n assembleAcceptOwnershipAction,\n assembleBeginAdminTransferAction,\n assembleCancelAdminTransferAction,\n assembleChangeAdminDelayAction,\n assembleGrantRoleAction,\n assembleRenounceOwnershipAction,\n assembleRenounceRoleAction,\n assembleRevokeRoleAction,\n assembleRollbackAdminDelayAction,\n assembleTransferOwnershipAction,\n} from './actions';\nimport { detectAccessControlCapabilities } from './feature-detection';\nimport {\n createIndexerClient,\n EvmIndexerClient,\n grantMapKey,\n type GrantInfo,\n} from './indexer-client';\nimport { getAdmin, readCurrentRoles, readOwnership } from './onchain-reader';\nimport { discoverRoleLabelsFromAbi } from './role-discovery';\nimport type { EvmAccessControlContext, EvmTransactionExecutor } from './types';\nimport { validateAddress, validateRoleId, validateRoleIds } from './validation';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Empty history result used for graceful degradation (FR-017) */\nconst EMPTY_HISTORY_RESULT: PaginatedHistoryResult = {\n items: [],\n pageInfo: { hasNextPage: false },\n};\n\n// ---------------------------------------------------------------------------\n// Service Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * EVM implementation of AccessControlService.\n *\n * This class is incrementally built across user stories. Phase 3 (US1) provides:\n * - registerContract()\n * - addKnownRoleIds()\n * - getCapabilities()\n * - dispose()\n *\n * Subsequent phases add: getOwnership, getAdminInfo, getCurrentRoles,\n * getCurrentRolesEnriched, grantRole, revokeRole, transferOwnership,\n * acceptOwnership, renounceOwnership, transferAdminRole, acceptAdminTransfer,\n * cancelAdminTransfer, changeAdminDelay, rollbackAdminDelay, renounceRole,\n * getHistory, exportSnapshot, discoverKnownRoleIds.\n */\nexport class EvmAccessControlService implements AccessControlService {\n private readonly contractContexts = new Map<string, EvmAccessControlContext>();\n private readonly networkConfig: EvmCompatibleNetworkConfig;\n private readonly executeTransaction: EvmTransactionExecutor;\n private readonly indexerClient: EvmIndexerClient;\n\n constructor(\n networkConfig: EvmCompatibleNetworkConfig,\n executeTransaction: EvmTransactionExecutor\n ) {\n this.networkConfig = networkConfig;\n this.executeTransaction = executeTransaction;\n this.indexerClient = createIndexerClient(networkConfig);\n }\n\n // ── Contract Registration ──────────────────────────────────────────────\n\n /**\n * Register a contract for access control operations.\n *\n * Validates the contract address and optional role IDs, then stores the context\n * in-memory. Re-registration overwrites the previous context.\n *\n * @param contractAddress - EVM address (0x-prefixed, 42 chars)\n * @param contractSchema - Parsed ABI as ContractSchema\n * @param knownRoleIds - Optional bytes32 role identifiers\n * @throws ConfigurationInvalid if address or role IDs are invalid\n */\n registerContract(\n contractAddress: string,\n contractSchema: ContractSchema,\n knownRoleIds?: string[]\n ): void {\n validateAddress(contractAddress, 'contractAddress');\n\n const validatedRoleIds = knownRoleIds ? validateRoleIds(knownRoleIds) : [];\n\n const normalizedAddress = contractAddress.toLowerCase();\n\n this.contractContexts.set(normalizedAddress, {\n contractAddress: normalizedAddress,\n contractSchema,\n knownRoleIds: validatedRoleIds,\n discoveredRoleIds: [],\n roleDiscoveryAttempted: false,\n capabilities: null,\n roleLabelMap: new Map(),\n abiRoleDiscoveryDone: false,\n });\n\n logger.debug('EvmAccessControlService.registerContract', `Registered ${normalizedAddress}`, {\n roleCount: validatedRoleIds.length,\n });\n }\n\n /**\n * Add additional known role IDs to a registered contract.\n *\n * Merges with existing role IDs using union with deduplication.\n * Accepts plain role IDs (string) or label pairs ({ id, label }) for human-readable display.\n * External labels are stored in context.roleLabelMap and take precedence over ABI/dictionary.\n *\n * @param contractAddress - Previously registered contract address\n * @param roleIds - Additional bytes32 role identifiers, or { id, label } pairs\n * @returns Merged array of all known role IDs\n * @throws ConfigurationInvalid if contract not registered or role IDs invalid\n */\n addKnownRoleIds(\n contractAddress: string,\n roleIds: Array<string | { id: string; label: string }>\n ): string[] {\n validateAddress(contractAddress, 'contractAddress');\n\n const context = this.getContextOrThrow(contractAddress);\n\n const validatedIds: string[] = [];\n for (let i = 0; i < roleIds.length; i++) {\n const item = roleIds[i];\n if (typeof item === 'string') {\n validatedIds.push(validateRoleId(item, `roleIds[${i}]`));\n } else {\n validatedIds.push(validateRoleId(item.id, `roleIds[${i}].id`));\n context.roleLabelMap.set(validatedIds[validatedIds.length - 1], item.label);\n }\n }\n\n if (validatedIds.length === 0) {\n logger.debug(\n 'EvmAccessControlService.addKnownRoleIds',\n `No valid role IDs to add for ${context.contractAddress}`\n );\n return [...context.knownRoleIds];\n }\n\n const mergedRoleIds = [...new Set([...context.knownRoleIds, ...validatedIds])];\n context.knownRoleIds = mergedRoleIds;\n\n logger.info(\n 'EvmAccessControlService.addKnownRoleIds',\n `Added ${validatedIds.length} role ID(s) for ${context.contractAddress}`,\n { added: validatedIds, total: mergedRoleIds.length }\n );\n\n return mergedRoleIds;\n }\n\n /**\n * Ensures ABI role constant discovery has been run once for this contract.\n * Merges discovered hash -> label into context.roleLabelMap and sets abiRoleDiscoveryDone.\n */\n private async ensureAbiRoleLabels(context: EvmAccessControlContext): Promise<void> {\n if (context.abiRoleDiscoveryDone) return;\n\n try {\n const discovered = await discoverRoleLabelsFromAbi(\n resolveRpcUrl(this.networkConfig),\n context.contractAddress,\n context.contractSchema,\n this.networkConfig.viemChain\n );\n for (const [hash, label] of discovered) {\n // Only set if not already present — external labels from addKnownRoleIds() take precedence\n if (!context.roleLabelMap.has(hash)) {\n context.roleLabelMap.set(hash, label);\n }\n }\n } finally {\n context.abiRoleDiscoveryDone = true;\n }\n }\n\n // ── Capability Detection ───────────────────────────────────────────────\n\n /**\n * Detect access control capabilities from the contract's ABI.\n *\n * Results are cached after the first call for a given contract. Also checks\n * indexer availability for the `supportsHistory` flag.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Detected capabilities\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getCapabilities(contractAddress: string): Promise<AccessControlCapabilities> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.getCapabilities',\n `Detecting capabilities for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n // Return cached capabilities if available\n if (context.capabilities !== null) {\n logger.debug(\n 'EvmAccessControlService.getCapabilities',\n `Returning cached capabilities for ${context.contractAddress}`\n );\n return context.capabilities;\n }\n\n // Check indexer availability based on configuration\n const indexerAvailable = this.hasIndexerEndpoint();\n\n const capabilities = detectAccessControlCapabilities(context.contractSchema, indexerAvailable);\n\n // Cache the result\n context.capabilities = capabilities;\n\n logger.debug('EvmAccessControlService.getCapabilities', 'Detected capabilities:', {\n hasOwnable: capabilities.hasOwnable,\n hasTwoStepOwnable: capabilities.hasTwoStepOwnable,\n hasAccessControl: capabilities.hasAccessControl,\n hasTwoStepAdmin: capabilities.hasTwoStepAdmin,\n hasEnumerableRoles: capabilities.hasEnumerableRoles,\n supportsHistory: capabilities.supportsHistory,\n });\n\n return capabilities;\n }\n\n // ── Ownership ──────────────────────────────────────────────────────────\n\n /**\n * Get current ownership state.\n *\n * On-chain reads: `owner()`, `pendingOwner()` (if Ownable2Step)\n * Indexer enrichment: pending transfer initiation timestamp/tx\n *\n * State mapping:\n * - owner !== zeroAddress && no pendingOwner → 'owned'\n * - pendingOwner set → 'pending' (expirationBlock = undefined — no expiration for EVM)\n * - owner === zeroAddress → 'renounced'\n * - Never returns 'expired' for EVM (FR-023)\n *\n * Graceful degradation (FR-017): Returns on-chain data without enrichment\n * when the indexer is unavailable.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Ownership information with state classification\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getOwnership(contractAddress: string): Promise<OwnershipInfo> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.getOwnership',\n `Reading ownership status for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n // Defense-in-depth: check capabilities before calling owner()\n // Prevents confusing revert errors when called on AccessControl-only contracts\n const capabilities = context.capabilities ?? (await this.getCapabilities(contractAddress));\n if (!capabilities.hasOwnable) {\n throw new OperationFailed(\n 'Contract does not implement the Ownable interface — no owner() function available',\n contractAddress,\n 'getOwnership'\n );\n }\n\n // Read on-chain ownership data\n const onChainData = await readOwnership(\n resolveRpcUrl(this.networkConfig),\n context.contractAddress,\n this.networkConfig.viemChain\n );\n\n // ── Renounced state — owner is null ─────────────────────────────\n if (onChainData.owner === null) {\n logger.debug(\n 'EvmAccessControlService.getOwnership',\n `Contract ${context.contractAddress} has renounced ownership`\n );\n return {\n owner: null,\n state: 'renounced',\n };\n }\n\n // ── No pending owner — owned state ──────────────────────────────\n if (!onChainData.pendingOwner) {\n logger.debug(\n 'EvmAccessControlService.getOwnership',\n `Contract ${context.contractAddress} has owner with no pending transfer`\n );\n return {\n owner: onChainData.owner,\n state: 'owned',\n };\n }\n\n // ── Pending owner exists — enrich from indexer if available ──────\n const pendingTransfer: PendingOwnershipTransfer = {\n pendingOwner: onChainData.pendingOwner,\n // EVM Ownable2Step has no expiration — expirationBlock is undefined (see research.md §R5)\n expirationBlock: undefined,\n };\n\n // Attempt indexer enrichment\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (indexerAvailable) {\n try {\n const enrichment = await this.indexerClient.queryPendingOwnershipTransfer(\n context.contractAddress\n );\n if (enrichment) {\n pendingTransfer.initiatedAt = enrichment.initiatedAt;\n pendingTransfer.initiatedTxId = enrichment.initiatedTxId;\n pendingTransfer.initiatedBlock = enrichment.initiatedBlock;\n }\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.getOwnership',\n `Failed to enrich ownership from indexer: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n logger.warn(\n 'EvmAccessControlService.getOwnership',\n `Indexer unavailable for ${this.networkConfig.id}: pending transfer enrichment skipped`\n );\n }\n\n logger.debug(\n 'EvmAccessControlService.getOwnership',\n `Contract ${context.contractAddress} has pending transfer to ${onChainData.pendingOwner}`\n );\n\n return {\n owner: onChainData.owner,\n state: 'pending',\n pendingTransfer,\n };\n }\n\n /**\n * Initiate ownership transfer.\n *\n * - Ownable: single-step `transferOwnership(newOwner)` — ownership changes immediately\n * - Ownable2Step: `transferOwnership(newOwner)` — sets `pendingOwner`, requires `acceptOwnership()`\n *\n * The `expirationBlock` parameter is **ignored for EVM** — EVM Ownable2Step has no\n * expiration mechanism (FR-023). The parameter exists for API parity with Stellar.\n *\n * @param contractAddress - Previously registered contract address\n * @param newOwner - The new owner address\n * @param _expirationBlock - Ignored for EVM (no expiration). Exists for Stellar API parity.\n * @param executionConfig - Execution strategy configuration (EOA, Relayer, etc.)\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered or addresses invalid\n */\n async transferOwnership(\n contractAddress: string,\n newOwner: string,\n _expirationBlock: number | undefined,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n validateAddress(newOwner, 'newOwner');\n\n logger.info(\n 'EvmAccessControlService.transferOwnership',\n `Initiating ownership transfer for ${contractAddress} to ${newOwner}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleTransferOwnershipAction(context.contractAddress, newOwner);\n\n logger.debug(\n 'EvmAccessControlService.transferOwnership',\n `Assembled transferOwnership tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Accept a pending ownership transfer (Ownable2Step only).\n *\n * Must be called by the pending owner. No arguments — the caller is\n * implicitly validated on-chain.\n *\n * @param contractAddress - Previously registered contract address\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async acceptOwnership(\n contractAddress: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.acceptOwnership',\n `Accepting ownership for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleAcceptOwnershipAction(context.contractAddress);\n\n logger.debug(\n 'EvmAccessControlService.acceptOwnership',\n `Assembled acceptOwnership tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Renounce ownership (Ownable).\n *\n * Permanently renounces ownership — after execution, `owner()` returns the zero address\n * and ownership queries return state `'renounced'`.\n *\n * Part of the unified `AccessControlService` interface — gated by\n * `hasRenounceOwnership` capability flag.\n *\n * @param contractAddress - Previously registered contract address\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async renounceOwnership(\n contractAddress: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.renounceOwnership',\n `Renouncing ownership for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleRenounceOwnershipAction(context.contractAddress);\n\n logger.debug(\n 'EvmAccessControlService.renounceOwnership',\n `Assembled renounceOwnership tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n // ── Expiration Metadata ────────────────────────────────────────────────\n\n /**\n * Get expiration metadata for a transfer type.\n *\n * EVM semantics:\n * - Ownership transfers (Ownable2Step): No expiration → mode 'none'\n * - Admin transfers (AccessControlDefaultAdminRules): Contract-managed accept schedule\n * → mode 'contract-managed' with the accept schedule as current value\n *\n * @param contractAddress - Previously registered contract address\n * @param transferType - 'ownership' or 'admin'\n * @returns Expiration metadata for the UI\n */\n async getExpirationMetadata(\n contractAddress: string,\n transferType: 'ownership' | 'admin'\n ): Promise<ExpirationMetadata> {\n validateAddress(contractAddress, 'contractAddress');\n\n if (transferType === 'ownership') {\n // EVM Ownable2Step has no expiration mechanism\n return { mode: 'none' };\n }\n\n // Admin transfers: contract-managed accept schedule\n return {\n mode: 'contract-managed',\n label: 'Accept Schedule',\n unit: 'UNIX timestamp',\n };\n }\n\n // ── Admin ──────────────────────────────────────────────────────────────\n\n /**\n * Get current default admin state (AccessControlDefaultAdminRules).\n *\n * On-chain reads: `defaultAdmin()`, `pendingDefaultAdmin()`, `defaultAdminDelay()`\n * Indexer enrichment: pending transfer initiation timestamp/tx\n *\n * State mapping:\n * - defaultAdmin !== zeroAddress && no pending → 'active'\n * - pendingDefaultAdmin set → 'pending'\n * - defaultAdmin === zeroAddress → 'renounced'\n * - Never returns 'expired' for EVM (FR-023)\n *\n * For pending transfers, `acceptSchedule` maps to `expirationBlock` — this is a\n * **UNIX timestamp in seconds** (NOT a block number). See research.md §R5 for the\n * semantic divergence between Stellar and EVM.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Admin information with state classification\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getAdminInfo(contractAddress: string): Promise<AdminInfo> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.getAdminInfo',\n `Reading admin status for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n // Defense-in-depth: check capabilities before calling defaultAdmin()\n // Prevents confusing revert errors when called on contracts without AccessControlDefaultAdminRules\n const capabilities = context.capabilities ?? (await this.getCapabilities(contractAddress));\n if (!capabilities.hasTwoStepAdmin) {\n throw new OperationFailed(\n 'Contract does not implement the AccessControlDefaultAdminRules interface — no defaultAdmin() function available',\n contractAddress,\n 'getAdminInfo'\n );\n }\n\n // Read on-chain admin data\n const onChainData = await getAdmin(\n resolveRpcUrl(this.networkConfig),\n context.contractAddress,\n this.networkConfig.viemChain\n );\n\n // ── Build delayInfo from on-chain data ─────────────────────────\n const delayInfo =\n onChainData.defaultAdminDelay != null\n ? {\n currentDelay: onChainData.defaultAdminDelay,\n ...(onChainData.pendingDefaultAdminDelay != null &&\n onChainData.pendingDefaultAdminDelaySchedule != null\n ? {\n pendingDelay: {\n newDelay: onChainData.pendingDefaultAdminDelay,\n effectAt: onChainData.pendingDefaultAdminDelaySchedule,\n },\n }\n : {}),\n }\n : undefined;\n\n // ── Renounced state — admin is null ─────────────────────────────\n if (onChainData.defaultAdmin === null) {\n logger.debug(\n 'EvmAccessControlService.getAdminInfo',\n `Contract ${context.contractAddress} has renounced admin`\n );\n return {\n admin: null,\n state: 'renounced',\n delayInfo,\n };\n }\n\n // ── No pending admin — active state ─────────────────────────────\n if (!onChainData.pendingDefaultAdmin) {\n logger.debug(\n 'EvmAccessControlService.getAdminInfo',\n `Contract ${context.contractAddress} has admin with no pending transfer`\n );\n return {\n admin: onChainData.defaultAdmin,\n state: 'active',\n delayInfo,\n };\n }\n\n // ── Pending admin exists — enrich from indexer if available ──────\n /**\n * The `expirationBlock` field stores the `acceptSchedule` value from\n * `pendingDefaultAdmin()` — this is a UNIX timestamp (seconds since epoch),\n * NOT a block number. See research.md §R5 for semantic divergence.\n */\n const pendingTransfer: PendingAdminTransfer = {\n pendingAdmin: onChainData.pendingDefaultAdmin,\n expirationBlock: onChainData.acceptSchedule,\n };\n\n // Attempt indexer enrichment\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (indexerAvailable) {\n try {\n const enrichment = await this.indexerClient.queryPendingAdminTransfer(\n context.contractAddress\n );\n if (enrichment) {\n pendingTransfer.initiatedAt = enrichment.initiatedAt;\n pendingTransfer.initiatedTxId = enrichment.initiatedTxId;\n pendingTransfer.initiatedBlock = enrichment.initiatedBlock;\n }\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.getAdminInfo',\n `Failed to enrich admin info from indexer: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n logger.warn(\n 'EvmAccessControlService.getAdminInfo',\n `Indexer unavailable for ${this.networkConfig.id}: pending admin enrichment skipped`\n );\n }\n\n logger.debug(\n 'EvmAccessControlService.getAdminInfo',\n `Contract ${context.contractAddress} has pending admin transfer to ${onChainData.pendingDefaultAdmin}`\n );\n\n return {\n admin: onChainData.defaultAdmin,\n state: 'pending',\n pendingTransfer,\n delayInfo,\n };\n }\n\n /**\n * Initiate default admin transfer (AccessControlDefaultAdminRules).\n *\n * Assembles `beginDefaultAdminTransfer(newAdmin)` and delegates execution.\n * The contract's built-in delay determines when the transfer can be accepted.\n *\n * The `expirationBlock` parameter is **ignored for EVM** — the delay is\n * determined by the contract's `defaultAdminDelay()`. The parameter exists\n * for API parity with Stellar.\n *\n * **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n * have the `hasTwoStepAdmin` capability.\n *\n * @param contractAddress - Previously registered contract address\n * @param newAdmin - The new admin address\n * @param _expirationBlock - Ignored for EVM. Exists for Stellar API parity.\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n */\n async transferAdminRole(\n contractAddress: string,\n newAdmin: string,\n _expirationBlock: number | undefined,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n validateAddress(newAdmin, 'newAdmin');\n\n logger.info(\n 'EvmAccessControlService.transferAdminRole',\n `Initiating admin transfer for ${contractAddress} to ${newAdmin}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n await this.ensureHasTwoStepAdmin(contractAddress);\n\n const txData = assembleBeginAdminTransferAction(context.contractAddress, newAdmin);\n\n logger.debug(\n 'EvmAccessControlService.transferAdminRole',\n `Assembled beginDefaultAdminTransfer tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Accept a pending default admin transfer (AccessControlDefaultAdminRules).\n *\n * Must be called by the pending admin after the accept schedule timestamp.\n * No arguments — the caller is implicitly validated on-chain.\n *\n * **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n * have the `hasTwoStepAdmin` capability.\n *\n * @param contractAddress - Previously registered contract address\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n */\n async acceptAdminTransfer(\n contractAddress: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.acceptAdminTransfer',\n `Accepting admin transfer for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n await this.ensureHasTwoStepAdmin(contractAddress);\n\n const txData = assembleAcceptAdminTransferAction(context.contractAddress);\n\n logger.debug(\n 'EvmAccessControlService.acceptAdminTransfer',\n `Assembled acceptDefaultAdminTransfer tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Cancel a pending default admin transfer (AccessControlDefaultAdminRules).\n *\n * Must be called by the current default admin. Cancels any pending transfer\n * and resets the pending admin state.\n *\n * Part of the unified `AccessControlService` interface — gated by\n * `hasCancelAdminTransfer` capability flag.\n *\n * **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n * have the `hasTwoStepAdmin` capability.\n *\n * @param contractAddress - Previously registered contract address\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n */\n async cancelAdminTransfer(\n contractAddress: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.cancelAdminTransfer',\n `Canceling admin transfer for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n await this.ensureHasTwoStepAdmin(contractAddress);\n\n const txData = assembleCancelAdminTransferAction(context.contractAddress);\n\n logger.debug(\n 'EvmAccessControlService.cancelAdminTransfer',\n `Assembled cancelDefaultAdminTransfer tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Change the default admin transfer delay (AccessControlDefaultAdminRules).\n *\n * Schedules a change to the delay period. The change itself has a delay\n * before it takes effect (determined by the current delay).\n *\n * Part of the unified `AccessControlService` interface — gated by\n * `hasAdminDelayManagement` capability flag.\n *\n * **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n * have the `hasTwoStepAdmin` capability.\n *\n * @param contractAddress - Previously registered contract address\n * @param newDelay - The new delay in seconds (uint48)\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n */\n async changeAdminDelay(\n contractAddress: string,\n newDelay: number,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.changeAdminDelay',\n `Changing admin delay for ${contractAddress} to ${newDelay}s`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n await this.ensureHasTwoStepAdmin(contractAddress);\n\n const txData = assembleChangeAdminDelayAction(context.contractAddress, newDelay);\n\n logger.debug(\n 'EvmAccessControlService.changeAdminDelay',\n `Assembled changeDefaultAdminDelay tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Rollback a pending admin delay change (AccessControlDefaultAdminRules).\n *\n * Cancels a scheduled delay change. Must be called by the current default admin\n * before the delay change takes effect.\n *\n * Part of the unified `AccessControlService` interface — gated by\n * `hasAdminDelayManagement` capability flag.\n *\n * **Guard (FR-024)**: Throws `ConfigurationInvalid` if the contract does not\n * have the `hasTwoStepAdmin` capability.\n *\n * @param contractAddress - Previously registered contract address\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, address invalid, or lacks hasTwoStepAdmin\n */\n async rollbackAdminDelay(\n contractAddress: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.rollbackAdminDelay',\n `Rolling back admin delay change for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n await this.ensureHasTwoStepAdmin(contractAddress);\n\n const txData = assembleRollbackAdminDelayAction(context.contractAddress);\n\n logger.debug(\n 'EvmAccessControlService.rollbackAdminDelay',\n `Assembled rollbackDefaultAdminDelay tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n // ── Roles ──────────────────────────────────────────────────────────────\n\n /**\n * Get current role assignments for a registered AccessControl contract.\n *\n * Strategy:\n * 1. If AccessControlEnumerable: enumerate on-chain via `getRoleMember()`\n * 2. If known role IDs available: use on-chain `readCurrentRoles()` with hasRole checks\n * 3. If indexer available: attempt to discover role IDs via indexer\n * 4. Fallback: return empty array\n *\n * The `DEFAULT_ADMIN_ROLE` (bytes32 zero) is given the label `\"DEFAULT_ADMIN_ROLE\"`.\n * Other roles have no label (the keccak256 hash cannot be reversed).\n *\n * **Note (FR-026)**: `DEFAULT_ADMIN_ROLE` is NOT auto-included in knownRoleIds.\n * Consumers must provide it explicitly or rely on indexer discovery.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Array of role assignments with members\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getCurrentRoles(contractAddress: string): Promise<RoleAssignment[]> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info('EvmAccessControlService.getCurrentRoles', `Reading roles for ${contractAddress}`);\n\n const context = this.getContextOrThrow(contractAddress);\n\n await this.ensureAbiRoleLabels(context);\n\n // Detect capabilities to check for enumerable roles\n const capabilities = await this.getCapabilities(contractAddress);\n\n // Determine the union of known + discovered role IDs\n let roleIds = this.getMergedRoleIds(context);\n\n // If no role IDs are available, attempt discovery\n if (roleIds.length === 0) {\n logger.debug(\n 'EvmAccessControlService.getCurrentRoles',\n 'No role IDs provided, attempting discovery via indexer'\n );\n roleIds = await this.attemptRoleDiscovery(context);\n }\n\n if (roleIds.length === 0) {\n logger.warn(\n 'EvmAccessControlService.getCurrentRoles',\n 'No role IDs available (neither provided nor discoverable), returning empty array'\n );\n return [];\n }\n\n // Read roles from on-chain (uses enumeration if available)\n const assignments = await readCurrentRoles(\n resolveRpcUrl(this.networkConfig),\n context.contractAddress,\n roleIds,\n capabilities.hasEnumerableRoles,\n this.networkConfig.viemChain,\n context.roleLabelMap\n );\n\n // For non-enumerable contracts, on-chain reads return empty members.\n // Use the indexer to populate members from historical grant data.\n if (!capabilities.hasEnumerableRoles) {\n const hasEmptyMembers = assignments.some((a) => a.members.length === 0);\n if (hasEmptyMembers) {\n await this.populateMembersFromIndexer(context, assignments);\n }\n }\n\n logger.debug(\n 'EvmAccessControlService.getCurrentRoles',\n `Retrieved ${assignments.length} role assignment(s) with ${assignments.reduce((sum, a) => sum + a.members.length, 0)} total member(s) for ${context.contractAddress}`\n );\n\n return assignments;\n }\n\n /**\n * Get enriched role assignments with grant metadata from the indexer.\n *\n * Builds on `getCurrentRoles()` and enriches each member with grant timestamp,\n * transaction ID, and block number from the indexer. Falls back to unenriched\n * data if the indexer is unavailable (graceful degradation per FR-017).\n *\n * The `grantedLedger` field in `EnrichedRoleMember` stores an EVM **block number**\n * despite its Stellar-originated name. This is a consequence of the unified type\n * design — see data-model.md §6.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Array of enriched role assignments\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getCurrentRolesEnriched(contractAddress: string): Promise<EnrichedRoleAssignment[]> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.getCurrentRolesEnriched',\n `Reading enriched roles for ${contractAddress}`\n );\n\n // Get base role assignments\n const currentRoles = await this.getCurrentRoles(contractAddress);\n\n if (currentRoles.length === 0) {\n return [];\n }\n\n // Check indexer availability for enrichment\n const indexerAvailable = await this.indexerClient.isAvailable();\n\n if (!indexerAvailable) {\n logger.debug(\n 'EvmAccessControlService.getCurrentRolesEnriched',\n 'Indexer not available, returning roles without timestamps'\n );\n return this.convertToEnrichedWithoutTimestamps(currentRoles);\n }\n\n // Attempt enrichment via indexer\n try {\n const context = this.getContextOrThrow(contractAddress);\n const roleIds = currentRoles.map((ra) => ra.role.id);\n\n const grantMap = await this.indexerClient.queryLatestGrants(context.contractAddress, roleIds);\n\n if (!grantMap) {\n logger.warn(\n 'EvmAccessControlService.getCurrentRolesEnriched',\n 'Indexer returned null for grant data, returning without enrichment'\n );\n return this.convertToEnrichedWithoutTimestamps(currentRoles);\n }\n\n // Build a reverse index: roleId → GrantInfo[] for populating non-enumerable roles\n const grantsByRole = new Map<string, GrantInfo[]>();\n for (const grant of grantMap.values()) {\n const key = grant.role.toLowerCase();\n const existing = grantsByRole.get(key) ?? [];\n existing.push(grant);\n grantsByRole.set(key, existing);\n }\n\n // Map each role assignment to enriched form\n const enriched: EnrichedRoleAssignment[] = currentRoles.map((roleAssignment) => {\n const roleIdLower = roleAssignment.role.id.toLowerCase();\n\n // For non-enumerable contracts, on-chain members will be empty.\n // Populate members from indexer grant data instead.\n if (roleAssignment.members.length === 0) {\n const indexerGrants = grantsByRole.get(roleIdLower) ?? [];\n return {\n role: roleAssignment.role,\n members: indexerGrants.map(\n (grant): EnrichedRoleMember => ({\n address: grant.account,\n grantedAt: grant.grantedAt,\n grantedTxId: grant.txHash,\n })\n ),\n };\n }\n\n // For enumerable contracts, enrich on-chain members with indexer metadata\n return {\n role: roleAssignment.role,\n members: roleAssignment.members.map((memberAddress): EnrichedRoleMember => {\n const grantInfo = grantMap.get(grantMapKey(roleAssignment.role.id, memberAddress));\n const member: EnrichedRoleMember = {\n address: memberAddress,\n };\n\n if (grantInfo) {\n member.grantedAt = grantInfo.grantedAt;\n member.grantedTxId = grantInfo.txHash;\n }\n\n return member;\n }),\n };\n });\n\n const totalMembers = enriched.reduce((sum, a) => sum + a.members.length, 0);\n logger.debug(\n 'EvmAccessControlService.getCurrentRolesEnriched',\n `Enriched ${enriched.length} role(s) with ${totalMembers} total member(s)`\n );\n\n return enriched;\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.getCurrentRolesEnriched',\n `Failed to enrich roles from indexer: ${error instanceof Error ? error.message : String(error)}`\n );\n // Graceful degradation: return on-chain data without enrichment\n return this.convertToEnrichedWithoutTimestamps(currentRoles);\n }\n }\n\n /**\n * Grant a role to an account.\n *\n * Assembles `grantRole(bytes32 role, address account)` and delegates execution.\n * Must be called by an account with the role's admin role (typically DEFAULT_ADMIN_ROLE).\n *\n * @param contractAddress - Previously registered contract address\n * @param roleId - The bytes32 role identifier to grant\n * @param account - The account to grant the role to\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n */\n async grantRole(\n contractAddress: string,\n roleId: string,\n account: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n const validatedRoleId = validateRoleId(roleId, 'roleId');\n validateAddress(account, 'account');\n\n logger.info(\n 'EvmAccessControlService.grantRole',\n `Granting role ${validatedRoleId} to ${account} on ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleGrantRoleAction(context.contractAddress, validatedRoleId, account);\n\n logger.debug(\n 'EvmAccessControlService.grantRole',\n `Assembled grantRole tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Revoke a role from an account.\n *\n * Assembles `revokeRole(bytes32 role, address account)` and delegates execution.\n * Must be called by an account with the role's admin role.\n *\n * @param contractAddress - Previously registered contract address\n * @param roleId - The bytes32 role identifier to revoke\n * @param account - The account to revoke the role from\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n */\n async revokeRole(\n contractAddress: string,\n roleId: string,\n account: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n const validatedRoleId = validateRoleId(roleId, 'roleId');\n validateAddress(account, 'account');\n\n logger.info(\n 'EvmAccessControlService.revokeRole',\n `Revoking role ${validatedRoleId} from ${account} on ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleRevokeRoleAction(context.contractAddress, validatedRoleId, account);\n\n logger.debug(\n 'EvmAccessControlService.revokeRole',\n `Assembled revokeRole tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n /**\n * Renounce own role.\n *\n * Assembles `renounceRole(bytes32 role, address callerConfirmation)` and delegates execution.\n * The `account` parameter acts as a caller confirmation — on-chain, the contract verifies\n * it matches `msg.sender` to prevent accidental renouncement.\n *\n * Part of the unified `AccessControlService` interface — gated by\n * `hasRenounceRole` capability flag.\n *\n * @param contractAddress - Previously registered contract address\n * @param roleId - The bytes32 role identifier to renounce\n * @param account - The caller's address for confirmation (must match msg.sender on-chain)\n * @param executionConfig - Execution strategy configuration\n * @param onStatusChange - Optional callback for transaction status updates\n * @param runtimeApiKey - Optional API key for relayer execution\n * @returns Operation result with transaction hash\n * @throws ConfigurationInvalid if contract not registered, addresses invalid, or role ID invalid\n */\n async renounceRole(\n contractAddress: string,\n roleId: string,\n account: string,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n validateAddress(contractAddress, 'contractAddress');\n const validatedRoleId = validateRoleId(roleId, 'roleId');\n validateAddress(account, 'account');\n\n logger.info(\n 'EvmAccessControlService.renounceRole',\n `Renouncing role ${validatedRoleId} for ${account} on ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n const txData = assembleRenounceRoleAction(context.contractAddress, validatedRoleId, account);\n\n logger.debug(\n 'EvmAccessControlService.renounceRole',\n `Assembled renounceRole tx for ${context.contractAddress}`\n );\n\n return this.executeAction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n\n // ── History (Phase 9 — US7) ────────────────────────────────────────────\n\n /**\n * Query historical access control events from the indexer.\n *\n * Delegates to the indexer client's `queryHistory()` with filter/pagination options.\n * Supports filtering by: role, account, event type, time range, and pagination.\n *\n * **Graceful degradation (FR-017)**: Returns an empty `PaginatedHistoryResult`\n * (`{ items: [], pageInfo: { hasNextPage: false } }`) when:\n * - The indexer is unavailable\n * - The indexer query returns null\n * - The indexer query throws an error\n *\n * @param contractAddress - Previously registered contract address\n * @param options - Optional filtering and pagination options\n * @returns Paginated history result\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async getHistory(\n contractAddress: string,\n options?: HistoryQueryOptions\n ): Promise<PaginatedHistoryResult> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info('EvmAccessControlService.getHistory', `Querying history for ${contractAddress}`);\n\n const context = this.getContextOrThrow(contractAddress);\n\n await this.ensureAbiRoleLabels(context);\n\n // Check indexer availability\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (!indexerAvailable) {\n logger.warn(\n 'EvmAccessControlService.getHistory',\n `Indexer unavailable for ${this.networkConfig.id}: returning empty history`\n );\n return EMPTY_HISTORY_RESULT;\n }\n\n // Delegate to indexer client\n try {\n const result = await this.indexerClient.queryHistory(\n context.contractAddress,\n options,\n context.roleLabelMap\n );\n\n if (!result) {\n logger.warn(\n 'EvmAccessControlService.getHistory',\n `Indexer returned null for history query on ${context.contractAddress}`\n );\n return EMPTY_HISTORY_RESULT;\n }\n\n logger.debug(\n 'EvmAccessControlService.getHistory',\n `Retrieved ${result.items.length} history event(s) for ${context.contractAddress}`\n );\n\n return result;\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.getHistory',\n `Failed to query history: ${error instanceof Error ? error.message : String(error)}`\n );\n return EMPTY_HISTORY_RESULT;\n }\n }\n\n /**\n * Export a point-in-time snapshot of the contract's access control state.\n *\n * Combines `getCurrentRoles()` + `getOwnership()` into a unified `AccessSnapshot`.\n * Ownership is omitted if the contract does not support Ownable (try/catch).\n * Roles default to an empty array if the read fails.\n *\n * **Known limitation**: The unified `AccessSnapshot` type does not include `adminInfo`.\n * Admin information is accessible separately via `getAdminInfo()`. If a future\n * `@openzeppelin/ui-types` update adds `adminInfo` to `AccessSnapshot`, this method\n * should be updated to populate it.\n *\n * @param contractAddress - Previously registered contract address\n * @returns Access control snapshot with roles and optional ownership\n * @throws ConfigurationInvalid if contract not registered or address invalid\n * @throws OperationFailed if the snapshot structure fails validation\n */\n async exportSnapshot(contractAddress: string): Promise<AccessSnapshot> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.exportSnapshot',\n `Exporting snapshot for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n // Read ownership (if supported — omit if contract is not Ownable)\n let ownership: OwnershipInfo | undefined;\n try {\n ownership = await this.getOwnership(context.contractAddress);\n } catch (error) {\n logger.debug(\n 'EvmAccessControlService.exportSnapshot',\n `Ownership not available: ${error instanceof Error ? error.message : String(error)}`\n );\n // Contract may not be Ownable — continue without ownership\n }\n\n // Read roles (fallback to empty array on failure)\n let roles: RoleAssignment[] = [];\n try {\n roles = await this.getCurrentRoles(context.contractAddress);\n } catch (error) {\n logger.debug(\n 'EvmAccessControlService.exportSnapshot',\n `Roles not available: ${error instanceof Error ? error.message : String(error)}`\n );\n // Continue with empty roles array\n }\n\n const snapshot: AccessSnapshot = {\n roles,\n ownership,\n };\n\n // Validate snapshot structure\n if (!validateSnapshot(snapshot)) {\n const errorMsg = `Invalid snapshot structure for contract ${context.contractAddress}`;\n logger.error('EvmAccessControlService.exportSnapshot', errorMsg);\n throw new OperationFailed(errorMsg, context.contractAddress, 'exportSnapshot');\n }\n\n logger.debug('EvmAccessControlService.exportSnapshot', 'Snapshot created and validated:', {\n hasOwnership: !!ownership?.owner,\n roleCount: roles.length,\n totalMembers: roles.reduce((sum, r) => sum + r.members.length, 0),\n });\n\n return snapshot;\n }\n\n // ── Role Discovery (Phase 11 — US9) ────────────────────────────────────\n\n /**\n * Discover role IDs from the indexer's historical events.\n *\n * Queries the indexer for all unique role IDs that have appeared in events\n * for the given contract. Results are cached in the contract context — subsequent\n * calls return the cached value without re-querying (`roleDiscoveryAttempted` flag).\n *\n * When `knownRoleIds` were explicitly provided at registration, they are preserved\n * and merged with any newly discovered roles.\n *\n * **Graceful degradation (FR-017)**: Returns an empty array when:\n * - The indexer is unavailable\n * - The indexer query returns null\n * - The indexer query throws an error\n *\n * @param contractAddress - Previously registered contract address\n * @returns Array of known + discovered role IDs (deduplicated)\n * @throws ConfigurationInvalid if contract not registered or address invalid\n */\n async discoverKnownRoleIds(contractAddress: string): Promise<string[]> {\n validateAddress(contractAddress, 'contractAddress');\n\n logger.info(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `Discovering role IDs for ${contractAddress}`\n );\n\n const context = this.getContextOrThrow(contractAddress);\n\n // If discovery was already attempted, return the merged known + discovered set\n if (context.roleDiscoveryAttempted) {\n logger.debug(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `Returning cached discovery result for ${context.contractAddress}`\n );\n return this.getMergedRoleIds(context);\n }\n\n // Mark as attempted immediately to prevent retries on failure\n context.roleDiscoveryAttempted = true;\n\n // Check indexer availability\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (!indexerAvailable) {\n logger.warn(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `Indexer unavailable for ${this.networkConfig.id}: role discovery skipped`\n );\n return this.getMergedRoleIds(context);\n }\n\n // Query indexer for role discovery\n try {\n const discoveredRoles = await this.indexerClient.discoverRoleIds(context.contractAddress);\n\n if (discoveredRoles && discoveredRoles.length > 0) {\n context.discoveredRoleIds = discoveredRoles;\n logger.info(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `Discovered ${discoveredRoles.length} role(s) for ${context.contractAddress}`\n );\n } else {\n logger.debug(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `No roles discovered for ${context.contractAddress}`\n );\n }\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.discoverKnownRoleIds',\n `Failed to discover roles: ${error instanceof Error ? error.message : String(error)}`\n );\n // Graceful degradation — continue with whatever we have\n }\n\n return this.getMergedRoleIds(context);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────\n\n /**\n * Clean up resources — clear all contract contexts and indexer resources.\n *\n * Safe to call multiple times.\n */\n dispose(): void {\n this.contractContexts.clear();\n // Indexer client is stateless (no subscriptions to unsubscribe) — no cleanup needed\n logger.debug('EvmAccessControlService.dispose', 'Service disposed');\n }\n\n // ── Internal Helpers ──────────────────────────────────────────────────\n\n /**\n * Retrieves the context for a registered contract, throwing if not found.\n *\n * @param contractAddress - Contract address (will be normalized)\n * @returns The contract context\n * @throws ConfigurationInvalid if the contract is not registered\n */\n private getContextOrThrow(contractAddress: string): EvmAccessControlContext {\n const normalizedAddress = contractAddress.toLowerCase();\n const context = this.contractContexts.get(normalizedAddress);\n\n if (!context) {\n throw new ConfigurationInvalid(\n 'Contract not registered. Call registerContract() first.',\n contractAddress,\n 'contractAddress'\n );\n }\n\n return context;\n }\n\n /**\n * Checks whether an indexer endpoint is configured for this network.\n *\n * Uses the config precedence: `accessControlIndexerUrl` on the network config.\n */\n private hasIndexerEndpoint(): boolean {\n return !!this.networkConfig.accessControlIndexerUrl;\n }\n\n /**\n * Guards admin operations — ensures the contract has `hasTwoStepAdmin` capability.\n *\n * Throws `ConfigurationInvalid` if the contract does not support\n * AccessControlDefaultAdminRules (FR-024). This prevents any on-chain\n * interaction with incompatible contracts.\n *\n * @param contractAddress - The contract address to check\n * @throws ConfigurationInvalid if the contract lacks hasTwoStepAdmin capability\n */\n private async ensureHasTwoStepAdmin(contractAddress: string): Promise<void> {\n const capabilities = await this.getCapabilities(contractAddress);\n if (!capabilities.hasTwoStepAdmin) {\n throw new ConfigurationInvalid(\n 'Contract does not support AccessControlDefaultAdminRules (hasTwoStepAdmin is false). ' +\n 'Admin operations require a contract with the DefaultAdminRules pattern.',\n contractAddress,\n 'contractAddress'\n );\n }\n }\n\n /**\n * Returns the union of known + discovered role IDs for a context.\n * Deduplicates the combined set.\n */\n private getMergedRoleIds(context: EvmAccessControlContext): string[] {\n return [...new Set([...context.knownRoleIds, ...context.discoveredRoleIds])];\n }\n\n /**\n * Attempt to discover role IDs via the indexer.\n *\n * Delegates to the indexer client's `discoverRoleIds()`. Results are cached\n * in the context's `discoveredRoleIds` and the `roleDiscoveryAttempted` flag\n * prevents retries on failure.\n *\n * @internal\n */\n private async attemptRoleDiscovery(context: EvmAccessControlContext): Promise<string[]> {\n // If discovery was already attempted, return what we have\n if (context.roleDiscoveryAttempted) {\n return this.getMergedRoleIds(context);\n }\n\n // Mark as attempted to prevent retries\n context.roleDiscoveryAttempted = true;\n\n // Check indexer availability\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (!indexerAvailable) {\n return this.getMergedRoleIds(context);\n }\n\n try {\n const discoveredRoles = await this.indexerClient.discoverRoleIds(context.contractAddress);\n\n if (discoveredRoles && discoveredRoles.length > 0) {\n context.discoveredRoleIds = discoveredRoles;\n logger.info(\n 'EvmAccessControlService.attemptRoleDiscovery',\n `Auto-discovered ${discoveredRoles.length} role(s) for ${context.contractAddress}`\n );\n }\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.attemptRoleDiscovery',\n `Role discovery failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n return this.getMergedRoleIds(context);\n }\n\n /**\n * Populate empty member arrays from indexer grant data (non-enumerable contracts).\n *\n * For contracts without `AccessControlEnumerable`, on-chain reads cannot enumerate\n * members. This method queries the indexer's `roleMemberships` to discover who holds\n * each role, mutating the `assignments` array in place.\n *\n * Graceful degradation: if the indexer is unavailable or the query fails,\n * members stay empty — no error is thrown.\n *\n * @internal\n */\n private async populateMembersFromIndexer(\n context: EvmAccessControlContext,\n assignments: RoleAssignment[]\n ): Promise<void> {\n const indexerAvailable = await this.indexerClient.isAvailable();\n if (!indexerAvailable) {\n return;\n }\n\n try {\n const roleIds = assignments.map((a) => a.role.id);\n const grantMap = await this.indexerClient.queryLatestGrants(context.contractAddress, roleIds);\n\n if (!grantMap || grantMap.size === 0) {\n return;\n }\n\n // Build reverse index: roleId (lowercased) → account addresses\n const membersByRole = new Map<string, string[]>();\n for (const grant of grantMap.values()) {\n const key = grant.role.toLowerCase();\n const existing = membersByRole.get(key) ?? [];\n existing.push(grant.account);\n membersByRole.set(key, existing);\n }\n\n // Fill empty member arrays from indexer data\n for (const assignment of assignments) {\n if (assignment.members.length === 0) {\n const indexerMembers = membersByRole.get(assignment.role.id.toLowerCase());\n if (indexerMembers && indexerMembers.length > 0) {\n assignment.members = indexerMembers;\n }\n }\n }\n\n const totalPopulated = assignments.reduce((sum, a) => sum + a.members.length, 0);\n logger.info(\n 'EvmAccessControlService.populateMembersFromIndexer',\n `Populated ${totalPopulated} member(s) from indexer for ${context.contractAddress}`\n );\n } catch (error) {\n logger.warn(\n 'EvmAccessControlService.populateMembersFromIndexer',\n `Failed to populate members from indexer: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Converts RoleAssignment[] to EnrichedRoleAssignment[] without timestamps.\n *\n * Used for graceful degradation when the indexer is unavailable.\n * Each member gets an `EnrichedRoleMember` with only the `address` field populated.\n */\n private convertToEnrichedWithoutTimestamps(\n assignments: RoleAssignment[]\n ): EnrichedRoleAssignment[] {\n return assignments.map((ra) => ({\n role: ra.role,\n members: ra.members.map((memberAddress) => ({\n address: memberAddress,\n })),\n }));\n }\n\n /**\n * Delegates transaction execution to the injected callback.\n * Single entry point for all write operations (Phase 6+).\n *\n * @internal\n */\n protected async executeAction(\n txData: WriteContractParameters,\n executionConfig: ExecutionConfig,\n onStatusChange?: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<OperationResult> {\n return this.executeTransaction(txData, executionConfig, onStatusChange, runtimeApiKey);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an EvmAccessControlService instance.\n *\n * @param networkConfig - EVM network configuration (includes indexer URL)\n * @param executeTransaction - Callback for transaction execution (provided by EvmAdapter)\n * @returns A new EvmAccessControlService instance\n */\nexport function createEvmAccessControlService(\n networkConfig: EvmCompatibleNetworkConfig,\n executeTransaction: EvmTransactionExecutor\n): EvmAccessControlService {\n return new EvmAccessControlService(networkConfig, executeTransaction);\n}\n","/**\n * EVM Access Control Input Validation\n *\n * Provides throwing validation wrappers for the access control module.\n * Reuses `isValidEvmAddress` from `../utils/validation.ts` for address checks\n * and adds bytes32 role ID validation (access-control-specific).\n *\n * All functions throw `ConfigurationInvalid` from `@openzeppelin/ui-types`\n * on failure, matching the Stellar adapter's error handling pattern.\n *\n * @module access-control/validation\n * @see research.md §R8 — EVM Address and Role Validation\n */\n\nimport { ConfigurationInvalid } from '@openzeppelin/ui-types';\n\nimport { isValidEvmAddress } from '../utils/validation';\n\n/**\n * Regex pattern for validating bytes32 hex strings.\n * Must be 0x followed by exactly 64 hex characters (case-insensitive).\n */\nconst BYTES32_PATTERN = /^0x[0-9a-fA-F]{64}$/;\n\n/**\n * Validates an EVM address, throwing `ConfigurationInvalid` on failure.\n *\n * Delegates to the existing `isValidEvmAddress()` utility (which uses\n * viem's `isAddress()` under the hood). EVM does not distinguish between\n * contract and account addresses — both are 20-byte hex strings — so a\n * single validation function is sufficient.\n *\n * @param address - The EVM address to validate (contract or account)\n * @param paramName - Parameter name for error messages (e.g. 'contractAddress', 'account', 'newOwner')\n * @throws ConfigurationInvalid if the address is empty or not a valid EVM address\n */\nexport function validateAddress(address: string, paramName = 'address'): void {\n assertNonEmptyString(address, paramName);\n\n if (!isValidEvmAddress(address)) {\n throw new ConfigurationInvalid(\n `Invalid EVM address: ${address}. Addresses must be 0x-prefixed, 40-character hex strings.`,\n address,\n paramName\n );\n }\n}\n\n/**\n * Validates a role identifier as a bytes32 hex string.\n *\n * EVM AccessControl uses `bytes32` values as role identifiers, typically\n * computed as `keccak256(\"ROLE_NAME\")`. The format is `0x` followed by\n * exactly 64 hex characters (case-insensitive).\n *\n * The `DEFAULT_ADMIN_ROLE` (bytes32 zero: `0x0000...0000`) is a valid role ID.\n *\n * Returns the trimmed, lowercase-normalized role ID so callers can use the\n * sanitized value in downstream operations (e.g. transaction assembly, Set\n * deduplication, Map lookups). Normalizing to lowercase at the validation\n * boundary ensures case-insensitive deduplication across all consumers.\n *\n * @param roleId - The role identifier to validate\n * @param paramName - Optional parameter name for error messages (defaults to 'roleId')\n * @returns The trimmed, lowercase-normalized, validated role ID\n * @throws ConfigurationInvalid if the role ID is invalid\n */\nexport function validateRoleId(roleId: string, paramName = 'roleId'): string {\n assertNonEmptyString(roleId, paramName);\n\n const trimmed = roleId.trim();\n\n if (!BYTES32_PATTERN.test(trimmed)) {\n throw new ConfigurationInvalid(\n `${paramName}: Invalid bytes32 role ID: ${trimmed}. Role IDs must be 0x-prefixed, 64-character hex strings (bytes32).`,\n roleId,\n paramName\n );\n }\n\n return trimmed.toLowerCase();\n}\n\n/**\n * Validates an array of role identifiers.\n *\n * Each role ID is validated as a bytes32 hex string. The array is deduplicated\n * before returning. An empty array is valid (means no known role IDs).\n *\n * @param roleIds - The array of role identifiers to validate\n * @param paramName - Optional parameter name for error messages (defaults to 'roleIds')\n * @returns The validated and deduplicated array of role IDs\n * @throws ConfigurationInvalid if the input is not an array or any role ID is invalid\n */\nexport function validateRoleIds(roleIds: string[], paramName = 'roleIds'): string[] {\n if (!Array.isArray(roleIds)) {\n throw new ConfigurationInvalid(`${paramName} must be an array`, String(roleIds), paramName);\n }\n\n const validated = roleIds.map((r, i) => validateRoleId(r, `${paramName}[${i}]`));\n\n return [...new Set(validated)];\n}\n\n// ---------------------------------------------------------------------------\n// Internal Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Asserts that a value is a non-empty string.\n *\n * @param value - The value to check\n * @param paramName - Parameter name for error messages\n * @throws ConfigurationInvalid if the value is not a non-empty string\n */\nfunction assertNonEmptyString(value: string, paramName: string): void {\n if (!value || typeof value !== 'string' || value.trim() === '') {\n throw new ConfigurationInvalid(\n `${paramName} is required and must be a non-empty string`,\n value,\n paramName\n );\n }\n}\n","import { type TransactionReceipt } from 'viem';\nimport React from 'react';\n\n// Core module imports - reusable EVM logic\nimport {\n compareContractDefinitions as coreCompareContractDefinitions,\n hashContractDefinition as coreHashContractDefinition,\n validateContractDefinition as coreValidateContractDefinition,\n createEvmAccessControlService,\n EvmProviderKeys,\n executeEvmTransaction,\n formatEvmFunctionResult,\n formatEvmTransactionData,\n generateEvmDefaultField,\n generateRainbowKitConfigFile,\n generateRainbowKitExportables,\n getEvmCompatibleFieldTypes,\n getEvmCurrentBlock,\n getEvmExplorerAddressUrl,\n getEvmExplorerTxUrl,\n getEvmTypeMappingInfo,\n isEvmViewFunction,\n isValidEvmAddress,\n loadContractSchema,\n loadContractWithFullMetadata,\n mapEvmParamTypeToFieldType,\n RelayerExecutionStrategy,\n resolveFullUiKitConfiguration,\n testEvmExplorerConnection,\n testEvmNetworkServiceConnection,\n testEvmRpcConnection,\n validateEvmExecutionConfig,\n validateEvmExplorerConfig,\n validateEvmNetworkServiceConfig,\n validateEvmRpcEndpoint,\n waitForEvmTransactionConfirmation,\n type EvmAccessControlService,\n type EvmContractDefinitionProviderKey,\n type TypedEvmNetworkConfig,\n type WriteContractParameters,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type {\n AccessControlService,\n AvailableUiKit,\n Connector,\n ContractAdapter,\n ContractFunction,\n ContractSchema,\n EcosystemReactUiProviderProps,\n EcosystemSpecificReactHooks,\n EcosystemWalletComponents,\n ExecutionConfig,\n ExecutionMethodDetail,\n FieldType,\n FormFieldType,\n FunctionParameter,\n NativeConfigLoader,\n NetworkConfig,\n NetworkServiceForm,\n ProxyInfo,\n RelayerDetails,\n RelayerDetailsRich,\n TransactionStatusUpdate,\n TxStatus,\n TypeMappingInfo,\n UiKitConfiguration,\n UserExplorerConfig,\n UserRpcProviderConfig,\n WalletConnectionStatus,\n} from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { EvmWalletUiRoot } from './wallet/components/EvmWalletUiRoot';\nimport { evmUiKitManager } from './wallet/evmUiKitManager';\nimport { evmFacadeHooks } from './wallet/hooks/facade-hooks';\nimport { loadInitialConfigFromAppService } from './wallet/hooks/useUiKitConfig';\n\n// Adapter-specific imports - EVM adapter orchestration\nimport {\n getEvmDefaultServiceConfig,\n getEvmNetworkServiceForms,\n getEvmSupportedExecutionMethods,\n} from './configuration';\n// Adapter-specific query with RPC resolution\nimport { queryEvmViewFunction } from './query';\nimport { EvmRelayerOptions } from './transaction';\nimport {\n connectAndEnsureCorrectNetwork,\n convertWagmiToEvmStatus,\n disconnectEvmWallet,\n evmSupportsWalletConnection,\n EvmWalletConnectionStatus,\n getEvmAvailableConnectors,\n getEvmWalletConnectionStatus,\n getEvmWalletImplementation,\n getInitializedEvmWalletImplementation,\n getResolvedWalletComponents,\n} from './wallet';\n\n/**\n * Type guard to check if a network config is a TypedEvmNetworkConfig\n * @param config The network configuration to check\n * @returns True if the config is for EVM\n */\nconst isTypedEvmNetworkConfig = (config: NetworkConfig): config is TypedEvmNetworkConfig =>\n config.ecosystem === 'evm';\n\n/**\n * EVM-specific adapter implementation\n */\nexport class EvmAdapter implements ContractAdapter {\n readonly networkConfig: TypedEvmNetworkConfig;\n readonly initialAppServiceKitName: UiKitConfiguration['kitName'];\n\n /**\n * Lazily initialized access control service (NFR-004).\n * Created on the first call to `getAccessControlService()` to avoid\n * unnecessary initialization overhead when access control is not used.\n */\n private accessControlService: EvmAccessControlService | null = null;\n\n constructor(networkConfig: TypedEvmNetworkConfig) {\n if (!isTypedEvmNetworkConfig(networkConfig)) {\n throw new Error('EvmAdapter requires a valid EVM network configuration.');\n }\n this.networkConfig = networkConfig;\n logger.info(\n 'EvmAdapter',\n `Adapter initialized for network: ${networkConfig.name} (ID: ${networkConfig.id})`\n );\n\n // Determine the initial kitName from AppConfigService at the time of adapter construction.\n // This provides a baseline kitName preference from the application's static/global configuration.\n // It defaults to 'custom' if no specific kitName is found in AppConfigService.\n // This value is stored on the instance to inform the first call to configureUiKit if no programmatic overrides are given.\n const initialGlobalConfig = loadInitialConfigFromAppService();\n this.initialAppServiceKitName =\n (initialGlobalConfig.kitName as UiKitConfiguration['kitName']) || 'custom';\n\n logger.info(\n 'EvmAdapter:constructor',\n 'Initial kitName from AppConfigService noted:',\n this.initialAppServiceKitName\n );\n // The actual EvmUiKitManager.configure call (which drives UI setup) is deferred.\n // It's typically triggered by WalletStateProvider after this adapter instance is fully initialized and provided to it,\n // ensuring that loadConfigModule (for user native configs) is available.\n }\n\n /**\n * @inheritdoc\n */\n public getNetworkServiceForms(): NetworkServiceForm[] {\n return getEvmNetworkServiceForms(this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async validateNetworkServiceConfig(\n serviceId: string,\n values: Record<string, unknown>\n ): Promise<boolean> {\n return validateEvmNetworkServiceConfig(serviceId, values);\n }\n\n /**\n * @inheritdoc\n */\n public async testNetworkServiceConnection(\n serviceId: string,\n values: Record<string, unknown>\n ): Promise<{ success: boolean; latency?: number; error?: string }> {\n return testEvmNetworkServiceConnection(serviceId, values, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public getDefaultServiceConfig(serviceId: string): Record<string, unknown> | null {\n return getEvmDefaultServiceConfig(this.networkConfig, serviceId);\n }\n\n /**\n * @inheritdoc\n */\n public async loadContract(source: string | Record<string, unknown>): Promise<ContractSchema> {\n return loadContractSchema(source, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async loadContractWithMetadata(source: string | Record<string, unknown>): Promise<{\n schema: ContractSchema;\n source: 'fetched' | 'manual';\n contractDefinitionOriginal?: string;\n metadata?: {\n fetchedFrom?: string;\n contractName?: string;\n verificationStatus?: 'verified' | 'unverified' | 'unknown';\n fetchTimestamp?: Date;\n definitionHash?: string;\n };\n proxyInfo?: ProxyInfo;\n }> {\n // Delegate to core convenience function\n // Errors (including unverified contract errors) are handled by the core function\n return loadContractWithFullMetadata(source, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n mapParameterTypeToFieldType(parameterType: string): FieldType {\n return mapEvmParamTypeToFieldType(parameterType);\n }\n\n /**\n * @inheritdoc\n */\n getCompatibleFieldTypes(parameterType: string): FieldType[] {\n return getEvmCompatibleFieldTypes(parameterType);\n }\n\n /**\n * @inheritdoc\n */\n generateDefaultField<T extends FieldType = FieldType>(\n parameter: FunctionParameter\n ): FormFieldType<T> {\n return generateEvmDefaultField(parameter);\n }\n\n /**\n * @inheritdoc\n */\n public formatTransactionData(\n contractSchema: ContractSchema,\n functionId: string,\n submittedInputs: Record<string, unknown>,\n fields: FormFieldType[]\n ): WriteContractParameters {\n return formatEvmTransactionData(contractSchema, functionId, submittedInputs, fields);\n }\n\n /**\n * @inheritdoc\n */\n public async signAndBroadcast(\n transactionData: unknown,\n executionConfig: ExecutionConfig,\n onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,\n runtimeApiKey?: string\n ): Promise<{ txHash: string }> {\n const walletImplementation = await getEvmWalletImplementation();\n return executeEvmTransaction(\n transactionData as WriteContractParameters,\n executionConfig,\n walletImplementation,\n onStatusChange,\n runtimeApiKey\n );\n }\n\n /**\n * @inheritdoc\n */\n public async getRelayers(serviceUrl: string, accessToken: string): Promise<RelayerDetails[]> {\n const relayerStrategy = new RelayerExecutionStrategy();\n return relayerStrategy.getEvmRelayers(serviceUrl, accessToken, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async getRelayer(\n serviceUrl: string,\n accessToken: string,\n relayerId: string\n ): Promise<RelayerDetailsRich> {\n const relayerStrategy = new RelayerExecutionStrategy();\n return relayerStrategy.getEvmRelayer(serviceUrl, accessToken, relayerId, this.networkConfig);\n }\n\n /**\n * Returns a React component for configuring EVM-specific relayer transaction options.\n * @returns The EVM relayer options component\n */\n public getRelayerOptionsComponent():\n | React.ComponentType<{\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n }>\n | undefined {\n return EvmRelayerOptions;\n }\n\n /**\n * @inheritdoc\n */\n public getWritableFunctions(contractSchema: ContractSchema): ContractSchema['functions'] {\n return contractSchema.functions.filter((fn) => fn.modifiesState);\n }\n\n /**\n * @inheritdoc\n */\n isValidAddress(address: string, _addressType?: string): boolean {\n // TODO: Could support ENS names as a different addressType (e.g., 'ens')\n // Viem provides normalize() and isAddress() functions that could validate ENS names\n // Example: addressType === 'ens' ? isValidEnsName(address) : isValidEvmAddress(address)\n\n // Currently, EVM treats all addresses uniformly (hex format)\n // The addressType parameter is ignored for backward compatibility with other chains\n return isValidEvmAddress(address);\n }\n\n /**\n * @inheritdoc\n */\n public async getSupportedExecutionMethods(): Promise<ExecutionMethodDetail[]> {\n return getEvmSupportedExecutionMethods();\n }\n\n /**\n * @inheritdoc\n */\n public async validateExecutionConfig(config: ExecutionConfig): Promise<true | string> {\n const walletStatus = this.getWalletConnectionStatus();\n return validateEvmExecutionConfig(config, walletStatus);\n }\n\n /**\n * @inheritdoc\n */\n isViewFunction(functionDetails: ContractFunction): boolean {\n return isEvmViewFunction(functionDetails);\n }\n\n /**\n * @inheritdoc\n */\n public filterAutoQueryableFunctions(functions: ContractFunction[]): ContractFunction[] {\n // Exclude admin/upgrade management getters that often revert or require permissions\n const skipNames = new Set([\n 'admin',\n 'implementation',\n 'getImplementation',\n '_implementation',\n 'proxyAdmin',\n 'changeAdmin',\n 'upgradeTo',\n 'upgradeToAndCall',\n ]);\n return functions.filter((f) => !skipNames.has(f.name));\n }\n\n /**\n * @inheritdoc\n */\n async queryViewFunction(\n contractAddress: string,\n functionId: string,\n params: unknown[] = [],\n contractSchema?: ContractSchema\n ): Promise<unknown> {\n const walletImplementation = await getEvmWalletImplementation();\n return queryEvmViewFunction(\n contractAddress,\n functionId,\n this.networkConfig,\n params,\n contractSchema,\n walletImplementation,\n (src: string) => this.loadContract({ contractAddress: src })\n );\n }\n\n /**\n * @inheritdoc\n */\n formatFunctionResult(decodedValue: unknown, functionDetails: ContractFunction): string {\n return formatEvmFunctionResult(decodedValue, functionDetails);\n }\n\n /**\n * @inheritdoc\n */\n public supportsWalletConnection(): boolean {\n return evmSupportsWalletConnection();\n }\n\n /**\n * @inheritdoc\n */\n public async getAvailableConnectors(): Promise<Connector[]> {\n return getEvmAvailableConnectors();\n }\n\n /**\n * @inheritdoc\n */\n public async connectWallet(\n connectorId: string\n ): Promise<{ connected: boolean; address?: string; error?: string }> {\n const result = await connectAndEnsureCorrectNetwork(connectorId, this.networkConfig.chainId);\n\n if (result.connected && result.address) {\n return { connected: true, address: result.address };\n } else {\n return {\n connected: false,\n error: result.error || 'Connection failed for an unknown reason.',\n };\n }\n }\n\n /**\n * @inheritdoc\n */\n public async disconnectWallet(): Promise<{ disconnected: boolean; error?: string }> {\n return disconnectEvmWallet();\n }\n\n /**\n * @inheritdoc\n */\n public getWalletConnectionStatus(): EvmWalletConnectionStatus {\n const status = getEvmWalletConnectionStatus();\n return convertWagmiToEvmStatus(status);\n }\n\n /**\n * @inheritdoc\n */\n public onWalletConnectionChange(\n callback: (\n currentStatus: WalletConnectionStatus,\n previousStatus: WalletConnectionStatus\n ) => void\n ): () => void {\n const walletImplementation = getInitializedEvmWalletImplementation();\n if (!walletImplementation) {\n logger.warn(\n 'EvmAdapter:onWalletConnectionChange',\n 'Wallet implementation not ready. Subscription may not work.'\n );\n return () => {};\n }\n return walletImplementation.onWalletConnectionChange(\n (currentWagmiStatus, previousWagmiStatus) => {\n // Convert wagmi's GetAccountReturnType to the rich adapter interface\n // This preserves all the enhanced UX capabilities from wagmi\n const current = convertWagmiToEvmStatus(currentWagmiStatus);\n const previous = convertWagmiToEvmStatus(previousWagmiStatus);\n\n callback(current, previous);\n }\n );\n }\n\n /**\n * @inheritdoc\n */\n getExplorerUrl(address: string): string | null {\n return getEvmExplorerAddressUrl(address, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n getExplorerTxUrl?(txHash: string): string | null {\n if (getEvmExplorerTxUrl) {\n return getEvmExplorerTxUrl(txHash, this.networkConfig);\n }\n return null;\n }\n\n /**\n * @inheritdoc\n */\n async getCurrentBlock(): Promise<number> {\n return getEvmCurrentBlock(this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n async waitForTransactionConfirmation(txHash: string): Promise<{\n status: 'success' | 'error';\n receipt?: TransactionReceipt;\n error?: Error;\n }> {\n const walletImplementation = await getEvmWalletImplementation();\n return waitForEvmTransactionConfirmation(txHash, walletImplementation);\n }\n\n /**\n * @inheritdoc\n */\n public async configureUiKit(\n programmaticOverrides: Partial<UiKitConfiguration> = {},\n options?: {\n loadUiKitNativeConfig?: NativeConfigLoader;\n }\n ): Promise<void> {\n const currentAppServiceConfig = loadInitialConfigFromAppService();\n\n // Delegate the entire configuration resolution to the service function.\n const finalFullConfig = await resolveFullUiKitConfiguration(\n programmaticOverrides,\n this.initialAppServiceKitName,\n currentAppServiceConfig,\n options\n );\n\n // Delegate the application of this configuration to the central EvmUiKitManager.\n await evmUiKitManager.configure(finalFullConfig);\n logger.info(\n 'EvmAdapter:configureUiKit',\n 'EvmUiKitManager configuration requested with final config:',\n finalFullConfig\n );\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemReactUiContextProvider():\n | React.ComponentType<EcosystemReactUiProviderProps>\n | undefined {\n // EvmWalletUiRoot is now the stable provider that subscribes to evmUiKitManager\n logger.info('EvmAdapter:getEcosystemReactUiContextProvider', 'Returning EvmWalletUiRoot.');\n return EvmWalletUiRoot;\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemReactHooks(): EcosystemSpecificReactHooks | undefined {\n // Always provide hooks for EVM adapter regardless of UI kit\n return evmFacadeHooks;\n }\n\n /**\n * @inheritdoc\n */\n public getSupportedContractDefinitionProviders(): Array<{\n key: EvmContractDefinitionProviderKey;\n label?: string;\n }> {\n return [\n { key: EvmProviderKeys.Etherscan, label: 'Etherscan' },\n { key: EvmProviderKeys.Sourcify, label: 'Sourcify' },\n ];\n }\n\n /**\n * @inheritdoc\n */\n public getEcosystemWalletComponents(): EcosystemWalletComponents | undefined {\n const currentManagerState = evmUiKitManager.getState();\n // Only attempt to resolve components if the manager has a configuration set.\n // During initial app load, currentFullUiKitConfig might be null until the first configure call completes.\n if (!currentManagerState.currentFullUiKitConfig) {\n logger.debug(\n // Changed from warn to debug, as this can be normal during init sequence\n 'EvmAdapter:getEcosystemWalletComponents',\n 'No UI kit configuration available in manager yet. Returning undefined components.'\n );\n return undefined; // Explicitly return undefined if manager isn't configured yet\n }\n // If manager has a config, use that for resolving components.\n return getResolvedWalletComponents(currentManagerState.currentFullUiKitConfig);\n }\n\n public async getAvailableUiKits(): Promise<AvailableUiKit[]> {\n const rainbowkitDefaultCode = generateRainbowKitConfigFile({});\n\n return [\n {\n id: 'custom',\n name: 'Wagmi Custom',\n configFields: [],\n },\n {\n id: 'rainbowkit',\n name: 'RainbowKit',\n linkToDocs: 'https://www.rainbowkit.com/docs/installation#configure',\n description: `Configure RainbowKit for your exported application. This code will be saved as <code class=\"bg-muted px-1 py-0.5 rounded text-xs\">rainbowkit.config.ts</code>.<br/><br/>\n<strong>Export Only:</strong> This configuration is <em>only used in exported apps</em>. The preview always uses the default RainbowKit configuration.<br/><br/>\n<strong>Available options:</strong><br/>\n• <code>wagmiParams</code>: Configure app name, projectId, wallets, etc.<br/>\n• <code>providerProps</code>: Set theme, modal size, and other UI options<br/><br/>\nGet your WalletConnect projectId from <a href=\"https://cloud.walletconnect.com\" target=\"_blank\" rel=\"noopener\" class=\"text-primary underline\">cloud.walletconnect.com</a>`,\n hasCodeEditor: true,\n defaultCode: rainbowkitDefaultCode,\n configFields: [],\n },\n ];\n }\n\n public async getExportableWalletConfigFiles(\n uiKitConfig?: UiKitConfiguration\n ): Promise<Record<string, string>> {\n if (uiKitConfig?.kitName === 'rainbowkit') {\n return generateRainbowKitExportables(uiKitConfig);\n }\n return {};\n }\n\n /**\n * @inheritdoc\n */\n public getUiLabels(): Record<string, string> | undefined {\n return {\n relayerConfigTitle: 'Gas Configuration',\n relayerConfigActiveDesc: 'Customize gas pricing strategy for transaction submission',\n relayerConfigInactiveDesc: 'Using recommended gas configuration for reliable transactions',\n relayerConfigPresetTitle: 'Fast Speed Preset Active',\n relayerConfigPresetDesc:\n 'Transactions will use high priority gas pricing for quick inclusion',\n relayerConfigCustomizeBtn: 'Customize Gas Settings',\n detailsTitle: 'Relayer Details',\n network: 'Network',\n relayerId: 'Relayer ID',\n active: 'Active',\n paused: 'Paused',\n systemDisabled: 'System Disabled',\n balance: 'Balance',\n nonce: 'Nonce',\n pending: 'Pending Transactions',\n lastTransaction: 'Last Transaction',\n };\n }\n\n /**\n * @inheritdoc\n */\n public getContractDefinitionInputs(): FormFieldType[] {\n return [\n {\n id: 'contractAddress',\n name: 'contractAddress',\n label: 'Contract Address',\n type: 'blockchain-address',\n validation: { required: true },\n placeholder: '0x1234...abcd',\n helperText:\n 'Enter the deployed contract address. For verified contracts, the ABI will be fetched automatically from the block explorer.',\n },\n {\n id: 'contractDefinition',\n name: 'contractDefinition',\n label: 'Contract ABI (Optional)',\n type: 'code-editor',\n validation: { required: false },\n placeholder:\n '[{\"inputs\":[],\"name\":\"myFunction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]',\n helperText:\n \"If the contract is not verified on the block explorer, paste the contract's ABI JSON here. You can find this in your contract's compilation artifacts or deployment files.\",\n codeEditorProps: {\n language: 'json',\n placeholder: 'Paste your contract ABI JSON here...',\n maxHeight: '500px',\n performanceThreshold: 3000, // Disable syntax highlighting for large ABIs\n },\n },\n ];\n }\n\n /**\n * @inheritdoc\n */\n public async validateRpcEndpoint(rpcConfig: UserRpcProviderConfig): Promise<boolean> {\n return validateEvmRpcEndpoint(rpcConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async testRpcConnection(rpcConfig: UserRpcProviderConfig): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n }> {\n return testEvmRpcConnection(rpcConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async validateExplorerConfig(explorerConfig: UserExplorerConfig): Promise<boolean> {\n return validateEvmExplorerConfig(explorerConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async testExplorerConnection(explorerConfig: UserExplorerConfig): Promise<{\n success: boolean;\n latency?: number;\n error?: string;\n }> {\n return testEvmExplorerConnection(explorerConfig, this.networkConfig);\n }\n\n /**\n * @inheritdoc\n */\n public async compareContractDefinitions(\n storedSchema: string,\n freshSchema: string\n ): Promise<{\n identical: boolean;\n differences: Array<{\n type: 'added' | 'removed' | 'modified';\n section: string;\n name: string;\n details: string;\n impact: 'low' | 'medium' | 'high';\n oldSignature?: string;\n newSignature?: string;\n }>;\n severity: 'none' | 'minor' | 'major' | 'breaking';\n summary: string;\n }> {\n // Delegate to core convenience function\n return coreCompareContractDefinitions(storedSchema, freshSchema);\n }\n\n /**\n * @inheritdoc\n */\n public validateContractDefinition(definition: string): {\n valid: boolean;\n errors: string[];\n warnings: string[];\n } {\n // Delegate to core convenience function\n return coreValidateContractDefinition(definition);\n }\n\n /**\n * @inheritdoc\n */\n public hashContractDefinition(definition: string): string {\n // Delegate to core convenience function\n return coreHashContractDefinition(definition);\n }\n\n /**\n * @inheritdoc\n *\n * Returns a lazily initialized `EvmAccessControlService` instance.\n * The service is created on first call with an `executeTransaction` callback\n * that wraps `signAndBroadcast`, decoupling the access control module from\n * wallet/signing infrastructure.\n *\n * @returns The AccessControlService for this adapter's network\n * @see research.md §R9 — Service Lifecycle and Transaction Execution\n */\n public getAccessControlService(): AccessControlService {\n if (!this.accessControlService) {\n logger.info(\n 'EvmAdapter:getAccessControlService',\n 'Initializing EvmAccessControlService (lazy, first call)'\n );\n\n this.accessControlService = createEvmAccessControlService(\n this.networkConfig,\n async (txData, executionConfig, onStatusChange, runtimeApiKey) => {\n const defaultStatusHandler = onStatusChange ?? (() => {});\n const result = await this.signAndBroadcast(\n txData,\n executionConfig,\n defaultStatusHandler,\n runtimeApiKey\n );\n return { id: result.txHash };\n }\n );\n }\n\n return this.accessControlService;\n }\n\n /**\n * @inheritdoc\n */\n public getTypeMappingInfo(): TypeMappingInfo {\n return getEvmTypeMappingInfo();\n }\n}\n\n// Also export as default to ensure compatibility with various import styles\nexport default EvmAdapter;\n","import { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { createConfig, http } from '@wagmi/core';\nimport { mainnet } from 'viem/chains';\nimport { WagmiProvider } from 'wagmi';\nimport React, { useEffect, useMemo, useState } from 'react';\n\nimport { WagmiProviderInitializedContext } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EcosystemReactUiProviderProps } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { evmUiKitManager, type EvmUiKitManagerState } from '../evmUiKitManager';\nimport type { RainbowKitKitConfig, RainbowKitProviderProps } from '../rainbowkit';\n\n// Create a single QueryClient instance to be reused by EvmWalletUiRoot instances.\n// This should be stable across re-renders of EvmWalletUiRoot itself.\nconst stableQueryClient = new QueryClient();\n\n// Create a minimal, default WagmiConfig to use when no other config is ready.\n// This ensures WagmiProvider can always be mounted with a valid config object.\n// Uses mainnet as a minimal default chain with HTTP transport.\nconst minimalDefaultWagmiConfig = createConfig({\n chains: [mainnet], // At least one chain is required in wagmi v2.20+\n connectors: [], // Empty connectors array\n transports: {\n [mainnet.id]: http(), // Basic HTTP transport for the default chain\n },\n});\n\nexport const EvmWalletUiRoot: React.FC<EcosystemReactUiProviderProps> = ({ children }) => {\n const [managerState, setManagerState] = useState<EvmUiKitManagerState>(\n evmUiKitManager.getState()\n );\n\n useEffect(() => {\n const handleStateChange = () => {\n setManagerState(evmUiKitManager.getState());\n };\n const unsubscribe = evmUiKitManager.subscribe(handleStateChange);\n handleStateChange();\n return unsubscribe;\n }, []); // Kept empty dep array as per previous working state of subscription\n\n // Memoize QueryClient to ensure stability if we ever decide to make it configurable per instance\n const queryClient = useMemo(() => stableQueryClient, []);\n\n const {\n wagmiConfig,\n kitProviderComponent,\n isKitAssetsLoaded,\n currentFullUiKitConfig,\n isInitializing,\n error,\n } = managerState;\n\n const configForWagmiProvider = wagmiConfig || minimalDefaultWagmiConfig;\n const isWagmiContextEffectivelyReady = !!wagmiConfig && !error;\n\n let finalChildren = children;\n\n // TODO: If many UI kits are added, and each requires a distinct way of being\n // rendered as a provider around `children` (beyond just passing different providerProps),\n // this conditional logic might become complex. Consider a strategy pattern or a\n // more abstract way to obtain the fully composed `innerContent` based on kitName.\n // For now, with RainbowKit and custom/default, this is manageable.\n if (\n isWagmiContextEffectivelyReady &&\n currentFullUiKitConfig?.kitName === 'rainbowkit' &&\n kitProviderComponent &&\n isKitAssetsLoaded\n ) {\n const DynKitProvider = kitProviderComponent;\n const kitConfig: RainbowKitKitConfig = currentFullUiKitConfig.kitConfig || {};\n\n // Pass through all provider props from the parsed config\n const providerProps: RainbowKitProviderProps = kitConfig.providerProps || {};\n\n logger.info(\n 'EvmWalletUiRoot',\n 'Wrapping children with dynamically loaded KitProvider (RainbowKit).'\n );\n finalChildren = <DynKitProvider {...providerProps}>{children}</DynKitProvider>;\n } else if (currentFullUiKitConfig?.kitName === 'rainbowkit' && !isWagmiContextEffectivelyReady) {\n logger.info(\n 'EvmWalletUiRoot',\n 'RainbowKit configured, but context or assets not ready. Button may show its loading/error state.'\n );\n }\n // For 'custom' kit, finalChildren also remains children.\n\n return (\n <WagmiProvider config={configForWagmiProvider}>\n <QueryClientProvider client={queryClient}>\n <WagmiProviderInitializedContext.Provider value={isWagmiContextEffectivelyReady}>\n {finalChildren}\n {isInitializing && (\n <div\n style={{\n position: 'fixed',\n top: '10px',\n right: '10px',\n background: 'rgba(0,0,0,0.1)',\n padding: '5px',\n borderRadius: '3px',\n fontSize: '0.8em',\n }}\n >\n Updating network...\n </div>\n )}\n {error && !wagmiConfig && (\n <div\n style={{\n position: 'fixed',\n bottom: '10px',\n left: '10px',\n background: 'red',\n color: 'white',\n padding: '10px',\n }}\n >\n Error initializing wallet provider: {error.message}\n </div>\n )}\n </WagmiProviderInitializedContext.Provider>\n </QueryClientProvider>\n </WagmiProvider>\n );\n};\n","import type { WagmiWalletImplementation } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\nimport { createEvmWalletImplementation } from '../implementation/wagmi-implementation';\n\nlet walletImplementationInstance: WagmiWalletImplementation | undefined;\nlet walletImplementationPromise: Promise<WagmiWalletImplementation> | undefined;\n\nconst LOG_SYSTEM = 'EvmWalletImplementationManager';\n\n/**\n * Get or create the singleton instance of WagmiWalletImplementation.\n * This function ensures that the initialization logic runs only once.\n *\n * @returns A Promise resolving to the WagmiWalletImplementation singleton\n */\nexport async function getEvmWalletImplementation(): Promise<WagmiWalletImplementation> {\n if (walletImplementationInstance) {\n return walletImplementationInstance;\n }\n\n if (walletImplementationPromise) {\n return walletImplementationPromise;\n }\n\n walletImplementationPromise = (async () => {\n try {\n logger.info(LOG_SYSTEM, 'Initializing WagmiWalletImplementation singleton (async)... ');\n // Get appName and projectId from appConfigService for RainbowKit\n // This assumes appConfigService is initialized before this manager is first called.\n const initialUiKitConfig = appConfigService.getTypedNestedConfig<UiKitConfiguration>(\n 'walletui',\n 'config'\n );\n\n const wcProjectId = appConfigService.getGlobalServiceParam('walletconnect', 'projectId') as\n | string\n | undefined;\n\n // Use factory function for proper EVM configuration\n const instance = createEvmWalletImplementation(wcProjectId, initialUiKitConfig);\n logger.info(LOG_SYSTEM, 'WagmiWalletImplementation singleton created (async).');\n walletImplementationInstance = instance;\n return instance;\n } catch (error) {\n logger.error(LOG_SYSTEM, 'Failed to initialize WagmiWalletImplementation (async):', error);\n const fallbackInstance = createEvmWalletImplementation();\n walletImplementationInstance = fallbackInstance;\n return fallbackInstance;\n }\n })();\n\n return walletImplementationPromise;\n}\n\n// Optional: A synchronous getter for cases where the instance is known to be initialized.\n// Use with caution, prefer the async getter.\nexport function getInitializedEvmWalletImplementation(): WagmiWalletImplementation | undefined {\n if (!walletImplementationInstance) {\n logger.warn(\n LOG_SYSTEM,\n 'getInitializedEvmWalletImplementation called before instance was ready.'\n );\n }\n return walletImplementationInstance;\n}\n","import {\n NetworkArbitrumOne,\n NetworkAvalanche,\n NetworkBase,\n NetworkBinanceSmartChain,\n NetworkEthereum,\n NetworkLinea,\n NetworkOptimism,\n NetworkPolygon,\n NetworkScroll,\n NetworkZksync,\n} from '@web3icons/react';\nimport {\n arbitrum as viemArbitrum,\n avalanche as viemAvalanche,\n base as viemBase,\n bsc as viemBsc,\n linea as viemLinea,\n mainnet as viemMainnet,\n optimism as viemOptimism,\n polygon as viemPolygon,\n polygonZkEvm as viemPolygonZkEvm,\n scroll as viemScroll,\n zksync as viemZkSync,\n} from 'viem/chains';\n\nimport type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport const ethereumMainnet: TypedEvmNetworkConfig = {\n id: 'ethereum-mainnet',\n exportConstName: 'ethereumMainnet',\n name: 'Ethereum',\n ecosystem: 'evm',\n network: 'ethereum',\n type: 'mainnet',\n isTestnet: false,\n chainId: 1,\n rpcUrl: viemMainnet.rpcUrls.default.http[0],\n explorerUrl: 'https://etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkEthereum,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemMainnet,\n accessControlIndexerUrl: 'https://openzeppelin-ethereum-mainnet.graphql.subquery.network/',\n};\n\nexport const arbitrumMainnet: TypedEvmNetworkConfig = {\n id: 'arbitrum-mainnet',\n exportConstName: 'arbitrumMainnet',\n name: 'Arbitrum One',\n ecosystem: 'evm',\n network: 'arbitrum',\n type: 'mainnet',\n isTestnet: false,\n chainId: 42161,\n rpcUrl: viemArbitrum.rpcUrls.default.http[0],\n explorerUrl: 'https://arbiscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkArbitrumOne,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemArbitrum,\n accessControlIndexerUrl: 'https://openzeppelin-arbitrum-mainnet.graphql.subquery.network/',\n};\n\nexport const polygonMainnet: TypedEvmNetworkConfig = {\n id: 'polygon-mainnet',\n exportConstName: 'polygonMainnet',\n name: 'Polygon',\n ecosystem: 'evm',\n network: 'polygon',\n type: 'mainnet',\n isTestnet: false,\n chainId: 137,\n rpcUrl: viemPolygon.rpcUrls.default.http[0],\n explorerUrl: 'https://polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'MATIC',\n symbol: 'MATIC',\n decimals: 18,\n },\n viemChain: viemPolygon,\n accessControlIndexerUrl: 'https://openzeppelin-polygon-mainnet.graphql.subquery.network/',\n};\n\nexport const polygonZkEvmMainnet: TypedEvmNetworkConfig = {\n id: 'polygon-zkevm-mainnet',\n exportConstName: 'polygonZkEvmMainnet',\n name: 'Polygon zkEVM',\n ecosystem: 'evm',\n network: 'polygon-zkevm',\n type: 'mainnet',\n isTestnet: false,\n chainId: 1101,\n rpcUrl: viemPolygonZkEvm.rpcUrls.default.http[0],\n explorerUrl: 'https://zkevm.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemPolygonZkEvm,\n accessControlIndexerUrl: 'https://openzeppelin-polygon-zkevm-mainnet.graphql.subquery.network/',\n};\n\nexport const baseMainnet: TypedEvmNetworkConfig = {\n id: 'base-mainnet',\n exportConstName: 'baseMainnet',\n name: 'Base',\n ecosystem: 'evm',\n network: 'base',\n type: 'mainnet',\n isTestnet: false,\n chainId: 8453,\n rpcUrl: viemBase.rpcUrls.default.http[0],\n explorerUrl: 'https://basescan.org',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBase,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemBase,\n accessControlIndexerUrl: 'https://openzeppelin-base-mainnet.graphql.subquery.network/',\n};\n\nexport const bscMainnet: TypedEvmNetworkConfig = {\n id: 'bsc-mainnet',\n exportConstName: 'bscMainnet',\n name: 'BNB Smart Chain',\n ecosystem: 'evm',\n network: 'bsc',\n type: 'mainnet',\n isTestnet: false,\n chainId: 56,\n rpcUrl: viemBsc.rpcUrls.default.http[0],\n explorerUrl: 'https://bscscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBinanceSmartChain,\n nativeCurrency: {\n name: 'BNB',\n symbol: 'BNB',\n decimals: 18,\n },\n viemChain: viemBsc,\n accessControlIndexerUrl: 'https://openzeppelin-bsc-mainnet.graphql.subquery.network/',\n};\n\nexport const optimismMainnet: TypedEvmNetworkConfig = {\n id: 'optimism-mainnet',\n exportConstName: 'optimismMainnet',\n name: 'OP Mainnet',\n ecosystem: 'evm',\n network: 'optimism',\n type: 'mainnet',\n isTestnet: false,\n chainId: 10,\n rpcUrl: viemOptimism.rpcUrls.default.http[0],\n explorerUrl: 'https://optimistic.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkOptimism,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemOptimism,\n accessControlIndexerUrl: 'https://openzeppelin-optimism-mainnet.graphql.subquery.network/',\n};\n\nexport const avalancheMainnet: TypedEvmNetworkConfig = {\n id: 'avalanche-mainnet',\n exportConstName: 'avalancheMainnet',\n name: 'Avalanche C-Chain',\n ecosystem: 'evm',\n network: 'avalanche',\n type: 'mainnet',\n isTestnet: false,\n chainId: 43114,\n rpcUrl: viemAvalanche.rpcUrls.default.http[0],\n explorerUrl: 'https://snowscan.xyz',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkAvalanche,\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n viemChain: viemAvalanche,\n accessControlIndexerUrl: 'https://openzeppelin-avalanche-mainnet.graphql.subquery.network/',\n};\n\n// TODO: test and setup the api and explorer config\nexport const zkSyncEraMainnet: TypedEvmNetworkConfig = {\n id: 'zksync-era-mainnet',\n exportConstName: 'zkSyncEraMainnet',\n name: 'ZkSync Era',\n ecosystem: 'evm',\n network: 'zksync-era',\n type: 'mainnet',\n isTestnet: false,\n chainId: 324,\n rpcUrl: viemZkSync.rpcUrls.default.http[0],\n explorerUrl: 'https://explorer.zksync.io',\n apiUrl: 'https://block-explorer-api.mainnet.zksync.io/api',\n primaryExplorerApiIdentifier: 'zksync-era-mainnet',\n supportsEtherscanV2: false,\n iconComponent: NetworkZksync,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemZkSync,\n accessControlIndexerUrl: 'https://openzeppelin-zksync-era-mainnet.graphql.subquery.network/',\n};\n\nexport const scrollMainnet: TypedEvmNetworkConfig = {\n id: 'scroll-mainnet',\n exportConstName: 'scrollMainnet',\n name: 'Scroll',\n ecosystem: 'evm',\n network: 'scroll',\n type: 'mainnet',\n isTestnet: false,\n chainId: 534352,\n rpcUrl: viemScroll.rpcUrls.default.http[0],\n explorerUrl: 'https://scrollscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkScroll,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemScroll,\n accessControlIndexerUrl: 'https://openzeppelin-scroll-mainnet.graphql.subquery.network/',\n};\n\nexport const lineaMainnet: TypedEvmNetworkConfig = {\n id: 'linea-mainnet',\n exportConstName: 'lineaMainnet',\n name: 'Linea',\n ecosystem: 'evm',\n network: 'linea',\n type: 'mainnet',\n isTestnet: false,\n chainId: 59144,\n rpcUrl: viemLinea.rpcUrls.default.http[0],\n explorerUrl: 'https://lineascan.build',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkLinea,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemLinea,\n accessControlIndexerUrl: 'https://openzeppelin-linea-mainnet.graphql.subquery.network/',\n};\n\n// TODO: Add other EVM mainnet networks with their public RPCs and viemChain objects\n","import {\n NetworkArbitrumOne,\n NetworkAvalanche,\n NetworkBase,\n NetworkBinanceSmartChain,\n NetworkEthereum,\n NetworkLinea,\n NetworkMonad,\n NetworkOptimism,\n NetworkPolygon,\n NetworkScroll,\n NetworkZksync,\n} from '@web3icons/react';\nimport {\n arbitrumSepolia as viemArbitrumSepolia,\n avalancheFuji as viemAvalancheFuji,\n baseSepolia as viemBaseSepolia,\n bscTestnet as viemBscTestnet,\n lineaSepolia as viemLineaSepolia,\n monadTestnet as viemMonadTestnet,\n optimismSepolia as viemOptimismSepolia,\n polygonAmoy as viemPolygonAmoy,\n polygonZkEvmCardona as viemPolygonZkEvmCardona,\n scrollSepolia as viemScrollSepolia,\n sepolia as viemSepolia,\n zksyncSepoliaTestnet as viemZkSyncSepoliaTestnet,\n} from 'viem/chains';\n\nimport type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport const ethereumSepolia: TypedEvmNetworkConfig = {\n id: 'ethereum-sepolia',\n exportConstName: 'ethereumSepolia',\n name: 'Sepolia',\n ecosystem: 'evm',\n network: 'ethereum',\n type: 'testnet',\n isTestnet: true,\n chainId: 11155111,\n rpcUrl: viemSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkEthereum,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-ethereum-sepolia.graphql.subquery.network/',\n};\n\nexport const arbitrumSepolia: TypedEvmNetworkConfig = {\n id: 'arbitrum-sepolia',\n exportConstName: 'arbitrumSepolia',\n name: 'Arbitrum Sepolia',\n ecosystem: 'evm',\n network: 'arbitrum',\n type: 'testnet',\n isTestnet: true,\n chainId: 421614,\n rpcUrl: viemArbitrumSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.arbiscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkArbitrumOne,\n nativeCurrency: {\n name: 'Arbitrum Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemArbitrumSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-arbitrum-sepolia.graphql.subquery.network/',\n};\n\nexport const polygonAmoy: TypedEvmNetworkConfig = {\n id: 'polygon-amoy',\n exportConstName: 'polygonAmoy',\n name: 'Polygon Amoy',\n ecosystem: 'evm',\n network: 'polygon',\n type: 'testnet',\n isTestnet: true,\n chainId: 80002,\n rpcUrl: viemPolygonAmoy.rpcUrls.default.http[0],\n explorerUrl: 'https://amoy.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'MATIC',\n symbol: 'MATIC',\n decimals: 18,\n },\n viemChain: viemPolygonAmoy,\n accessControlIndexerUrl: 'https://openzeppelin-polygon-amoy.graphql.subquery.network/',\n};\n\nexport const polygonZkEvmCardona: TypedEvmNetworkConfig = {\n id: 'polygon-zkevm-cardona',\n exportConstName: 'polygonZkEvmCardona',\n name: 'Polygon zkEVM Cardona',\n ecosystem: 'evm',\n network: 'polygon-zkevm',\n type: 'testnet',\n isTestnet: true,\n chainId: 2442,\n rpcUrl: viemPolygonZkEvmCardona.rpcUrls.default.http[0],\n explorerUrl: 'https://cardona-zkevm.polygonscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkPolygon,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemPolygonZkEvmCardona,\n accessControlIndexerUrl: 'https://openzeppelin-polygon-zkevm-cardona.graphql.subquery.network/',\n};\n\nexport const baseSepolia: TypedEvmNetworkConfig = {\n id: 'base-sepolia',\n exportConstName: 'baseSepolia',\n name: 'Base Sepolia',\n ecosystem: 'evm',\n network: 'base',\n type: 'testnet',\n isTestnet: true,\n chainId: 84532,\n rpcUrl: viemBaseSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.basescan.org',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBase,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemBaseSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-base-sepolia.graphql.subquery.network/',\n};\n\nexport const bscTestnet: TypedEvmNetworkConfig = {\n id: 'bsc-testnet',\n exportConstName: 'bscTestnet',\n name: 'BSC Testnet',\n ecosystem: 'evm',\n network: 'bsc',\n type: 'testnet',\n isTestnet: true,\n chainId: 97,\n rpcUrl: viemBscTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.bscscan.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkBinanceSmartChain,\n nativeCurrency: {\n name: 'BNB',\n symbol: 'BNB',\n decimals: 18,\n },\n viemChain: viemBscTestnet,\n accessControlIndexerUrl: 'https://openzeppelin-bsc-testnet.graphql.subquery.network/',\n};\n\nexport const optimismSepolia: TypedEvmNetworkConfig = {\n id: 'optimism-sepolia',\n exportConstName: 'optimismSepolia',\n name: 'OP Sepolia',\n ecosystem: 'evm',\n network: 'optimism',\n type: 'testnet',\n isTestnet: true,\n chainId: 11155420,\n rpcUrl: viemOptimismSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia-optimism.etherscan.io',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkOptimism,\n nativeCurrency: {\n name: 'Sepolia Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemOptimismSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-optimism-sepolia.graphql.subquery.network/',\n};\n\nexport const avalancheFuji: TypedEvmNetworkConfig = {\n id: 'avalanche-fuji',\n exportConstName: 'avalancheFuji',\n name: 'Avalanche Fuji C-Chain',\n ecosystem: 'evm',\n network: 'avalanche',\n type: 'testnet',\n isTestnet: true,\n chainId: 43113,\n rpcUrl: viemAvalancheFuji.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.snowscan.xyz',\n apiUrl: 'https://api.etherscan.io/v2/api', // Using Etherscan V2 unified API\n primaryExplorerApiIdentifier: 'etherscan-v2', // Unified identifier for V2 API\n supportsEtherscanV2: true,\n requiresExplorerApiKey: true,\n iconComponent: NetworkAvalanche,\n nativeCurrency: {\n name: 'Avalanche',\n symbol: 'AVAX',\n decimals: 18,\n },\n viemChain: viemAvalancheFuji,\n accessControlIndexerUrl: 'https://openzeppelin-avalanche-fuji.graphql.subquery.network/',\n};\n\n// TODO: test and setup the api and explorer config\nexport const zksyncSepoliaTestnet: TypedEvmNetworkConfig = {\n id: 'zksync-era-sepolia',\n exportConstName: 'zksyncSepoliaTestnet',\n name: 'ZkSync Era Sepolia',\n ecosystem: 'evm',\n network: 'zksync-era',\n type: 'testnet',\n isTestnet: true,\n chainId: 300,\n rpcUrl: viemZkSyncSepoliaTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.explorer.zksync.io',\n apiUrl: 'https://block-explorer-api.sepolia.zksync.dev/api',\n primaryExplorerApiIdentifier: 'zksync-era-sepolia',\n supportsEtherscanV2: false,\n iconComponent: NetworkZksync,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemZkSyncSepoliaTestnet,\n accessControlIndexerUrl: 'https://openzeppelin-zksync-era-sepolia.graphql.subquery.network/',\n};\n\nexport const scrollSepolia: TypedEvmNetworkConfig = {\n id: 'scroll-sepolia',\n exportConstName: 'scrollSepolia',\n name: 'Scroll Sepolia',\n ecosystem: 'evm',\n network: 'scroll',\n type: 'testnet',\n isTestnet: true,\n chainId: 534351,\n rpcUrl: viemScrollSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.scrollscan.dev',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkScroll,\n nativeCurrency: {\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemScrollSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-scroll-sepolia.graphql.subquery.network/',\n};\n\nexport const lineaSepolia: TypedEvmNetworkConfig = {\n id: 'linea-sepolia',\n exportConstName: 'lineaSepolia',\n name: 'Linea Sepolia',\n ecosystem: 'evm',\n network: 'linea',\n type: 'testnet',\n isTestnet: true,\n chainId: 59141,\n rpcUrl: viemLineaSepolia.rpcUrls.default.http[0],\n explorerUrl: 'https://sepolia.lineascan.build',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkLinea,\n nativeCurrency: {\n name: 'Linea Ether',\n symbol: 'ETH',\n decimals: 18,\n },\n viemChain: viemLineaSepolia,\n accessControlIndexerUrl: 'https://openzeppelin-linea-sepolia.graphql.subquery.network/',\n};\n\nexport const monadTestnet: TypedEvmNetworkConfig = {\n id: 'monad-testnet',\n exportConstName: 'monadTestnet',\n name: 'Monad Testnet',\n ecosystem: 'evm',\n network: 'monad',\n type: 'testnet',\n isTestnet: true,\n chainId: 10143,\n rpcUrl: viemMonadTestnet.rpcUrls.default.http[0],\n explorerUrl: 'https://testnet.monadexplorer.com',\n apiUrl: 'https://api.etherscan.io/v2/api',\n primaryExplorerApiIdentifier: 'etherscan-v2',\n supportsEtherscanV2: true,\n iconComponent: NetworkMonad,\n nativeCurrency: {\n name: 'Monad',\n symbol: 'MON',\n decimals: 18,\n },\n viemChain: viemMonadTestnet,\n accessControlIndexerUrl: 'https://openzeppelin-monad-testnet.graphql.subquery.network/',\n};\n\n// TODO: Add other EVM testnet networks as needed (e.g., Arbitrum Sepolia)\n","import type { TypedEvmNetworkConfig } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport {\n arbitrumMainnet,\n avalancheMainnet,\n baseMainnet,\n bscMainnet,\n ethereumMainnet,\n lineaMainnet,\n optimismMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n} from './mainnet';\nimport {\n arbitrumSepolia,\n avalancheFuji,\n baseSepolia,\n bscTestnet,\n ethereumSepolia,\n lineaSepolia,\n monadTestnet,\n optimismSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n scrollSepolia,\n zksyncSepoliaTestnet,\n} from './testnet';\n\n// All mainnet networks\nexport const evmMainnetNetworks: TypedEvmNetworkConfig[] = [\n ethereumMainnet,\n arbitrumMainnet,\n baseMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n // Other mainnet networks...\n];\n\n// All testnet networks\nexport const evmTestnetNetworks: TypedEvmNetworkConfig[] = [\n ethereumSepolia,\n arbitrumSepolia,\n baseSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n monadTestnet,\n // Other testnet networks...\n];\n\n// All EVM networks\n// NOTE: The wagmi integration automatically uses all networks defined here that have a `viemChain` property.\n// This ensures that adding a new network to mainnet.ts or testnet.ts automatically makes it available to wagmi.\nexport const evmNetworks: TypedEvmNetworkConfig[] = [...evmMainnetNetworks, ...evmTestnetNetworks];\n\n// Export individual networks for direct import\nexport {\n // Mainnet networks\n ethereumMainnet,\n arbitrumMainnet,\n baseMainnet,\n polygonMainnet,\n polygonZkEvmMainnet,\n bscMainnet,\n optimismMainnet,\n avalancheMainnet,\n lineaMainnet,\n scrollMainnet,\n zkSyncEraMainnet,\n // Testnet networks\n ethereumSepolia,\n arbitrumSepolia,\n baseSepolia,\n polygonAmoy,\n polygonZkEvmCardona,\n bscTestnet,\n optimismSepolia,\n avalancheFuji,\n lineaSepolia,\n scrollSepolia,\n zksyncSepoliaTestnet,\n monadTestnet,\n};\n","/**\n * EVM Wagmi Wallet Implementation\n *\n * This file configures and exports the core WagmiWalletImplementation\n * with EVM-specific settings.\n */\nimport {\n WagmiWalletImplementation as CoreWagmiWalletImplementation,\n getWagmiConfigForRainbowKit,\n type WagmiConfigChains,\n type WagmiWalletConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { UiKitConfiguration } from '@openzeppelin/ui-types';\n\nimport { evmNetworks } from '../../networks';\n\n/**\n * Generates the supported chains from EVM network configurations.\n * Only includes networks that have a viemChain property (ensuring wagmi compatibility).\n */\nconst getSupportedChainsFromNetworks = () => {\n return evmNetworks\n .filter((network) => network.viemChain)\n .map((network) => network.viemChain!)\n .filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index);\n};\n\n/**\n * The supported chains for EVM adapter.\n */\nconst defaultSupportedChains = getSupportedChainsFromNetworks();\n\n/**\n * Create an EVM-configured WagmiWalletImplementation instance.\n *\n * @param walletConnectProjectId - Optional WalletConnect project ID\n * @param initialUiKitConfig - Optional initial UI kit configuration\n * @returns A configured WagmiWalletImplementation instance\n */\nexport function createEvmWalletImplementation(\n walletConnectProjectId?: string,\n initialUiKitConfig?: UiKitConfiguration\n): CoreWagmiWalletImplementation {\n const config: WagmiWalletConfig = {\n chains: defaultSupportedChains,\n networkConfigs: evmNetworks,\n walletConnectProjectId,\n initialUiKitConfig,\n logSystem: 'WagmiWalletImplementation',\n };\n\n const instance = new CoreWagmiWalletImplementation(config);\n\n // Inject the RainbowKit config function\n instance.setRainbowKitConfigFn(\n async (uiKitConfiguration, chains, chainIdToNetworkIdMap, getRpcOverride) => {\n return getWagmiConfigForRainbowKit(\n uiKitConfiguration,\n chains as WagmiConfigChains,\n chainIdToNetworkIdMap,\n getRpcOverride\n );\n }\n );\n\n return instance;\n}\n","/**\n * EVM UI Kit Manager\n *\n * Manages UI kit configuration for EVM networks using the shared factory from adapter-evm-core.\n */\n\nimport {\n createUiKitManager,\n ensureRainbowKitAssetsLoaded,\n type UiKitManagerState,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport { getEvmWalletImplementation } from './utils/walletImplementationManager';\n\n/**\n * State interface for EVM UI Kit Manager.\n * This is a type alias to the shared UiKitManagerState for backwards compatibility.\n */\nexport type EvmUiKitManagerState = UiKitManagerState;\n\n/**\n * EVM UI Kit Manager instance.\n * Provides state management for UI kit configuration in EVM adapters.\n */\nexport const evmUiKitManager = createUiKitManager({\n getWalletImplementation: getEvmWalletImplementation,\n loadRainbowKitAssets: ensureRainbowKitAssetsLoaded,\n logPrefix: 'EvmUiKitManager',\n});\n","import {\n useAccount,\n useBalance,\n useChainId,\n useChains,\n useConnect,\n useDisconnect,\n useSendTransaction,\n useSignMessage,\n useSignTypedData,\n useSwitchChain,\n useWaitForTransactionReceipt,\n type UseAccountReturnType,\n type UseBalanceReturnType,\n type UseChainIdReturnType,\n type UseChainsReturnType,\n type UseConnectReturnType,\n type UseDisconnectReturnType,\n type UseSendTransactionReturnType,\n type UseSignMessageReturnType,\n type UseSignTypedDataReturnType,\n type UseSwitchChainReturnType,\n type UseWaitForTransactionReceiptReturnType,\n} from 'wagmi';\n\nimport type { EcosystemSpecificReactHooks } from '@openzeppelin/ui-types';\n\n/**\n * Direct export of wagmi hooks as our facade hooks\n * Using the EcosystemSpecificReactHooks interface which now accepts any function signatures\n */\nexport const evmFacadeHooks: EcosystemSpecificReactHooks = {\n useAccount,\n useConnect,\n useDisconnect,\n useSwitchChain,\n useChainId,\n useChains,\n useBalance,\n useSendTransaction,\n useWaitForTransactionReceipt,\n useSignMessage,\n useSignTypedData,\n};\n\n// Re-export the wagmi hook types for convenience when consuming these hooks\nexport type {\n UseAccountReturnType,\n UseBalanceReturnType,\n UseChainIdReturnType,\n UseChainsReturnType,\n UseConnectReturnType,\n UseDisconnectReturnType,\n UseSendTransactionReturnType,\n UseSignMessageReturnType,\n UseSignTypedDataReturnType,\n UseSwitchChainReturnType,\n UseWaitForTransactionReceiptReturnType,\n};\n","import type { UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { appConfigService, logger } from '@openzeppelin/ui-utils';\n\n/**\n * Default configuration when no specific configuration is provided\n */\nconst defaultConfig: UiKitConfiguration = {\n kitName: 'custom', // Default to using our custom implementation for EVM\n kitConfig: {\n showInjectedConnector: false, // Default to hiding the injected connector\n },\n};\n\n// Singleton instance of the UI kit configuration\nlet uiKitConfig: UiKitConfiguration = { ...defaultConfig };\n\nexport function loadInitialConfigFromAppService(): UiKitConfiguration {\n logger.debug('useUiKitConfig', 'Attempting to load initial config from AppConfigService...');\n const configObj = appConfigService.getWalletUIConfig<UiKitConfiguration>('evm');\n\n if (configObj && configObj.kitName) {\n logger.info(\n 'useUiKitConfig',\n `Loaded initial config from AppConfigService: kitName=${configObj.kitName}`,\n configObj.kitConfig\n );\n // Merge with defaults to ensure all base keys are present if AppConfigService only provides partial config\n return {\n kitName: configObj.kitName,\n kitConfig: { ...defaultConfig.kitConfig, ...(configObj.kitConfig || {}) },\n };\n }\n logger.debug(\n 'useUiKitConfig',\n 'No initial config found in AppConfigService, using module default.'\n );\n return { ...defaultConfig };\n}\n\n/**\n * Updates the UI kit configuration\n * @param config The new configuration to set. This should be the fully resolved\n * config from the adapter, potentially including user-native settings.\n */\nexport function setUiKitConfig(config: UiKitConfiguration): void {\n uiKitConfig = { ...config }; // Store a copy of the provided config\n logger.info(\n 'useUiKitConfig:setUiKitConfig',\n `Global uiKitConfig was SET to: kitName=${uiKitConfig.kitName}`,\n `kitConfig: ${JSON.stringify(uiKitConfig.kitConfig)}`\n );\n}\n\n/**\n * Helper to check if a specific config option is enabled\n * @param key The configuration key to check\n * @returns True if the configuration option is enabled, false otherwise\n */\nexport function isConfigEnabled(key: string): boolean {\n return Boolean(uiKitConfig.kitConfig?.[key]);\n}\n\n/**\n * Hook to access the UI kit configuration.\n * The configuration is typically loaded at module initialization and when `setUiKitConfig` is called.\n * @returns The current UI kit configuration (module-level singleton).\n */\nexport function useUiKitConfig(): UiKitConfiguration {\n // The module-level `uiKitConfig` is updated by `loadInitialConfigFromAppService` (called at module load)\n // and `setUiKitConfig` (called by adapter's configureUiKit).\n // Thus, this hook can simply return the current state of the module-level singleton.\n return uiKitConfig;\n}\n\n/**\n * Getter function to access the current module-level UI kit configuration directly.\n * Useful for initializing adapter instance configurations.\n * @returns The current module-level UI kit configuration.\n */\nexport function getUiKitConfig(): UiKitConfiguration {\n // Return the direct reference to the singleton. Setters should ensure immutability if needed elsewhere.\n // For this flow, setUiKitConfig is the explicit mutator.\n return uiKitConfig;\n}\n","import type { ExecutionMethodDetail } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Returns details for execution methods supported by the EVM adapter.\n */\nexport async function getEvmSupportedExecutionMethods(): Promise<ExecutionMethodDetail[]> {\n logger.warn(\n 'adapter-evm-execution-config',\n 'getEvmSupportedExecutionMethods is using placeholder implementation.'\n );\n // TODO: Implement actual supported methods for EVM (e.g., EOA, Safe).\n return Promise.resolve([\n {\n type: 'eoa',\n name: 'EOA (External Account)',\n description: 'Execute using a standard wallet address.',\n },\n {\n type: 'relayer',\n name: 'OpenZeppelin Relayer',\n description: 'Execute via a OpenZeppelin open source transaction relayer service.',\n disabled: false,\n },\n {\n type: 'multisig',\n name: 'Safe Multisig', // Example for future\n description: 'Execute via a Safe multisignature wallet.',\n disabled: true,\n },\n ]);\n}\n","// Import from core package via barrel files\nimport {\n EvmProviderKeys,\n resolveExplorerApiKeyFromAppConfig,\n type TypedEvmNetworkConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EvmNetworkConfig, NetworkServiceForm } from '@openzeppelin/ui-types';\nimport { appConfigService, userNetworkServiceConfigService } from '@openzeppelin/ui-utils';\n\n/**\n * Returns the default service configuration values for a given service ID.\n * Used for proactive health checks when no user overrides are configured.\n *\n * @param networkConfig The network configuration\n * @param serviceId The service identifier (e.g., 'rpc', 'explorer', 'contract-definitions', 'access-control-indexer')\n * @returns The default configuration values, or null if not available\n */\nexport function getEvmDefaultServiceConfig(\n networkConfig: EvmNetworkConfig,\n serviceId: string\n): Record<string, unknown> | null {\n switch (serviceId) {\n case 'rpc':\n if (networkConfig.rpcUrl) {\n return { rpcUrl: networkConfig.rpcUrl };\n }\n break;\n case 'explorer': {\n // For explorer service, we need to include the API key if available\n // Use the shared helper from adapter-evm-core to resolve the API key\n const typedConfig = networkConfig as TypedEvmNetworkConfig;\n const apiKey = resolveExplorerApiKeyFromAppConfig(typedConfig);\n\n // Return config if we have at least an explorer URL or an API key\n if (networkConfig.explorerUrl || apiKey) {\n return {\n explorerUrl: networkConfig.explorerUrl,\n apiUrl: networkConfig.apiUrl,\n ...(apiKey ? { apiKey } : {}),\n };\n }\n break;\n }\n case 'access-control-indexer': {\n // Access control indexer is optional — return default URL from network config if available\n const typedNetworkConfig = networkConfig as TypedEvmNetworkConfig;\n if (typedNetworkConfig.accessControlIndexerUrl) {\n return { accessControlIndexerUrl: typedNetworkConfig.accessControlIndexerUrl };\n }\n return null;\n }\n case 'contract-definitions':\n // No connection test for contract definitions service\n return null;\n }\n return null;\n}\n\n/**\n * Returns the network service forms for EVM networks.\n * Defines the UI configuration for RPC, Explorer, and Contract Definitions services.\n */\nexport function getEvmNetworkServiceForms(\n networkConfig: TypedEvmNetworkConfig\n): NetworkServiceForm[] {\n const globalV2ApiKey = appConfigService.getGlobalServiceConfig('etherscanv2')?.apiKey as\n | string\n | undefined;\n const v2DefaultEnabled = Boolean(globalV2ApiKey);\n // Read any saved contract-definitions config to seed defaults in the UI\n const savedContractDefCfg = userNetworkServiceConfigService.get(\n networkConfig.id,\n 'contract-definitions'\n ) as Record<string, unknown> | null;\n const savedDefaultProvider =\n savedContractDefCfg && typeof savedContractDefCfg.defaultProvider === 'string'\n ? (savedContractDefCfg.defaultProvider as string)\n : undefined;\n return [\n {\n id: 'rpc',\n label: 'RPC Provider',\n description:\n 'Setting your own RPC endpoint ensures better reliability, faster response times, and higher rate limits. Public endpoints may be rate-limited or experience congestion during high traffic periods.',\n fields: [\n {\n id: 'evm-rpc-url',\n name: 'rpcUrl',\n type: 'text',\n label: 'RPC URL',\n placeholder: 'https://mainnet.infura.io/v3/your-key',\n validation: { required: true, pattern: '^https?://.+' },\n width: 'full',\n },\n ],\n },\n {\n id: 'explorer',\n label: 'Block Explorer',\n description:\n 'Public API keys are rate-limited and may be exhausted quickly. Using your own key ensures reliable access to explorer services.',\n fields: [\n // Adapter-led informational notes (rendered generically by the panel)\n {\n id: 'evm-explorer-note-etherscan',\n name: '_note_etherscan',\n type: 'hidden',\n label: '',\n validation: {},\n isHidden: true,\n metadata: {\n note: {\n variant: 'warning',\n title: 'Etherscan API Support',\n html: true,\n lines: [\n '<strong>V2 API (Recommended):</strong> Supports all Etherscan-compatible explorers across multiple chains with a single API key.',\n '<strong>V1 API (Legacy):</strong> Requires chain-specific API endpoints. Some explorers may not be supported.',\n '<strong>Note:</strong> Non-Etherscan explorers (Blockscout, Routescan, etc.) are not supported.',\n ],\n },\n },\n },\n {\n id: 'evm-explorer-api-key',\n name: 'apiKey',\n type: 'password',\n label: 'API Key',\n placeholder: 'Your explorer API key',\n helperText: 'Required for fetching contract ABIs and other API operations',\n validation: {},\n width: 'full',\n },\n {\n id: 'evm-explorer-use-v2',\n name: 'useV2Api',\n type: 'checkbox',\n label: 'Use Etherscan V2 API',\n helperText:\n 'Enable the new V2 API for all Etherscan-compatible networks. V2 provides unified access across all chains.',\n validation: {},\n defaultValue: v2DefaultEnabled,\n metadata: {\n section: 'api-config',\n sectionLabel: 'API Configuration',\n sectionHelp: 'Configure API version and network application settings.',\n },\n },\n {\n id: 'evm-explorer-apply-all',\n name: 'applyToAllNetworks',\n type: 'checkbox',\n label: 'Apply to all compatible networks',\n helperText: 'Apply these settings to all Etherscan-compatible networks in your project.',\n validation: {},\n defaultValue: v2DefaultEnabled,\n // UI hinting for generic renderer to indent under and disable when V2 is off\n metadata: {\n section: 'api-config',\n nestUnder: 'useV2Api',\n disabledWhen: { field: 'useV2Api', equals: false },\n },\n },\n {\n id: 'evm-explorer-url',\n name: 'explorerUrl',\n type: 'text',\n label: 'Explorer Base URL (optional)',\n placeholder: 'https://etherscan.io',\n validation: {},\n helperText:\n 'Base URL for viewing transactions and addresses. If not provided, defaults from the network will be used.',\n width: 'full',\n metadata: {\n section: 'custom-endpoints',\n sectionLabel: 'Custom Endpoints',\n sectionHelp: 'Override default URLs for explorer and API endpoints.',\n },\n },\n {\n id: 'evm-explorer-api-url',\n name: 'apiUrl',\n type: 'text',\n label: 'Explorer API URL (legacy / V1)',\n placeholder: 'https://api.etherscan.io/api',\n validation: {},\n helperText:\n 'API endpoint for fetching contract data. If not provided, defaults from the network will be used.',\n width: 'full',\n metadata: { section: 'custom-endpoints' },\n },\n ],\n },\n {\n id: 'access-control-indexer',\n label: 'Access Control Indexer',\n description:\n 'Optional GraphQL indexer endpoint for historical access control data. Overrides the default indexer URL for this network.',\n supportsConnectionTest: true,\n requiredFeature: 'access_control_indexer',\n fields: [\n {\n id: 'evm-access-control-indexer-url',\n name: 'accessControlIndexerUrl',\n type: 'text',\n label: 'Access Control Indexer GraphQL Endpoint',\n placeholder: 'https://gateway.subquery.network/query/...',\n validation: { required: false, pattern: '^https?://.+' },\n width: 'full',\n helperText:\n 'Optional. Used for querying historical access control events and role discovery on non-enumerable contracts.',\n },\n ],\n },\n {\n id: 'contract-definitions',\n label: 'Contract Definitions',\n description: undefined,\n supportsConnectionTest: false,\n fields: [\n // Informational note\n {\n id: 'evm-contract-def-note',\n name: '_note_contract_def',\n type: 'hidden',\n label: '',\n validation: {},\n isHidden: true,\n metadata: {\n hideTestConnection: true,\n note: {\n variant: 'info',\n title: 'Contract Definition Provider',\n lines: [\n 'Select which provider the builder should try first when loading verified contract definitions. Deep links can override this preference temporarily.',\n ],\n },\n },\n },\n // Default provider select\n {\n id: 'evm-contract-def-provider',\n name: 'defaultProvider',\n type: 'select',\n label: 'Default Contract Definition Provider',\n placeholder: 'Select a provider',\n helperText: 'Used as the first provider to query for contract definitions.',\n validation: {},\n options: [\n { label: 'Etherscan', value: EvmProviderKeys.Etherscan },\n { label: 'Sourcify', value: EvmProviderKeys.Sourcify },\n ],\n // Seed from saved user config or app-config default if present; otherwise empty\n defaultValue:\n savedDefaultProvider ||\n (appConfigService.getGlobalServiceParam('contractdefinition', 'defaultProvider') as\n | string\n | undefined) ||\n '',\n width: 'full',\n },\n // Apply to all networks\n {\n id: 'evm-contract-def-apply-all',\n name: 'applyToAllNetworks',\n type: 'checkbox',\n label: 'Apply to all compatible networks',\n helperText:\n 'Apply this default provider setting to all compatible networks in your project.',\n validation: {},\n defaultValue: false,\n metadata: {\n nestUnder: 'defaultProvider',\n disabledWhen: { field: 'defaultProvider', equals: '' },\n },\n },\n ],\n },\n ];\n}\n","/**\n * Adapter-specific query wrapper\n *\n * Wraps the core queryEvmViewFunction with adapter-specific functionality:\n * - Resolves RPC URL from network config (with user override support)\n * - Supports loading contract schema for proxy implementations\n */\nimport {\n queryEvmViewFunction as coreQueryEvmViewFunction,\n resolveRpcUrl,\n type TypedEvmNetworkConfig,\n type WagmiWalletImplementation,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { ContractSchema } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\n/**\n * Query a view function on an EVM contract.\n *\n * This adapter-specific version wraps the core queryEvmViewFunction to:\n * 1. Resolve the RPC URL from network config (supporting user overrides)\n * 2. Support optional wallet implementation for RPC context\n * 3. Support loading proxy implementation schemas via callback\n *\n * @param contractAddress The contract address to query\n * @param functionId The function ID to call\n * @param networkConfig The network configuration\n * @param params The parameters for the function call\n * @param contractSchema Optional contract schema (if not provided, will use loadContractCallback)\n * @param _walletImplementation Optional wallet implementation (reserved for future use)\n * @param loadContractCallback Optional callback to load contract schema when not provided\n * @returns The result of the view function call\n */\nexport async function queryEvmViewFunction(\n contractAddress: string,\n functionId: string,\n networkConfig: TypedEvmNetworkConfig,\n params: unknown[] = [],\n contractSchema?: ContractSchema,\n _walletImplementation?: WagmiWalletImplementation,\n loadContractCallback?: (address: string) => Promise<ContractSchema>\n): Promise<unknown> {\n // Use provided schema or fall back to loading via callback\n let schema = contractSchema;\n if (!schema) {\n if (loadContractCallback) {\n logger.debug('adapter-query', `Loading contract schema for ${contractAddress} via callback`);\n schema = await loadContractCallback(contractAddress);\n } else {\n throw new Error(\n 'Contract schema is required for view function query. ' +\n 'Provide either a contractSchema or a loadContractCallback.'\n );\n }\n }\n\n // Resolve RPC URL from network config (supports user overrides)\n // Note: resolveRpcUrl throws if no valid URL can be resolved\n const rpcUrl = resolveRpcUrl(networkConfig);\n\n logger.debug('adapter-query', `Using RPC URL for query: ${rpcUrl}`);\n\n // Call core function with resolved RPC URL\n return coreQueryEvmViewFunction(\n contractAddress,\n functionId,\n params,\n schema,\n rpcUrl,\n networkConfig\n );\n}\n","import React from 'react';\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@openzeppelin/ui-components';\n\nimport { AdvancedInfo } from './AdvancedInfo';\nimport { CustomGasParameters } from './CustomGasParameters';\nimport { SpeedSelection } from './SpeedSelection';\nimport { useEvmRelayerOptions } from './useEvmRelayerOptions';\n\n/**\n * EVM-specific relayer transaction options component.\n *\n * Provides configuration for gas pricing strategies:\n * - Speed presets: Use predefined gas pricing levels (OpenZeppelin Relayer API)\n * - Custom: Manual gas parameter configuration for precise control\n *\n * We default to Speed mode with FAST preset to ensure valid API requests.\n * The OpenZeppelin Relayer API requires exactly one pricing strategy to be provided.\n */\nexport const EvmRelayerOptions: React.FC<{\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n}> = ({ options, onChange }) => {\n const [showAdvancedInfo, setShowAdvancedInfo] = React.useState(false);\n\n const {\n control,\n formValues,\n configMode,\n gasType,\n handleSpeedChange,\n handleModeChange,\n handleGasTypeSwitch,\n } = useEvmRelayerOptions({ options, onChange });\n\n return (\n <div className=\"space-y-4\">\n <AdvancedInfo\n showAdvancedInfo={showAdvancedInfo}\n onToggle={() => setShowAdvancedInfo(!showAdvancedInfo)}\n />\n\n <Tabs value={configMode} onValueChange={handleModeChange}>\n <TabsList className=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"speed\">Speed</TabsTrigger>\n <TabsTrigger value=\"custom\">Custom</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"speed\" className=\"space-y-4\">\n <SpeedSelection selectedSpeed={formValues.speed} onSpeedChange={handleSpeedChange} />\n </TabsContent>\n\n <TabsContent value=\"custom\" className=\"space-y-4\">\n <CustomGasParameters\n control={control}\n configMode={configMode}\n gasType={gasType}\n showGasLimit={formValues.showGasLimit || false}\n onGasTypeSwitch={handleGasTypeSwitch}\n />\n </TabsContent>\n </Tabs>\n </div>\n );\n};\n","import { Info } from 'lucide-react';\nimport React from 'react';\n\nimport { Button } from '@openzeppelin/ui-components';\n\ninterface AdvancedInfoProps {\n showAdvancedInfo: boolean;\n onToggle: () => void;\n}\n\nexport const AdvancedInfo: React.FC<AdvancedInfoProps> = ({ showAdvancedInfo, onToggle }) => {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <label className=\"text-base font-medium\">Gas Pricing Strategy</label>\n <Button variant=\"ghost\" size=\"sm\" onClick={onToggle} className=\"text-xs\" type=\"button\">\n <Info className=\"h-3 w-3 mr-1\" />\n API Requirements\n </Button>\n </div>\n\n {showAdvancedInfo && (\n <div className=\"mt-3 rounded-lg bg-muted/30 p-4\">\n <p className=\"text-sm text-muted-foreground leading-relaxed\">\n The OpenZeppelin Relayer API requires exactly one pricing strategy: either a{' '}\n <strong>Speed</strong> enum value (FASTEST, FAST, AVERAGE, SAFE_LOW) or{' '}\n <strong>custom gas parameters</strong> (gasPrice for legacy, or maxFeePerGas +\n maxPriorityFeePerGas for EIP-1559).\n </p>\n </div>\n )}\n </div>\n );\n};\n","import { Circle } from 'lucide-react';\nimport React from 'react';\nimport { Control } from 'react-hook-form';\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n BooleanField,\n NumberField,\n} from '@openzeppelin/ui-components';\nimport { cn } from '@openzeppelin/ui-utils';\n\nimport { EvmRelayerFormData } from './useEvmRelayerOptions';\n\ninterface CustomGasParametersProps {\n control: Control<EvmRelayerFormData>;\n configMode: string;\n gasType: string;\n showGasLimit: boolean;\n onGasTypeSwitch: (type: string) => void;\n}\n\nexport const CustomGasParameters: React.FC<CustomGasParametersProps> = ({\n control,\n configMode,\n gasType,\n showGasLimit,\n onGasTypeSwitch,\n}) => {\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-lg bg-muted/50 p-4\">\n <p className=\"text-sm text-muted-foreground leading-relaxed\">\n Manually configure gas parameters. You must provide either <strong>Legacy</strong>{' '}\n (gasPrice) or <strong>EIP-1559</strong> (maxFeePerGas + maxPriorityFeePerGas) values.\n </p>\n </div>\n\n <div className=\"space-y-3\">\n <p className=\"text-xs text-muted-foreground font-medium uppercase tracking-wider\">\n Select Gas Pricing Method\n </p>\n\n <Accordion\n type=\"single\"\n collapsible\n value={gasType}\n onValueChange={(value) => value && onGasTypeSwitch(value)}\n className=\"w-full space-y-3\"\n >\n <AccordionItem\n value=\"eip1559\"\n className={cn(\n 'rounded-lg border shadow-sm overflow-hidden transition-all',\n gasType === 'eip1559'\n ? 'border-primary bg-primary/5'\n : 'border-border bg-card hover:border-muted-foreground/50'\n )}\n >\n <AccordionTrigger className=\"px-4 py-3 text-sm font-medium hover:no-underline\">\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Circle\n className={`h-4 w-4 ${gasType === 'eip1559' ? 'text-primary' : 'text-muted-foreground'}`}\n />\n {gasType === 'eip1559' && (\n <Circle className=\"h-4 w-4 absolute inset-0 text-primary fill-primary scale-50\" />\n )}\n </div>\n <span>EIP-1559</span>\n </div>\n {gasType === 'eip1559' && (\n <span className=\"text-xs text-primary font-medium mr-2\">Selected</span>\n )}\n </div>\n </AccordionTrigger>\n <AccordionContent>\n <div className=\"px-4 pb-4 pt-4 grid gap-4 border-t bg-background/50\">\n <NumberField\n id=\"maxFeePerGas\"\n label=\"Max Fee Per Gas\"\n name=\"transactionOptions.maxFeePerGas\"\n control={control}\n placeholder=\"30\"\n helperText=\"Maximum total fee per gas unit you're willing to pay (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'eip1559' }}\n />\n\n <NumberField\n id=\"maxPriorityFeePerGas\"\n label=\"Max Priority Fee Per Gas\"\n name=\"transactionOptions.maxPriorityFeePerGas\"\n control={control}\n placeholder=\"2\"\n helperText=\"Priority fee (tip) to incentivize miners (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'eip1559' }}\n />\n </div>\n </AccordionContent>\n </AccordionItem>\n\n <AccordionItem\n value=\"legacy\"\n className={cn(\n 'rounded-lg border shadow-sm overflow-hidden transition-all',\n gasType === 'legacy'\n ? 'border-primary bg-primary/5'\n : 'border-border bg-card hover:border-muted-foreground/50'\n )}\n >\n <AccordionTrigger className=\"px-4 py-3 text-sm font-medium hover:no-underline\">\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <Circle\n className={`h-4 w-4 ${gasType === 'legacy' ? 'text-primary' : 'text-muted-foreground'}`}\n />\n {gasType === 'legacy' && (\n <Circle className=\"h-4 w-4 absolute inset-0 text-primary fill-primary scale-50\" />\n )}\n </div>\n <span>Legacy Gas Price</span>\n </div>\n {gasType === 'legacy' && (\n <span className=\"text-xs text-primary font-medium mr-2\">Selected</span>\n )}\n </div>\n </AccordionTrigger>\n <AccordionContent>\n <div className=\"px-4 pb-4 pt-4 border-t bg-background/50\">\n <NumberField\n id=\"gasPrice\"\n label=\"Gas Price\"\n name=\"transactionOptions.gasPrice\"\n control={control}\n placeholder=\"20\"\n helperText=\"Fixed gas price for legacy transactions (in gwei)\"\n step={0.1}\n min={0}\n validation={{ required: configMode === 'custom' && gasType === 'legacy' }}\n />\n </div>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n </div>\n\n <div className=\"space-y-2\">\n <BooleanField\n id=\"showGasLimit\"\n label=\"Override gas limit\"\n name=\"transactionOptions.showGasLimit\"\n control={control}\n helperText=\"Enable manual gas limit configuration\"\n />\n\n {showGasLimit && (\n <div className=\"pl-6\">\n <NumberField\n id=\"gasLimit\"\n label=\"Gas Limit\"\n name=\"transactionOptions.gasLimit\"\n control={control}\n placeholder=\"Auto-detected by relayer\"\n helperText=\"Leave empty to let the relayer estimate. Only override if you need a specific limit.\"\n step={1000}\n min={21000}\n />\n </div>\n )}\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nimport { Speed } from '@openzeppelin/relayer-sdk';\nimport { RadioGroup, RadioGroupItem } from '@openzeppelin/ui-components';\n\ninterface SpeedSelectionProps {\n selectedSpeed: Speed | undefined;\n onSpeedChange: (speed: Speed) => void;\n}\n\nconst speedOptions = [\n {\n value: Speed.FASTEST,\n label: 'Fastest',\n description: 'Maximum priority, highest gas prices',\n },\n {\n value: Speed.FAST,\n label: 'Fast',\n description: 'High priority, recommended for most transactions',\n recommended: true,\n },\n {\n value: Speed.AVERAGE,\n label: 'Average',\n description: 'Standard priority, balanced cost',\n },\n {\n value: Speed.SAFE_LOW,\n label: 'Safe Low',\n description: 'Lower priority, minimal gas cost',\n },\n];\n\nexport const SpeedSelection: React.FC<SpeedSelectionProps> = ({ selectedSpeed, onSpeedChange }) => {\n return (\n <RadioGroup\n value={selectedSpeed || Speed.FAST}\n onValueChange={(value) => onSpeedChange(value as Speed)}\n >\n <div className=\"space-y-3\">\n {speedOptions.map((option) => (\n <label\n key={option.value}\n htmlFor={`speed-${option.value}`}\n className={`relative block rounded-lg border p-4 cursor-pointer transition-colors ${\n selectedSpeed === option.value\n ? 'border-primary bg-primary/5'\n : 'border-border hover:border-muted-foreground/50'\n }`}\n >\n {option.recommended && (\n <span className=\"absolute -top-2 right-4 bg-primary text-primary-foreground text-xs px-2 py-0.5 rounded\">\n Recommended\n </span>\n )}\n <div className=\"flex items-start space-x-3\">\n <RadioGroupItem\n value={option.value}\n id={`speed-${option.value}`}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1\">\n <div className=\"font-medium\">{option.label}</div>\n <p className=\"text-sm text-muted-foreground mt-0.5\">{option.description}</p>\n </div>\n </div>\n </label>\n ))}\n </div>\n </RadioGroup>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { Speed } from '@openzeppelin/relayer-sdk';\nimport {\n gweiToWei,\n weiToGwei,\n type EvmRelayerTransactionOptions,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\n\nexport interface EvmRelayerFormData {\n transactionOptions: EvmRelayerTransactionOptions & {\n showGasLimit?: boolean;\n };\n}\n\ninterface UseEvmRelayerOptionsProps {\n options: Record<string, unknown>;\n onChange: (options: Record<string, unknown>) => void;\n}\n\nexport const useEvmRelayerOptions = ({ options, onChange }: UseEvmRelayerOptionsProps) => {\n // Store latest onChange in a ref to avoid effect re-runs due to changing function identity\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n // Initialize form with options from parent (only on mount to prevent loops)\n const initialOptions = {\n speed: (() => {\n const hasCustomSettings = Boolean(\n options.gasPrice || options.maxFeePerGas || options.maxPriorityFeePerGas\n );\n return options.speed || (!hasCustomSettings ? Speed.FAST : undefined);\n })() as Speed,\n gasPrice: weiToGwei(options.gasPrice as number | undefined),\n maxFeePerGas: weiToGwei(options.maxFeePerGas as number | undefined),\n maxPriorityFeePerGas: weiToGwei(options.maxPriorityFeePerGas as number | undefined),\n gasLimit: options.gasLimit as number | undefined,\n showGasLimit: Boolean(options.gasLimit),\n };\n\n const { control, setValue, watch } = useForm<EvmRelayerFormData>({\n defaultValues: {\n transactionOptions: initialOptions,\n },\n });\n\n const formValues = watch('transactionOptions');\n const isInitialMount = useRef(true);\n\n // Determine current mode and gas type\n const hasCustomSettings = Boolean(\n formValues.gasPrice || formValues.maxFeePerGas || formValues.maxPriorityFeePerGas\n );\n const configMode = hasCustomSettings ? 'custom' : 'speed';\n const isEip1559 = Boolean(formValues.maxFeePerGas || formValues.maxPriorityFeePerGas);\n const gasType = isEip1559 ? 'eip1559' : 'legacy';\n\n // Handle initial mount - ensure the default speed value is communicated to parent\n useEffect(() => {\n if (isInitialMount.current) {\n isInitialMount.current = false;\n\n // Only notify parent if we have a default speed value that wasn't already in options\n if (initialOptions.speed && !options.speed) {\n const newOptions: EvmRelayerTransactionOptions = {};\n if (initialOptions.speed) newOptions.speed = initialOptions.speed;\n if (initialOptions.gasLimit) newOptions.gasLimit = initialOptions.gasLimit;\n\n onChange(newOptions as Record<string, unknown>);\n }\n return;\n }\n }, []);\n\n // Notify parent of changes after initial mount (watch specific fields to avoid loops)\n useEffect(() => {\n if (isInitialMount.current) {\n return;\n }\n\n const timeoutId = setTimeout(() => {\n const newOptions: EvmRelayerTransactionOptions = {};\n\n if (formValues.speed) newOptions.speed = formValues.speed;\n if (formValues.gasPrice) newOptions.gasPrice = gweiToWei(formValues.gasPrice);\n if (formValues.maxFeePerGas) newOptions.maxFeePerGas = gweiToWei(formValues.maxFeePerGas);\n if (formValues.maxPriorityFeePerGas) {\n newOptions.maxPriorityFeePerGas = gweiToWei(formValues.maxPriorityFeePerGas);\n }\n if (formValues.gasLimit) newOptions.gasLimit = formValues.gasLimit;\n\n onChangeRef.current(newOptions as Record<string, unknown>);\n }, 100);\n\n return () => clearTimeout(timeoutId);\n }, [\n formValues.speed,\n formValues.gasPrice,\n formValues.maxFeePerGas,\n formValues.maxPriorityFeePerGas,\n formValues.gasLimit,\n ]);\n\n // Event handlers\n const handleSpeedChange = (speed: Speed) => {\n setValue('transactionOptions', {\n ...formValues,\n speed,\n gasPrice: undefined,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n });\n };\n\n const handleModeChange = (mode: string) => {\n if (mode === 'speed') {\n setValue('transactionOptions', {\n ...formValues,\n speed: Speed.FAST,\n gasPrice: undefined,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n });\n } else {\n setValue('transactionOptions', {\n ...formValues,\n speed: undefined,\n maxFeePerGas: 30,\n maxPriorityFeePerGas: 2,\n });\n }\n };\n\n const handleGasTypeSwitch = (type: string) => {\n if (type === 'eip1559') {\n setValue('transactionOptions', {\n ...formValues,\n gasPrice: undefined,\n maxFeePerGas: 30,\n maxPriorityFeePerGas: 2,\n });\n } else {\n setValue('transactionOptions', {\n ...formValues,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n gasPrice: 20,\n });\n }\n };\n\n return {\n control,\n formValues,\n configMode,\n gasType,\n handleSpeedChange,\n handleModeChange,\n handleGasTypeSwitch,\n };\n};\n","import type { GetAccountReturnType } from '@wagmi/core';\n\nimport {\n connectAndEnsureCorrectNetworkCore,\n DEFAULT_DISCONNECTED_STATUS,\n type EvmWalletConnectionResult,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { Connector } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport {\n getEvmWalletImplementation,\n getInitializedEvmWalletImplementation,\n} from './walletImplementationManager';\n\nconst LOG_SYSTEM = 'adapter-evm-connection';\n\n/**\n * Indicates if this adapter implementation supports wallet connection.\n */\nexport function evmSupportsWalletConnection(): boolean {\n // For now, assume EVM always supports wallet connection if wagmi can be initialized.\n // This might depend on walletConnectProjectId being available for WalletConnect to be viable.\n return true;\n}\n\n/**\n * Gets the list of available wallet connectors supported by this adapter's implementation.\n */\nexport async function getEvmAvailableConnectors(): Promise<Connector[]> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.warn(LOG_SYSTEM, 'getEvmAvailableConnectors: Wallet implementation not ready.');\n return [];\n }\n return impl.getAvailableConnectors();\n}\n\n/**\n * Initiates the wallet connection process for a specific connector and ensures the network is correct.\n *\n * @param connectorId - The ID of the connector to use.\n * @param targetChainId - The desired chain ID to switch to after connection.\n * @returns An object containing connection status, address, and any error.\n */\nexport async function connectAndEnsureCorrectNetwork(\n connectorId: string,\n targetChainId: number\n): Promise<EvmWalletConnectionResult> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.error(LOG_SYSTEM, 'connectAndEnsureCorrectNetwork: Wallet implementation not ready.');\n return { connected: false, error: 'Wallet system not initialized.' };\n }\n\n return connectAndEnsureCorrectNetworkCore(impl, connectorId, targetChainId, LOG_SYSTEM);\n}\n\n/**\n * Disconnects the currently connected EVM wallet.\n */\nexport async function disconnectEvmWallet(): Promise<{\n disconnected: boolean;\n error?: string;\n}> {\n const impl = await getEvmWalletImplementation();\n if (!impl) {\n logger.warn(LOG_SYSTEM, 'disconnectEvmWallet: Wallet implementation not ready.');\n return { disconnected: false, error: 'Wallet system not initialized.' };\n }\n return impl.disconnect();\n}\n\n/**\n * Gets the current wallet connection status.\n * This function might need to become async if getEvmWalletImplementation is async\n * and the status depends on an initialized instance.\n * For now, assuming getWalletConnectionStatus on the impl is synchronous after init.\n */\nexport function getEvmWalletConnectionStatus(): GetAccountReturnType {\n const impl = getInitializedEvmWalletImplementation();\n if (!impl) {\n logger.warn(\n LOG_SYSTEM,\n 'getEvmWalletConnectionStatus: Wallet implementation not ready. Returning default disconnected state.'\n );\n return DEFAULT_DISCONNECTED_STATUS;\n }\n return impl.getWalletConnectionStatus();\n}\n\n/**\n * Subscribes to wallet connection changes.\n */\nexport function onEvmWalletConnectionChange(\n callback: (account: GetAccountReturnType, prevAccount: GetAccountReturnType) => void\n): () => void {\n // Return type is now synchronous () => void\n const walletImplementation = getInitializedEvmWalletImplementation(); // Use sync getter\n if (!walletImplementation) {\n logger.warn(\n 'onEvmWalletConnectionChange',\n 'Wallet implementation not initialized. Cannot subscribe to changes. Returning no-op.'\n );\n return () => {}; // Return a no-op unsubscribe function\n }\n return walletImplementation.onWalletConnectionChange(callback);\n}\n","import {\n CustomAccountDisplay,\n CustomConnectButton,\n CustomNetworkSwitcher,\n filterWalletComponents,\n getComponentExclusionsFromConfig,\n} from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\nimport { logger } from '@openzeppelin/ui-utils';\n\nimport { createRainbowKitComponents, validateRainbowKitConfig } from '../rainbowkit';\n\n/** Service for resolving UI kit specific components and providers for the EVM adapter. */\n\n/**\n * Determines the final set of wallet components to be provided by the adapter\n * based on the UI kit configuration and any specified exclusions.\n *\n * @param uiKitConfiguration - The UiKitConfiguration from the adapter instance.\n * @returns The EcosystemWalletComponents object or undefined.\n */\nexport function getResolvedWalletComponents(\n uiKitConfiguration: UiKitConfiguration\n): EcosystemWalletComponents | undefined {\n logger.debug(\n 'uiKitService:getResolvedWalletComponents',\n 'Received uiKitConfiguration:',\n JSON.stringify(uiKitConfiguration)\n );\n\n const currentKitName = uiKitConfiguration.kitName || 'custom';\n\n if (currentKitName === 'none') {\n logger.info(\n 'uiKitService',\n 'UI Kit set to \"none\" for getResolvedWalletComponents, not providing wallet components.'\n );\n return undefined;\n }\n\n const exclusions = getComponentExclusionsFromConfig(uiKitConfiguration.kitConfig);\n logger.debug(\n 'uiKitService',\n `Extracted component exclusions for ${currentKitName}: ${exclusions.join(', ') || 'none'}.`\n );\n\n // TODO: If many more UI kits are added, this conditional logic could be refactored\n // using a map or strategy pattern to resolve components based on kitName.\n // For example: const componentFactory = this.kitComponentFactories[currentKitName];\n // if (componentFactory) { return filterWalletComponents(componentFactory(), exclusions, currentKitName); }\n if (currentKitName === 'custom') {\n const allCustomComponents: EcosystemWalletComponents = {\n ConnectButton: CustomConnectButton,\n AccountDisplay: CustomAccountDisplay,\n NetworkSwitcher: CustomNetworkSwitcher,\n };\n return filterWalletComponents(allCustomComponents, exclusions, currentKitName);\n }\n\n if (currentKitName === 'rainbowkit') {\n const validation = validateRainbowKitConfig(uiKitConfiguration.kitConfig);\n\n if (!validation.isValid) {\n logger.warn(\n 'uiKitService',\n `Invalid RainbowKit configuration for components: ${validation.error}. No components provided.`\n );\n return undefined; // Fail fast for components if config is invalid for RainbowKit\n }\n\n // Get RainbowKit components and apply any exclusions\n const rainbowKitComponents = createRainbowKitComponents();\n logger.info('uiKitService', 'Providing RainbowKit components.');\n return filterWalletComponents(rainbowKitComponents, exclusions, currentKitName);\n }\n // if (currentKitName === 'connectkit') { /* return ConnectKit components */ }\n // if (currentKitName === 'appkit') { /* return AppKit components */ }\n logger.warn(\n 'uiKitService',\n `UI Kit \"${currentKitName}\" for getResolvedWalletComponents not explicitly supported. No components provided.`\n );\n return undefined;\n}\n","/**\n * EVM Adapter RainbowKit Components\n *\n * This file exports only React components to support Fast Refresh.\n * Factory functions are in componentFactory.ts.\n */\nimport { createRainbowKitConnectButton } from '@openzeppelin/ui-builder-adapter-evm-core';\nimport type { BaseComponentProps } from '@openzeppelin/ui-types';\n\nimport { evmUiKitManager } from '../evmUiKitManager';\n\n/**\n * Props for the RainbowKitConnectButton component.\n */\nexport type RainbowKitConnectButtonProps = BaseComponentProps;\n\n/**\n * RainbowKitConnectButton component configured with the EVM UI kit manager.\n * This component lazily loads the RainbowKit ConnectButton and manages\n * its state through the evmUiKitManager.\n */\nexport const RainbowKitConnectButton: React.FC<RainbowKitConnectButtonProps> =\n createRainbowKitConnectButton(evmUiKitManager);\n","/**\n * EVM Adapter RainbowKit Component Factory\n *\n * Factory function for creating RainbowKit components.\n * Separated from components.tsx to support React Fast Refresh.\n */\nimport { createRainbowKitComponents as coreCreateRainbowKitComponents } from '@openzeppelin/ui-builder-adapter-evm-core';\n\nimport { RainbowKitConnectButton } from './components';\n\n/**\n * Creates the complete set of RainbowKit wallet components for the EVM adapter.\n *\n * @returns An object containing all RainbowKit wallet components\n */\nexport function createRainbowKitComponents() {\n return coreCreateRainbowKitComponents(RainbowKitConnectButton);\n}\n","import type { GetAccountReturnType } from '@wagmi/core';\n\nimport type { EvmWalletConnectionStatus } from '../types';\n\n/**\n * Converts wagmi's GetAccountReturnType to our enhanced EvmWalletConnectionStatus.\n * This utility preserves all the rich UX capabilities from wagmi while ensuring\n * compatibility with our adapter interface.\n *\n * @param wagmiStatus - The status object from wagmi's GetAccountReturnType\n * @returns Enhanced EvmWalletConnectionStatus with all wagmi properties\n */\nexport function convertWagmiToEvmStatus(\n wagmiStatus: GetAccountReturnType\n): EvmWalletConnectionStatus {\n return {\n isConnected: wagmiStatus.isConnected,\n isConnecting: wagmiStatus.isConnecting,\n isDisconnected: wagmiStatus.isDisconnected,\n isReconnecting: wagmiStatus.isReconnecting,\n status: wagmiStatus.status,\n address: wagmiStatus.address,\n chainId: wagmiStatus.chainId?.toString(),\n addresses: wagmiStatus.addresses,\n connector: wagmiStatus.connector\n ? {\n id: wagmiStatus.connector.id,\n name: wagmiStatus.connector.name,\n type: wagmiStatus.connector.type,\n }\n : undefined,\n chain: wagmiStatus.chain ? { ...wagmiStatus.chain } : undefined,\n };\n}\n","import type { EcosystemWalletComponents, UiKitConfiguration } from '@openzeppelin/ui-types';\n\n// Import the actual service functions instead of using placeholders\nimport { getResolvedWalletComponents as getWalletComponentsFromService } from './utils/uiKitService';\n\n// Function to get wallet components based on UiKitConfiguration\nexport function getResolvedWalletComponents(\n uiKitConfig: UiKitConfiguration\n): EcosystemWalletComponents | undefined {\n return getWalletComponentsFromService(uiKitConfig);\n}\n","/**\n * Configuration for the EVM adapter\n *\n * This file defines the dependencies required by the EVM adapter\n * when generating exported projects. It follows the AdapterConfig\n * interface to provide a structured approach to dependency management.\n */\nimport type { AdapterConfig } from '@openzeppelin/ui-types';\n\nexport const evmAdapterConfig: AdapterConfig = {\n /**\n * Dependencies required by the EVM adapter\n * These will be included in exported projects that use this adapter\n */\n dependencies: {\n // Runtime dependencies\n runtime: {\n // Core EVM libraries\n // Wallet connection libraries\n wagmi: '^2.15.0',\n '@wagmi/core': '^2.20.3',\n viem: '^2.28.0',\n '@tanstack/react-query': '^5.0.0',\n // Utility library\n // lodash: '^4.17.21',\n },\n\n // Development dependencies\n dev: {\n // '@types/lodash': '^4.17.16',\n '@types/lodash': '^4.17.5',\n },\n },\n overrides: {\n 'use-sync-external-store': '^1.2.0',\n valtio: '^1.13.2',\n },\n uiKits: {\n rainbowkit: {\n dependencies: {\n runtime: {\n '@rainbow-me/rainbowkit': '^2.2.8',\n },\n },\n overrides: {\n '@paulmillr/qr': 'npm:qr@^0.5.0',\n '@walletconnect/modal': '^2.7.1',\n },\n },\n },\n};\n","import { NetworkEthereum } from '@web3icons/react';\n\nimport type { EcosystemMetadata } from '@openzeppelin/ui-types';\n\nexport const ecosystemMetadata: EcosystemMetadata = {\n id: 'evm',\n name: 'Ethereum (EVM)',\n description:\n 'Ethereum is a decentralized, open-source blockchain with smart contract functionality. It supports the Ethereum Virtual Machine (EVM) and uses the native cryptocurrency Ether (ETH).',\n explorerGuidance: 'Etherscan verified contracts',\n addressExample: '0x...',\n iconComponent: NetworkEthereum,\n bgColorClass: 'bg-blue-100',\n textColorClass: 'text-blue-900',\n defaultFeatureConfig: { enabled: true, showInUI: true },\n};\n"],"mappings":"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","names":["import_viem","import_ui_utils","import_lodash","import_react","import_ui_components","import_ui_react","import_jsx_runtime","import_lucide_react","import_core","import_ui_types","init_artifacts","__export","logger","__export","SYSTEM_LOG_TAG","init_eoa","logger","module","userNetworkServiceConfigService","appConfigService","createPublicClient","http","isAddress","validateAndConvertEvmArtifacts","simpleHash","logger","SYSTEM_LOG_TAG","EoaExecutionStrategy","RelayerExecutionStrategy","jsx","connect","useState","useEffect","jsxs","Button","useDerivedAccountStatus","useDerivedConnectStatus","disconnect","cn","switchChain","Loader2","LOG_SYSTEM","userNetworkServiceConfigService","isValidUrl","__publicField","appConfigService","http","defaultConfig","uiKitConfig","getWagmiWalletClient","getWagmiCorePublicClient","useState","useContext","useEffect","logger","getWalletButtonSizeProps","jsxs","Button","cn","jsx","Loader2","RainbowKitConnectButton","http","LOG_PREFIX","module","SYSTEM_LOG_TAG","logger","LOG_SYSTEM","__publicField","logger","LOG_SYSTEM","logger","__publicField","OperationFailed","ConfigurationInvalid","import_ui_utils","import_core","import_chains","import_react","import_ui_utils","import_ui_utils","import_react","viemMainnet","viemArbitrum","viemPolygon","viemPolygonZkEvm","viemBase","viemBsc","viemOptimism","viemAvalanche","viemZkSync","viemScroll","viemLinea","import_react","import_chains","viemSepolia","viemArbitrumSepolia","viemPolygonAmoy","viemPolygonZkEvmCardona","viemBaseSepolia","viemBscTestnet","viemOptimismSepolia","viemAvalancheFuji","viemZkSyncSepoliaTestnet","viemScrollSepolia","viemLineaSepolia","viemMonadTestnet","getSupportedChainsFromNetworks","LOG_SYSTEM","import_jsx_runtime","import_wagmi","import_ui_utils","import_ui_utils","import_ui_utils","import_ui_utils","queryEvmViewFunction","import_react","import_ui_components","import_lucide_react","import_ui_components","import_jsx_runtime","import_lucide_react","import_ui_components","import_ui_utils","import_jsx_runtime","import_relayer_sdk","import_ui_components","import_jsx_runtime","import_react","import_relayer_sdk","hasCustomSettings","import_jsx_runtime","React","import_ui_utils","LOG_SYSTEM","import_ui_utils","createRainbowKitComponents","createRainbowKitComponents","getResolvedWalletComponents","uiKitConfig","queryEvmViewFunction","getResolvedWalletComponents","uiKitConfig","import_react"]}