@coti-io/coti-wallet-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +76 -0
- package/dist/index.d.mts +4740 -0
- package/dist/index.d.ts +4740 -0
- package/dist/index.js +12720 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12564 -0
- package/dist/index.mjs.map +1 -0
- package/docs/npm-publish-checklist.md +47 -0
- package/package.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chains/coti.ts","../src/chains/podInbox.ts","../src/chains/sepolia.ts","../src/chains/avalancheFuji.ts","../src/chains/viemChains.ts","../src/chains/rpcUrls.ts","../src/chains/index.ts","../src/config/plugin.ts","../src/lib/logger.ts","../src/contracts/pod.ts","../src/chains/portal/podSdkConfig.ts","../src/chains/portal/fees.ts","../src/chains/portal/podPortalFees.ts","../src/index.ts","../src/errors.ts","../src/pod/podPortalRequestsStorage.ts","../src/chains/cotiBridgeGasEstimate.ts","../src/hooks/useEstimateBridgeFees.ts","../src/contracts/config.ts","../src/contracts/abis.ts","../src/chains/coti-bridge/fees.ts","../src/chains/portal/helpers.ts","../src/chains/portal/podRequestStatus.ts","../src/chains/portal/podRequestTrackingDiagnostics.ts","../src/chains/portal/executePodPortalTransaction.ts","../src/chains/portal/podPTokenBlockingDiagnostics.ts","../src/chains/podPriceOracle.ts","../src/chains/portal/podPortalAdminData.ts","../src/contracts/limits.ts","../src/hooks/useMetamask.ts","../src/lib/ethereum.ts","../src/lib/format.ts","../src/lib/chainMute.ts","../src/lib/metaMaskMobile.ts","../src/hooks/usePrivateTokenBalance.ts","../src/crypto/decryption.ts","../src/types/ciphertext.ts","../src/crypto/aesKey.ts","../src/lib/rpcProvider.ts","../src/hooks/useBalanceUpdater.ts","../src/lib/utils.ts","../src/crypto/aesKeyValidation.ts","../src/hooks/useBridgeData.ts","../src/hooks/useBridgeFees.ts","../src/config/chains.ts","../src/hooks/useBridgeStatus.ts","../src/hooks/privacyBridge/tokens.ts","../src/hooks/privacyBridge/executePrivateTokenTransfer.ts","../src/hooks/privacyBridge/encryptValue256.ts","../src/hooks/privacyBridge/utils.ts","../src/hooks/privacyBridge/usePrivacyBridgeAllowance.ts","../src/hooks/useSnap.ts","../src/hooks/privacyBridge/usePrivacyBridgeExecutor.ts","../src/hooks/privacyBridge/usePrivacyBridgeGas.ts","../src/hooks/privacyBridge/useCotiBridgeFees.ts","../src/hooks/privacyBridge/usePodPortalFees.ts","../src/hooks/useNetworkEnforcer.ts","../src/hooks/useWalletType.ts","../src/context/privacyBridge/PrivacyBridgeProvider.tsx","../src/hooks/usePrivacyBridge.ts","../src/context/privacyBridge/usePrivacyBridgeModalsState.ts","../src/utils/walletErrors.ts","../src/context/privacyBridge/usePrivacyBridgeSession.ts","../src/context/privacyBridge/usePrivacyBridgeSessionCore.ts","../src/hooks/useAesKeyProvider.ts","../src/crypto/aesKeyBackupVault.ts","../src/lib/snapOrigins.ts","../src/lib/aesAccessStrategy.ts","../src/lib/onboardingServices.ts","../src/lib/persistEncryptedAesBackup.ts","../src/lib/walletErrors.ts","../src/context/privacyBridge/usePrivacyBridgeSessionKey.ts","../src/context/privacyBridge/usePrivacyBridgeNetworkSession.ts","../src/context/privacyBridge/usePrivacyBridgeAccountSync.ts","../src/context/privacyBridge/usePrivacyBridgeWagmiSync.ts","../src/context/privacyBridge/usePrivacyBridgeWalletConnection.ts","../node_modules/@wagmi/core/src/actions/disconnect.ts","../node_modules/@wagmi/core/src/exports/index.ts","../src/lib/wagmiDisconnect.ts","../src/context/privacyBridge/usePrivacyBridgeUnlockSession.ts","../src/hooks/privacyBridge/privateValueCrypto.ts","../src/context/privacyBridge/usePrivacyBridgePodState.ts","../src/context/privacyBridge/contexts.tsx","../src/context/privacyBridge/types.ts","../src/context/privateUnlock/PrivateUnlockProvider.tsx","../src/context/privateUnlock/usePrivateUnlockController.tsx","../src/components/OnboardModal.tsx","../src/lib/walletDisplayName.ts","../src/lib/onboardingProgressDisplay.ts","../src/components/onboard/deriveOnboardScreen.ts","../src/components/WalletSignPrompt.tsx","../src/providers/WagmiRainbowKitProvider.tsx","../src/config/walletConnect.ts","../src/providers/eip6963MetaMaskWallet.ts","../src/providers/injectedTarget.ts","../src/providers/mobileMetaMaskWallet.ts","../src/providers/mobileRabbyWallet.ts","../src/providers/mobileOneKeyWallet.ts","../src/providers/mobileZerionWallet.ts","../src/components/NetworkGuard.tsx"],"sourcesContent":["import type { ChainConfig, TokenConfig } from \"./types\";\n\nexport const COTI_TESTNET_CHAIN_ID = 7082400;\nexport const COTI_MAINNET_CHAIN_ID = 2632500;\n\nconst cotiTokenConfigs = (supportedChainIds: number[]): TokenConfig[] => [\n { symbol: \"COTI\", name: \"COTI\", icon: \"/icons/coti.svg\", decimals: 18, isPrivate: false, bridgeAddressKey: \"PrivacyBridgeCotiNative\", timeout: 1800, supportedChainIds },\n { symbol: \"WETH\", name: \"Wrapped Ether\", icon: \"/icons/wETH.svg\", decimals: 18, isPrivate: false, addressKey: \"WETH\", bridgeAddressKey: \"PrivacyBridgeWETH\", timeout: 1800, supportedChainIds },\n { symbol: \"WBTC\", name: \"Wrapped BTC\", icon: \"/icons/wBTC.svg\", decimals: 8, isPrivate: false, addressKey: \"WBTC\", bridgeAddressKey: \"PrivacyBridgeWBTC\", timeout: 1800, supportedChainIds },\n { symbol: \"USDT\", name: \"Tether USD\", icon: \"/icons/usdt.svg\", decimals: 6, isPrivate: false, addressKey: \"USDT\", bridgeAddressKey: \"PrivacyBridgeUSDT\", timeout: 1800, supportedChainIds },\n { symbol: \"USDC.e\", name: \"Bridged USDC\", icon: \"/icons/USDC.svg\", decimals: 6, isPrivate: false, addressKey: \"USDC_E\", bridgeAddressKey: \"PrivacyBridgeUSDCe\", timeout: 1800, supportedChainIds },\n { symbol: \"WADA\", name: \"Wrapped ADA\", icon: \"/icons/wADA.svg\", decimals: 6, isPrivate: false, addressKey: \"WADA\", bridgeAddressKey: \"PrivacyBridgeWADA\", timeout: 1800, supportedChainIds },\n { symbol: \"gCOTI\", name: \"gCOTI\", icon: \"/icons/gcoti.svg\", decimals: 18, isPrivate: false, addressKey: \"gCOTI\", bridgeAddressKey: \"PrivacyBridgegCOTI\", timeout: 1800, supportedChainIds },\n { symbol: \"NIGHT\", name: \"NIGHT\", icon: \"https://coti.io/icons/midnight.png\", decimals: 6, isPrivate: false, addressKey: \"NIGHT\", bridgeAddressKey: \"PrivacyBridgeNight\", timeout: 1800, supportedChainIds },\n { symbol: \"p.COTI\", name: \"p.COTI\", icon: \"/icons/coti.svg\", decimals: 18, isPrivate: true, addressKey: \"PrivateCoti\", bridgeAddressKey: \"PrivacyBridgeCotiNative\", timeout: 1800, supportedChainIds },\n { symbol: \"p.WETH\", name: \"p.WETH\", icon: \"/icons/wETH.svg\", decimals: 18, isPrivate: true, addressKey: \"p.WETH\", bridgeAddressKey: \"PrivacyBridgeWETH\", timeout: 1800, supportedChainIds },\n { symbol: \"p.WBTC\", name: \"p.WBTC\", icon: \"/icons/wBTC.svg\", decimals: 8, isPrivate: true, addressKey: \"p.WBTC\", bridgeAddressKey: \"PrivacyBridgeWBTC\", timeout: 1800, supportedChainIds },\n { symbol: \"p.USDT\", name: \"p.USDT\", icon: \"/icons/usdt.svg\", decimals: 6, isPrivate: true, addressKey: \"p.USDT\", bridgeAddressKey: \"PrivacyBridgeUSDT\", timeout: 1800, supportedChainIds },\n { symbol: \"p.USDC.e\", name: \"p.USDC.e\", icon: \"/icons/USDC.svg\", decimals: 6, isPrivate: true, addressKey: \"p.USDC_E\", bridgeAddressKey: \"PrivacyBridgeUSDCe\", timeout: 1800, supportedChainIds },\n { symbol: \"p.WADA\", name: \"p.WADA\", icon: \"/icons/wADA.svg\", decimals: 6, isPrivate: true, addressKey: \"p.WADA\", bridgeAddressKey: \"PrivacyBridgeWADA\", timeout: 1800, supportedChainIds },\n { symbol: \"p.gCOTI\", name: \"p.gCOTI\", icon: \"/icons/gcoti.svg\", decimals: 18, isPrivate: true, addressKey: \"p.gCOTI\", bridgeAddressKey: \"PrivacyBridgegCOTI\", timeout: 1800, supportedChainIds },\n { symbol: \"p.NIGHT\", name: \"p.NIGHT\", icon: \"https://coti.io/icons/midnight.png\", decimals: 6, isPrivate: true, addressKey: \"p.NIGHT\", bridgeAddressKey: \"PrivacyBridgeNight\", timeout: 1800, supportedChainIds },\n];\n\nexport const cotiTestnetChain: ChainConfig = {\n id: COTI_TESTNET_CHAIN_ID,\n hexId: \"0x6c11a0\",\n name: \"COTI Testnet\",\n rpcUrl: \"https://testnet.coti.io/rpc\",\n explorerBaseUrl: \"https://testnet.cotiscan.io\",\n unlockStrategy: \"snap\",\n portalStrategy: \"coti-bridge\",\n addresses: {\n PrivateCoti: \"0x6cE8907414986E73De9e7D28d62Ea2080F8E88E1\",\n PrivacyBridgeCotiNative: \"0x96117882328407B13A5f378de25764C4eD8477eA\",\n CotiPriceConsumer: \"0xD5EeD24e909AdE249b688671e32dcc013B236B74\",\n WETH: \"0x8bca4e6bbE402DB4aD189A316137aD08206154FB\",\n WBTC: \"0x5dBDb2E5D51c3FFab5D6B862Caa11FCe1D83F492\",\n USDT: \"0x9e961430053cd5AbB3b060544cEcCec848693Cf0\",\n USDC_E: \"0x63f3D2Cc8F5608F57ce6E5Aa3590A2Beb428D19C\",\n WADA: \"0xe3E2cd3Abf412c73a404b9b8227B71dE3CfE829D\",\n gCOTI: \"0x878a42D3cB737DEC9E6c7e7774d973F46fd8ed4C\",\n NIGHT: \"0x918084eee42832f08b868Ea64Bba2d41A5F360c6\",\n PrivacyBridgeNight: \"0x025b0E54ae5fac3BF3ca6eDe7bd62fa684c25D29\",\n \"p.WETH\": \"0xF009BADb181d471995a1CFF406C3Db7B180F64eA\",\n \"p.WBTC\": \"0xB50F1680a4C69145ABc09A2A71c8D5b8051578cF\",\n \"p.USDT\": \"0xcEF137E96eDF68EE99D4CdEa7085f154d74895cD\",\n \"p.USDC_E\": \"0x37f78dcCd15876F74391EF1F01b76557D9FF1dea\",\n \"p.WADA\": \"0x1245f50a3E9129A219b4bf66D10fEaEA47467B69\",\n \"p.gCOTI\": \"0x1503b02a4Aa27812306c65116FD23b733603F142\",\n \"p.NIGHT\": \"0xfb3A2F7ca2416e7BE312feA60a647f880B840957\",\n PrivacyBridgeWETH: \"0x6f1628D7F1D5d5aDF39b924a28acb10B5C9df283\",\n PrivacyBridgeWBTC: \"0x9EBEbC8F5Cff021459a56A681719dF1C0A7435cc\",\n PrivacyBridgeUSDT: \"0x549634daBE8237EBda7473d7aA2bB17459826781\",\n PrivacyBridgeUSDCe: \"0xaa63D41890D576F93d79272988e212d8B46CdD26\",\n PrivacyBridgeWADA: \"0x4AFe67D4aD7AF0a70ACe6f79FbfAB66C72211c9F\",\n PrivacyBridgegCOTI: \"0xDB54B4B1B8F9614567bd673A17a5cD31A3DD6033\",\n },\n tokens: cotiTokenConfigs([COTI_TESTNET_CHAIN_ID, COTI_MAINNET_CHAIN_ID]),\n walletNetwork: {\n chainId: \"0x6c11a0\",\n chainName: \"COTI Testnet\",\n rpcUrls: [\"https://testnet.coti.io/rpc\"],\n nativeCurrency: { name: \"COTI\", symbol: \"COTI\", decimals: 18 },\n blockExplorerUrls: [\"https://testnet.cotiscan.io\"],\n },\n indexPage: {\n showPodRequestTracker: false,\n amountModalGasLabel: \"Estimated Gas Fee\",\n amountModalGasSymbol: \"COTI\",\n },\n};\n\nexport const cotiMainnetChain: ChainConfig = {\n id: COTI_MAINNET_CHAIN_ID,\n hexId: \"0x282b34\",\n name: \"COTI Mainnet\",\n rpcUrl: \"https://mainnet.coti.io/rpc\",\n explorerBaseUrl: \"https://mainnet.cotiscan.io\",\n unlockStrategy: \"snap\",\n portalStrategy: \"coti-bridge\",\n addresses: {\n PrivateCoti: \"\",\n PrivacyBridgeCotiNative: \"\",\n CotiPriceConsumer: \"0x830c5112E677459648C1aa7Bc5Dd65A36d71Aa4D\",\n WETH: \"0x639aCc80569c5FC83c6FBf2319A6Cc38bBfe26d1\",\n WBTC: \"0x8C39B1fD0e6260fdf20652Fc436d25026832bfEA\",\n USDT: \"0xfA6f73446b17A97a56e464256DA54AD43c2Cbc3E\",\n USDC_E: \"0xf1Feebc4376c68B7003450ae66343Ae59AB37D3C\",\n WADA: \"0xe757Ca19d2c237AA52eBb1d2E8E4368eeA3eb331\",\n gCOTI: \"0x7637C7838EC4Ec6b85080F28A678F8E234bB83D1\",\n NIGHT: \"\",\n PrivacyBridgeNight: \"\",\n \"p.WETH\": \"\",\n \"p.WBTC\": \"\",\n \"p.USDT\": \"\",\n \"p.USDC_E\": \"\",\n \"p.WADA\": \"\",\n \"p.gCOTI\": \"\",\n \"p.NIGHT\": \"\",\n PrivacyBridgeWETH: \"\",\n PrivacyBridgeWBTC: \"\",\n PrivacyBridgeUSDT: \"\",\n PrivacyBridgeUSDCe: \"\",\n PrivacyBridgeWADA: \"\",\n PrivacyBridgegCOTI: \"\",\n },\n tokens: cotiTokenConfigs([COTI_TESTNET_CHAIN_ID, COTI_MAINNET_CHAIN_ID]),\n walletNetwork: {\n chainId: \"0x282b34\",\n chainName: \"COTI Mainnet\",\n rpcUrls: [\"https://mainnet.coti.io/rpc\"],\n nativeCurrency: { name: \"COTI\", symbol: \"COTI\", decimals: 18 },\n blockExplorerUrls: [\"https://mainnet.cotiscan.io\"],\n },\n indexPage: {\n showPodRequestTracker: false,\n amountModalGasLabel: \"Estimated Gas Fee\",\n amountModalGasSymbol: \"COTI\",\n },\n};\n","/**\n * PoD inbox contract — same deployment on Sepolia, Avalanche Fuji, and COTI testnet.\n * Single source of truth for {@link getPodSdkConfig}, {@link getPodInboxAddress}, and\n * {@link PodContract} fee estimation via `@coti-io/pod-sdk`.\n */\nexport const POD_INBOX_ADDRESS = \"0xAb625bE229F603f6BBF964474AFf6d5487e364De\";\n\n/**\n * Default callback payload size (bytes) for inbox `estimateFee` when a chain config\n * omits `callBackDataSize`. Must be set together with `callBackGasLimit` per SDK rules.\n */\nexport const POD_DEFAULT_CALLBACK_DATA_SIZE = 1024n;\n\n/** @deprecated Use {@link POD_INBOX_ADDRESS}. */\nexport const POD_TESTNET_INBOX_ADDRESS = POD_INBOX_ADDRESS;\n\n/** @deprecated Use {@link POD_INBOX_ADDRESS}. */\nexport const COTI_TESTNET_POD_INBOX = POD_INBOX_ADDRESS;\n","import type { ChainConfig } from \"./types\";\n\nexport const SEPOLIA_CHAIN_ID = 11155111;\n\nconst SEPOLIA_RPC_URL =\n \"https://sepolia.infura.io/v3/ed65559ebd384beabfee7a97c266d6bf\";\nconst SEPOLIA_RPC_FALLBACK_URL = \"https://ethereum-sepolia-rpc.publicnode.com\";\n\n/** Underlying ERC-20s from PrivacyPortalConfig.json (Sepolia). */\nconst WETH = \"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9\";\nconst USDC = \"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238\";\nconst MTT = \"0xd3f5c63f4D87D2235b295FbA83351d31d0eD1BeE\";\n\n/** Deployed PoD portal pairs from pod-mpc-lib deployConfig.json (Sepolia). */\nconst P_ETH = \"0x28f6CFc45c3D4C13E6BAB034cb05278Db496b9d6\";\nconst P_USDC = \"0xc727D2Ab43bF0d4cab75FD5C046BA38899ca988a\";\nconst PORTAL_ETH = \"0xa4efc209144565126c034dfD23208f040748923f\";\nconst PORTAL_USDC = \"0xDc0b0e5681C17A8449Baf5aBB130d7664Bb56d5a\";\n\nexport const sepoliaChain: ChainConfig = {\n id: SEPOLIA_CHAIN_ID,\n hexId: \"0xaa36a7\",\n name: \"Sepolia\",\n rpcUrl: SEPOLIA_RPC_URL,\n rpcFallbackUrls: [SEPOLIA_RPC_FALLBACK_URL],\n explorerBaseUrl: \"https://eth-sepolia.blockscout.com\",\n unlockStrategy: \"manual-aes-key\",\n portalStrategy: \"pod-privacy-portal\",\n podFeeEstimation: {\n deposit: { forwardGasLimit: 850_000n, callBackGasLimit: 2_000_000n },\n withdraw: { forwardGasLimit: 900_000n, callBackGasLimit: 2_000_000n },\n },\n priceOracleAddress: \"0x7eecdceec31d285aee99c7960b405f63593903d1\",\n addresses: {\n MTT,\n WETH,\n USDC,\n \"p.MTT\": \"0x46f9f46971f6bEc21Fe5d42909Ef99D1D2af43c4\",\n \"p.USDC\": P_USDC,\n \"p.ETH\": P_ETH,\n PrivacyPortalMTT: \"0xaCD7fE838354Dd72147d9c387558477D7d4D6514\",\n PrivacyPortalUSDC: PORTAL_USDC,\n PrivacyPortalETH: PORTAL_ETH,\n },\n tokens: [\n {\n symbol: \"MTT\",\n name: \"MyTestToken\",\n icon: \"/icons/coti.svg\",\n decimals: 18,\n isPrivate: false,\n addressKey: \"MTT\",\n bridgeAddressKey: \"PrivacyPortalMTT\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n {\n symbol: \"p.MTT\",\n name: \"Private MyTestToken\",\n icon: \"/icons/coti.svg\",\n decimals: 18,\n isPrivate: true,\n addressKey: \"p.MTT\",\n bridgeAddressKey: \"PrivacyPortalMTT\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n {\n symbol: \"USDC\",\n name: \"USD Coin\",\n icon: \"/icons/USDC.svg\",\n decimals: 6,\n isPrivate: false,\n addressKey: \"USDC\",\n bridgeAddressKey: \"PrivacyPortalUSDC\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n {\n symbol: \"p.USDC\",\n name: \"Private USDC\",\n icon: \"/icons/USDC.svg\",\n decimals: 6,\n isPrivate: true,\n addressKey: \"p.USDC\",\n bridgeAddressKey: \"PrivacyPortalUSDC\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n {\n symbol: \"ETH\",\n name: \"Ether\",\n icon: \"/icons/wETH.svg\",\n decimals: 18,\n isPrivate: false,\n isNative: true,\n addressKey: \"WETH\",\n bridgeAddressKey: \"PrivacyPortalETH\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n {\n symbol: \"p.ETH\",\n name: \"Private WETH\",\n icon: \"/icons/wETH.svg\",\n decimals: 18,\n isPrivate: true,\n addressKey: \"p.ETH\",\n bridgeAddressKey: \"PrivacyPortalETH\",\n supportedChainIds: [SEPOLIA_CHAIN_ID],\n },\n ],\n walletNetwork: {\n chainId: \"0xaa36a7\",\n chainName: \"Sepolia\",\n rpcUrls: [SEPOLIA_RPC_URL, SEPOLIA_RPC_FALLBACK_URL],\n nativeCurrency: { name: \"Sepolia Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorerUrls: [\"https://eth-sepolia.blockscout.com\"],\n },\n indexPage: {\n showPodRequestTracker: true,\n amountModalGasLabel: \"Estimated Network Gas\",\n amountModalGasSymbol: \"native\",\n },\n};\n","import type { ChainConfig } from \"./types\";\n\nexport const AVALANCHE_FUJI_CHAIN_ID = 43113;\n\nconst AVALANCHE_FUJI_RPC_URL =\n \"https://twilight-small-rain.avalanche-testnet.quiknode.pro/ad1393483c2713058688a4e0fb47a308f29dd52d/ext/bc/C/rpc/\";\nconst AVALANCHE_FUJI_RPC_FALLBACK_URL =\n \"https://avalanche-fuji-c-chain-rpc.publicnode.com\";\n\n/** Underlying ERC-20s from PrivacyPortalConfig.json (Avalanche Fuji). */\nconst MTT = \"0x328e70e1c52662cd5f19f824fcb8b463d77a6686\";\nconst USDC = \"0x5425890298aed601595a70AB815c96711a31Bc65\";\nconst WAVAX = \"0xd00ae08403B9bbb9124bB305C09058E32C39A48c\";\n\n/** Deployed PoD portal pairs from pod-mpc-lib deployConfig.json (Fuji). */\nconst P_AVAX = \"0xe7956aDaC668b563Dc77eD29C5E7A4Ef5edFB3FB\";\nconst P_USDC = \"0x4C8dD09336BB7A219bef9448914a9E4621cE3645\";\nconst PORTAL_AVAX = \"0x25E7a1BddF4b9696F19A726Cb2Ce550467527e90\";\nconst PORTAL_USDC = \"0x956D8994a56F65d2fF1F9b09565857a09374D852\";\n\nexport const avalancheFujiChain: ChainConfig = {\n id: AVALANCHE_FUJI_CHAIN_ID,\n hexId: \"0xa869\",\n name: \"Avalanche Fuji\",\n rpcUrl: AVALANCHE_FUJI_RPC_URL,\n rpcFallbackUrls: [AVALANCHE_FUJI_RPC_FALLBACK_URL],\n explorerBaseUrl: \"https://testnet.snowscan.xyz\",\n priceOracleAddress: \"0xb06340c020274ef5d92f664070966402a4d27712\",\n unlockStrategy: \"manual-aes-key\",\n portalStrategy: \"pod-privacy-portal\",\n podFeeEstimation: {\n deposit: { forwardGasLimit: 850_000n, callBackGasLimit: 2_000_000n },\n withdraw: { forwardGasLimit: 900_000n, callBackGasLimit: 2_000_000n },\n },\n addresses: {\n MTT,\n USDC,\n WAVAX,\n \"p.MTT\": \"0x8F34570CEAD49273D5DA8A0E25e728eCC28af267\",\n \"p.USDC\": P_USDC,\n \"p.AVAX\": P_AVAX,\n PrivacyPortalMTT: \"0x64D99D761aC68D1a495B4f7E5bE7277586EDFE78\",\n PrivacyPortalUSDC: PORTAL_USDC,\n PrivacyPortalAVAX: PORTAL_AVAX,\n },\n tokens: [\n {\n symbol: \"MTT\",\n name: \"MyTestToken\",\n icon: \"/icons/coti.svg\",\n decimals: 18,\n isPrivate: false,\n addressKey: \"MTT\",\n bridgeAddressKey: \"PrivacyPortalMTT\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n {\n symbol: \"p.MTT\",\n name: \"Private MyTestToken\",\n icon: \"/icons/coti.svg\",\n decimals: 18,\n isPrivate: true,\n addressKey: \"p.MTT\",\n bridgeAddressKey: \"PrivacyPortalMTT\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n {\n symbol: \"USDC\",\n name: \"USD Coin\",\n icon: \"/icons/USDC.svg\",\n decimals: 6,\n isPrivate: false,\n addressKey: \"USDC\",\n bridgeAddressKey: \"PrivacyPortalUSDC\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n {\n symbol: \"p.USDC\",\n name: \"Private USDC\",\n icon: \"/icons/USDC.svg\",\n decimals: 6,\n isPrivate: true,\n addressKey: \"p.USDC\",\n bridgeAddressKey: \"PrivacyPortalUSDC\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n {\n symbol: \"AVAX\",\n name: \"Avalanche\",\n icon: \"/icons/avalanche.svg\",\n decimals: 18,\n isPrivate: false,\n isNative: true,\n addressKey: \"WAVAX\",\n bridgeAddressKey: \"PrivacyPortalAVAX\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n {\n symbol: \"p.AVAX\",\n name: \"Private WAVAX\",\n icon: \"/icons/avalanche.svg\",\n decimals: 18,\n isPrivate: true,\n addressKey: \"p.AVAX\",\n bridgeAddressKey: \"PrivacyPortalAVAX\",\n supportedChainIds: [AVALANCHE_FUJI_CHAIN_ID],\n },\n ],\n walletNetwork: {\n chainId: \"0xa869\",\n chainName: \"Avalanche Fuji Testnet\",\n rpcUrls: [AVALANCHE_FUJI_RPC_URL, AVALANCHE_FUJI_RPC_FALLBACK_URL],\n nativeCurrency: { name: \"Avalanche\", symbol: \"AVAX\", decimals: 18 },\n blockExplorerUrls: [\"https://testnet.snowscan.xyz\"],\n },\n indexPage: {\n showPodRequestTracker: true,\n amountModalGasLabel: \"Estimated Network Gas\",\n amountModalGasSymbol: \"native\",\n },\n};\n","import { defineChain, type Chain } from \"viem\";\nimport type { ChainConfig } from \"./types\";\nimport { cotiMainnetChain, cotiTestnetChain } from \"./coti\";\nimport { sepoliaChain } from \"./sepolia\";\nimport { avalancheFujiChain } from \"./avalancheFuji\";\n\nconst REGISTRY_RPC_BY_CHAIN_ID: Record<number, string> = {\n [cotiMainnetChain.id]: cotiMainnetChain.rpcUrl,\n [cotiTestnetChain.id]: cotiTestnetChain.rpcUrl,\n [sepoliaChain.id]: sepoliaChain.rpcUrl,\n [avalancheFujiChain.id]: avalancheFujiChain.rpcUrl,\n};\n\n/** Explorer display name derived from registry URL (avoids duplicating viem metadata). */\nconst explorerNameFromUrl = (url: string): string => {\n if (url.includes(\"etherscan\")) return \"Etherscan\";\n if (url.includes(\"cotiscan\")) return \"CotiScan\";\n return \"Explorer\";\n};\n\n/** Builds a viem {@link Chain} from a {@link CHAIN_CONFIGS} entry. */\nexport const chainConfigToViemChain = (config: ChainConfig): Chain => {\n const httpRpcUrls = config.rpcFallbackUrls?.length\n ? [config.rpcUrl, ...config.rpcFallbackUrls]\n : [config.rpcUrl];\n\n return defineChain({\n id: config.id,\n name: config.name,\n nativeCurrency: { ...config.walletNetwork.nativeCurrency },\n rpcUrls: { default: { http: httpRpcUrls } },\n blockExplorers: {\n default: {\n name: explorerNameFromUrl(config.explorerBaseUrl),\n url: config.explorerBaseUrl,\n },\n },\n });\n};\n\n/** viem chains for wagmi — derived from {@link CHAIN_CONFIGS}. */\nexport const cotiMainnet = chainConfigToViemChain(cotiMainnetChain);\nexport const cotiTestnet = chainConfigToViemChain(cotiTestnetChain);\nexport const sepolia = chainConfigToViemChain(sepoliaChain);\nexport const avalancheFuji = chainConfigToViemChain(avalancheFujiChain);\n\n/** RPC URL constants derived from the registry (single source of truth). */\nexport const COTI_MAINNET_RPC = cotiMainnetChain.rpcUrl;\nexport const COTI_TESTNET_RPC = cotiTestnetChain.rpcUrl;\nexport const SEPOLIA_RPC = sepoliaChain.rpcUrl;\nexport const SEPOLIA_RPC_FALLBACK = sepoliaChain.rpcFallbackUrls?.[0] ?? sepoliaChain.rpcUrl;\nexport const AVALANCHE_FUJI_RPC = avalancheFujiChain.rpcUrl;\nexport const AVALANCHE_FUJI_RPC_FALLBACK =\n avalancheFujiChain.rpcFallbackUrls?.[0] ?? avalancheFujiChain.rpcUrl;\n\n/**\n * Auxiliary Ethereum L1 chain — not in {@link CHAIN_CONFIGS}; legacy RPC helper only.\n */\nexport const ETHEREUM_MAINNET_CHAIN_ID = 1;\nexport const ETHEREUM_MAINNET_RPC = \"https://eth.llamarpc.com\";\nexport const ethereumMainnet = defineChain({\n id: ETHEREUM_MAINNET_CHAIN_ID,\n name: \"Ethereum Mainnet\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: { default: { http: [ETHEREUM_MAINNET_RPC] } },\n blockExplorers: { default: { name: \"Etherscan\", url: \"https://etherscan.io\" } },\n});\n\n/**\n * Resolves an RPC URL for ethers.js callers.\n * Prefer {@link getRpcUrlForChain} for registry chains; handles auxiliary chain id 1.\n */\nexport function getRpcUrlForChainId(chainId?: number): string {\n if (chainId === ETHEREUM_MAINNET_CHAIN_ID) return ETHEREUM_MAINNET_RPC;\n if (chainId != null && chainId in REGISTRY_RPC_BY_CHAIN_ID) {\n return REGISTRY_RPC_BY_CHAIN_ID[chainId];\n }\n return cotiTestnetChain.rpcUrl;\n}\n","import { cotiTestnetChain } from \"./coti\";\nimport type { ChainConfig } from \"./types\";\n\ntype ChainConfigLookup = (chainId?: number | string | null) => ChainConfig | undefined;\n\nlet resolveChainConfig: ChainConfigLookup = () => undefined;\n\n/** Wired from {@link ./index} to avoid a circular import at module load. */\nexport function bindChainConfigLookup(lookup: ChainConfigLookup): void {\n resolveChainConfig = lookup;\n}\n\nexport const getRpcUrlsForChain = (chainId?: number | string | null): string[] => {\n const config = resolveChainConfig(chainId);\n if (!config) return [cotiTestnetChain.rpcUrl];\n return config.rpcFallbackUrls?.length\n ? [config.rpcUrl, ...config.rpcFallbackUrls]\n : [config.rpcUrl];\n};\n","import {\n cotiMainnetChain,\n cotiTestnetChain,\n COTI_MAINNET_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID,\n} from \"./coti\";\nimport { COTI_TESTNET_POD_INBOX, POD_INBOX_ADDRESS } from \"./podInbox\";\nimport { sepoliaChain, SEPOLIA_CHAIN_ID } from \"./sepolia\";\nimport { avalancheFujiChain, AVALANCHE_FUJI_CHAIN_ID } from \"./avalancheFuji\";\nimport type {\n ChainConfig,\n ResolvedIndexPageUi,\n TokenConfig,\n UnlockStrategy,\n WalletNetworkConfig,\n} from \"./types\";\n\nexport type { ChainConfig, ResolvedIndexPageUi, TokenConfig, UnlockStrategy, WalletNetworkConfig };\nexport {\n COTI_MAINNET_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID,\n COTI_TESTNET_POD_INBOX,\n POD_INBOX_ADDRESS,\n SEPOLIA_CHAIN_ID,\n AVALANCHE_FUJI_CHAIN_ID,\n};\n\nexport const CHAIN_CONFIGS: Record<number, ChainConfig> = {\n [sepoliaChain.id]: sepoliaChain,\n [avalancheFujiChain.id]: avalancheFujiChain,\n [cotiTestnetChain.id]: cotiTestnetChain,\n [cotiMainnetChain.id]: cotiMainnetChain,\n};\n\nexport const DEFAULT_CHAIN_ID = COTI_TESTNET_CHAIN_ID;\n\n/** Numeric chain IDs registered in {@link CHAIN_CONFIGS} (COTI + Sepolia PoD, etc.). */\nexport const getSupportedChainIds = (): number[] =>\n Object.keys(CHAIN_CONFIGS).map(id => Number(id));\n\n/** True when the chain has plugin config (bridge/PoD portal, tokens, RPC). */\nexport const isSupportedChain = (chainId: number): boolean =>\n Number.isFinite(chainId) && chainId in CHAIN_CONFIGS;\n\nexport const getChainConfig = (chainId?: number | string | null) => {\n const numericChainId = chainId == null ? undefined : Number(chainId);\n return numericChainId ? CHAIN_CONFIGS[numericChainId] : undefined;\n};\n\nexport const requireChainConfig = (chainId: number | string) => {\n const config = getChainConfig(chainId);\n if (!config) throw new Error(`Unsupported chain ID: ${chainId}`);\n return config;\n};\n\nexport const getContractAddresses = (chainId?: number | string | null) =>\n getChainConfig(chainId)?.addresses;\n\nexport const getTokensForChain = (chainId?: number | string | null) =>\n getChainConfig(chainId)?.tokens ?? [];\n\nexport const getPublicTokensForChain = (chainId?: number | string | null): TokenConfig[] =>\n getTokensForChain(chainId).filter(token => !token.isPrivate);\n\nexport const getPrivateTokensForChain = (chainId?: number | string | null): TokenConfig[] =>\n getTokensForChain(chainId).filter(token => token.isPrivate);\n\nexport const getExplorerBaseUrlForChain = (chainId?: number | string | null) =>\n getChainConfig(chainId)?.explorerBaseUrl ?? cotiTestnetChain.explorerBaseUrl;\n\nexport const getRpcUrlForChain = (chainId?: number | string | null) =>\n getChainConfig(chainId)?.rpcUrl ?? cotiTestnetChain.rpcUrl;\n\nexport const getNetworkNameForChain = (chainId?: number | string | null) =>\n getChainConfig(chainId)?.name ?? \"Wrong Network\";\n\nexport const getUnlockStrategyForChain = (chainId?: number | string | null): UnlockStrategy =>\n getChainConfig(chainId)?.unlockStrategy ?? \"snap\";\n\nexport const getWalletNetworkConfigs = (): Record<string, WalletNetworkConfig> =>\n Object.values(CHAIN_CONFIGS).reduce<Record<string, WalletNetworkConfig>>((acc, config) => {\n acc[config.hexId] = config.walletNetwork;\n return acc;\n }, {});\n\nexport const getWalletNetworkOptions = () =>\n Object.values(CHAIN_CONFIGS).map(config => ({ id: config.hexId, label: config.name }));\n\nexport const getChainIdConstants = () => ({\n COTI_MAINNET_ID: cotiMainnetChain.hexId,\n COTI_TESTNET_ID: cotiTestnetChain.hexId,\n SEPOLIA_ID: sepoliaChain.hexId,\n});\n\nexport const resolveIndexPageUi = (chainId: number): ResolvedIndexPageUi => {\n const cfg = CHAIN_CONFIGS[chainId] ?? CHAIN_CONFIGS[DEFAULT_CHAIN_ID];\n const ip = cfg.indexPage;\n const nativeSymbol = cfg.walletNetwork.nativeCurrency.symbol;\n return {\n showPodRequestTracker: ip.showPodRequestTracker,\n amountModalGasLabel: ip.amountModalGasLabel,\n amountModalGasSymbol: ip.amountModalGasSymbol === \"native\" ? nativeSymbol : \"COTI\",\n };\n};\n\nexport {\n chainConfigToViemChain,\n cotiMainnet,\n cotiTestnet,\n sepolia,\n ethereumMainnet,\n ETHEREUM_MAINNET_CHAIN_ID,\n ETHEREUM_MAINNET_RPC,\n COTI_MAINNET_RPC,\n COTI_TESTNET_RPC,\n SEPOLIA_RPC,\n SEPOLIA_RPC_FALLBACK,\n AVALANCHE_FUJI_RPC_FALLBACK,\n getRpcUrlForChainId,\n} from \"./viemChains\";\nexport { getRpcUrlsForChain } from \"./rpcUrls\";\nimport { bindChainConfigLookup } from \"./rpcUrls\";\n\nbindChainConfigLookup(getChainConfig);\n","import type { BigNumberish } from 'ethers';\nimport { COTI_MAINNET_CHAIN_ID, COTI_TESTNET_CHAIN_ID } from '../chains';\n\nexport type AesKeyChainId = typeof COTI_TESTNET_CHAIN_ID | typeof COTI_MAINNET_CHAIN_ID;\n\nexport interface EncryptedAesBackup {\n version: 1;\n address: string;\n chainId: number;\n signatureKind: 'eip712';\n iv: string;\n ciphertext: string;\n createdAt: string;\n}\n\nexport interface GrantResult {\n txHash?: string;\n amountWei?: string;\n status?: 'submitted' | 'funded' | 'skipped';\n}\n\nexport interface OnboardingServiceRequest {\n address: string;\n chainId: number;\n}\n\nexport interface SaveEncryptedAesBackupRequest extends OnboardingServiceRequest {\n backup: EncryptedAesBackup;\n}\n\nexport interface OnboardingServices {\n /**\n * Disabled: no grant/backup features. Custom: use provided callbacks.\n * Official is reserved for stable COTI-hosted APIs.\n */\n mode?: 'disabled' | 'custom' | 'official';\n grantNativeCoti?: (request: OnboardingServiceRequest) => Promise<GrantResult>;\n fetchEncryptedAesBackup?: (request: OnboardingServiceRequest) => Promise<EncryptedAesBackup | null>;\n saveEncryptedAesBackup?: (request: SaveEncryptedAesBackupRequest) => Promise<void>;\n replaceEncryptedAesBackup?: (request: SaveEncryptedAesBackupRequest) => Promise<void>;\n}\n\n/**\n * Plugin configuration — replaces Vite environment variables.\n * Consumers can override these via `configureCotiPlugin()` before using hooks.\n */\nexport interface CotiPluginConfig {\n /** The Snap ID for the COTI MetaMask Snap. Default: 'npm:@coti-io/coti-snap' */\n snapId: string;\n /**\n * Optional Snap version to request on install (`wallet_requestSnaps`).\n * When unset, MetaMask installs the latest published version.\n */\n snapVersion?: string;\n /**\n * When false, the plugin will not call `wallet_requestSnaps` to install or\n * reconnect the Snap. An already-installed Snap can still be used for AES\n * key retrieval. Default: true.\n */\n snapInstallEnabled?: boolean;\n /** If set, enforces a specific network chain ID (decimal string or hex). */\n defaultNetworkId?: string;\n /** Sepolia RPC URL for PoD portal operations. */\n sepoliaRpcUrl?: string;\n /** COTI testnet RPC URL for PoD SDK tracking. */\n cotiTestnetRpcUrl?: string;\n /** WalletConnect Cloud project ID for RainbowKit / WalletConnect wallets. */\n walletConnectProjectId?: string;\n /**\n * Enables verbose internal logging via the plugin logger.\n * Disabled by default — the library is silent unless a consumer opts in.\n * Even when enabled, secret material (AES keys, ciphertext, signatures) is never logged.\n */\n debug?: boolean;\n /**\n * When true, clears the in-memory session AES key (and Snap cache) on implicit\n * wagmi/RainbowKit disconnect. Default false preserves the key so reconnecting\n * the same wallet can skip Snap re-fetch; use true for stricter shared-browser security.\n */\n clearSessionKeyOnWagmiDisconnect?: boolean;\n /** Optional onboarding service hooks for grant and encrypted AES backup flows. */\n onboardingServices?: OnboardingServices;\n /**\n * COTI chain that owns AES onboarding state for this app/session.\n * Only COTI Testnet and COTI Mainnet can hold AES keys.\n */\n aesKeyChainId?: AesKeyChainId;\n /** Native COTI threshold required before contract onboarding. Defaults to 0. */\n onboardingGrantMinBalanceWei?: BigNumberish;\n /** Polling interval after grant callback. Defaults to 2000ms. */\n onboardingGrantPollIntervalMs?: number;\n /** Max time to wait after grant callback. Defaults to 60000ms. */\n onboardingGrantTimeoutMs?: number;\n /**\n * Additional origins allowed to call wallet_invokeSnap set-aes-key.\n * Use this to whitelist dApp domains that are not the published COTI portals.\n * Each entry must be an exact origin string (e.g. 'https://portal.example.com').\n * The Snap manifest's allowedOrigins must also include these domains — see PL-3.\n */\n additionalSnapAesWriteOrigins?: string[];\n}\n\nlet _config: CotiPluginConfig = {\n snapId: 'npm:@coti-io/coti-snap',\n snapInstallEnabled: true,\n defaultNetworkId: undefined,\n debug: false,\n clearSessionKeyOnWagmiDisconnect: false,\n onboardingServices: { mode: 'disabled' },\n onboardingGrantMinBalanceWei: 0,\n onboardingGrantPollIntervalMs: 2000,\n onboardingGrantTimeoutMs: 60000,\n additionalSnapAesWriteOrigins: [],\n};\n\nexport function isAesKeyChainId(chainId: unknown): chainId is AesKeyChainId {\n return chainId === COTI_TESTNET_CHAIN_ID || chainId === COTI_MAINNET_CHAIN_ID;\n}\n\nexport function assertAesKeyChainId(chainId: unknown): asserts chainId is AesKeyChainId {\n if (chainId === undefined) return;\n if (!isAesKeyChainId(chainId)) {\n throw new Error(\n `Invalid aesKeyChainId: expected ${COTI_TESTNET_CHAIN_ID} or ${COTI_MAINNET_CHAIN_ID}, got ${String(chainId)}`,\n );\n }\n}\n\n/**\n * Configure the COTI Wallet Plugin at initialization time.\n * Call this before rendering any hooks.\n */\nexport function configureCotiPlugin(config: Partial<CotiPluginConfig>): void {\n assertAesKeyChainId(config.aesKeyChainId);\n _config = {\n ..._config,\n ...config,\n onboardingServices: {\n ..._config.onboardingServices,\n ...config.onboardingServices,\n },\n };\n if ('snapInstallEnabled' in config && _config.debug) {\n console.log('[CotiPlugin] snapInstallEnabled:', {\n snapInstallEnabled: config.snapInstallEnabled,\n effective: isSnapInstallEnabled(),\n });\n }\n}\n\n/**\n * Returns the params object for `wallet_requestSnaps`.\n * Omits version when unset so MetaMask installs the latest Snap.\n */\nexport function getSnapRequestParams(\n snapId: string = _config.snapId,\n snapVersion?: string,\n): Record<string, Record<string, never> | { version: string }> {\n const version = (snapVersion ?? _config.snapVersion)?.trim();\n return version ? { [snapId]: { version } } : { [snapId]: {} };\n}\n\n/**\n * Returns the current plugin configuration.\n */\nexport function getPluginConfig(): Readonly<CotiPluginConfig> {\n return _config;\n}\n\n/** Whether `wallet_requestSnaps` install/connect is allowed for this app. */\nexport function isSnapInstallEnabled(): boolean {\n return getPluginConfig().snapInstallEnabled !== false;\n}\n","/**\n * Internal logger for the COTI Wallet Plugin.\n *\n * As a library, this plugin must stay silent by default — it should never write\n * to a consuming application's console unless explicitly opted in. All output is\n * gated behind the `debug` flag in the plugin config (see `configureCotiPlugin`).\n *\n * SECURITY: Never pass secret material (AES keys, plaintext balances, ciphertext,\n * or signatures) to this logger, even at debug level. Log opaque identifiers or\n * lengths instead of raw values.\n */\n\nimport { configureCotiPlugin, getPluginConfig } from '../config/plugin';\n\ntype LogMethod = (...args: unknown[]) => void;\n\nfunction isDebugEnabled(): boolean {\n try {\n return getPluginConfig().debug === true;\n } catch {\n return false;\n }\n}\n\nexport interface Logger {\n log: LogMethod;\n info: LogMethod;\n warn: LogMethod;\n error: LogMethod;\n debug: LogMethod;\n}\n\nexport const logger: Logger = {\n log: (...args) => {\n if (isDebugEnabled()) console.log(...args);\n },\n info: (...args) => {\n if (isDebugEnabled()) console.info(...args);\n },\n warn: (...args) => {\n if (isDebugEnabled()) console.warn(...args);\n },\n error: (...args) => {\n if (isDebugEnabled()) console.error(...args);\n },\n debug: (...args) => {\n if (isDebugEnabled()) console.debug(...args);\n },\n};\n\n/**\n * Convenience toggle for the plugin's verbose logging.\n * Equivalent to `configureCotiPlugin({ debug: enabled })`.\n */\nexport function setDebugLogging(enabled: boolean): void {\n configureCotiPlugin({ debug: enabled });\n}\n","export const SEPOLIA_CHAIN_ID = 11155111;\nexport const COTI_TESTNET_CHAIN_ID = 7082400;\nexport const DEFAULT_POD_EXPLORER_BASE_URL = \"https://coti-pod-explorer.netlify.app\";\n\nexport const buildPodExplorerRequestUrl = (\n requestId: string,\n chainSlug = \"sepolia\",\n baseUrl = DEFAULT_POD_EXPLORER_BASE_URL\n) => {\n const normalizedBaseUrl = baseUrl.replace(/\\/$/, \"\");\n const normalizedRequestId = requestId.replace(/^0x/, \"\");\n return `${normalizedBaseUrl}/#/request/${chainSlug}/${normalizedRequestId}`;\n};\n\nexport type PodBalanceTrustState = \"ready\" | \"pending-request\" | \"callback-error\" | \"unknown\";\n\nexport interface PodBalanceState {\n status: PodBalanceTrustState;\n pending: boolean;\n callbackErrored: boolean;\n message?: string;\n}\n\nexport const DEFAULT_POD_BALANCE_STATE: PodBalanceState = {\n status: \"unknown\",\n pending: false,\n callbackErrored: false,\n};\n\nexport type PodPortalRequestStatus =\n | \"wallet-signing\"\n | \"source-submitted\"\n | \"source-mined\"\n | \"target-mined\"\n | \"callback-generated\"\n | \"pod-pending\"\n | \"callback-errored\"\n | \"succeeded\"\n | \"failed\"\n | \"burn-debt\";\n\nexport interface PodPortalRequest {\n id: string;\n kind: \"deposit\" | \"withdraw\";\n chainId: number;\n sourceTxHash: string;\n requestId?: string;\n withdrawalId?: string;\n wallet: string;\n token: string;\n amount: string;\n fromBlock?: number;\n status: PodPortalRequestStatus;\n balanceRefreshPending?: boolean;\n message?: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport const PRIVACY_PORTAL_ABI = [\n \"function underlyingToken() view returns (address)\",\n \"function pToken() view returns (address)\",\n \"function decimals() view returns (uint8)\",\n \"function withdrawals(bytes32) view returns (address,address,uint256,uint256,uint256,bytes32,bytes32,uint8)\",\n \"function deposit(address recipient,uint256 amount,uint256 portalFee,uint256 mintCallbackFee) payable returns (bytes32)\",\n \"function depositNative(address recipient,uint256 amount,uint256 portalFee,uint256 mintCallbackFee) payable returns (bytes32)\",\n \"function nativeWrappedUnderlying() view returns (bool)\",\n \"function estimateDepositFees(uint256 amount) view returns (uint256 portalFee,bool usedDynamicPricing,uint256 mintTotalFee,uint256 mintCallbackFee)\",\n \"function estimateWithdrawFees(uint256 amount) view returns (uint256 portalFee,bool usedDynamicPricing,uint256 transferTotalFee,uint256 transferCallbackFee)\",\n \"function requestWithdrawWithPermit(address recipient,uint256 amount,uint256 portalFee,uint256 transferFee,uint256 transferCallbackFee,uint256 permitDeadline,uint8 v,bytes32 r,bytes32 s) payable returns (bytes32,bytes32)\",\n \"event DepositRequested(address indexed user,address indexed recipient,uint256 amount,bytes32 indexed mintRequestId)\",\n \"event WithdrawalRequested(bytes32 indexed withdrawalId,address indexed user,address indexed recipient,uint256 amount,bytes32 transferRequestId)\",\n \"event WithdrawalReleased(bytes32 indexed withdrawalId,address indexed recipient,uint256 amount)\",\n \"event BurnSubmitted(bytes32 indexed withdrawalId,uint256 amount,bytes32 burnRequestId)\",\n \"event BurnDebtRecorded(bytes32 indexed withdrawalId,uint256 amount,bytes reason)\",\n] as const;\n\n/**\n * Owner/admin surface of the PoD PrivacyPortal contracts (EIP-1167 proxies;\n * all portals on a chain share one implementation). Recovered via bytecode\n * selector analysis and live eth_calls — the portal source is not published\n * and the contracts are unverified on explorers.\n *\n * Assumptions pending on-chain confirmation:\n * - getFeeConfig(true) is the DEPOSIT config (both configs are currently\n * identical on every deployed portal, so polarity is unverified);\n * - fixedFee/maxFee are denominated in native wei (ETH on Sepolia, AVAX on\n * Fuji); percentageBps shares COTI's FEE_DIVISOR = 1e6 scale.\n * - maxFee == type(uint128).max is the deployed \"no cap\" sentinel.\n */\nexport const POD_PORTAL_ADMIN_ABI = [\n \"function owner() view returns (address)\",\n \"function setDepositFee(uint256 fixedFee, uint256 percentageBps, uint256 maxFee)\",\n \"function setWithdrawFee(uint256 fixedFee, uint256 percentageBps, uint256 maxFee)\",\n \"function getFeeConfig(bool isDeposit) view returns (uint256 fixedFee, uint256 percentageBps, uint256 maxFee)\",\n \"function accumulatedPortalFees() view returns (uint256)\",\n \"function estimateDepositFees(uint256 amount) view returns (uint256 portalFee,bool usedDynamicPricing,uint256 mintTotalFee,uint256 mintCallbackFee)\",\n \"function estimateWithdrawFees(uint256 amount) view returns (uint256 portalFee,bool usedDynamicPricing,uint256 transferTotalFee,uint256 transferCallbackFee)\",\n] as const;\n\nexport const POD_PTOKEN_ABI = [\n \"function name() view returns (string)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n \"function nonces(address owner) view returns (uint256)\",\n \"function failedRequests(bytes32 requestId) view returns (bytes)\",\n \"function balanceOf(address account) view returns (tuple(uint256 ciphertextHigh,uint256 ciphertextLow))\",\n \"function balanceWithState(address account) view returns (tuple(uint256 ciphertextHigh,uint256 ciphertextLow) balance,bool pending,bool callbackErrored)\",\n \"function balanceOfWithStatus(address account) view returns (tuple(uint256 ciphertextHigh,uint256 ciphertextLow),bool)\",\n \"error TransferAlreadyPending(address from, address to, bytes32 requestId)\",\n \"event TransferRequestSubmitted(address indexed from,address indexed to,bytes32 requestId)\",\n \"event Transfer(address indexed from,address indexed to,bytes senderValue,bytes receiverValue)\",\n \"event TransferFailed(address indexed from,address indexed to,bytes errorMsg)\",\n \"event RequestCallbackFailed(address indexed from,address indexed to,bytes32 requestId,bytes callbackData)\",\n] as const;\n\n","import type { PodSdkConfig } from \"@coti-io/pod-sdk\";\nimport { COTI_TESTNET_CHAIN_ID, SEPOLIA_CHAIN_ID } from \"../../contracts/pod\";\nimport { getPluginConfig, type CotiPluginConfig } from \"../../config/plugin\";\nimport { AVALANCHE_FUJI_CHAIN_ID, getRpcUrlForChain } from \"../index\";\nimport { POD_INBOX_ADDRESS } from \"../podInbox\";\n\n/** Source/target chains registered for PoD portal cross-chain tracking. */\nconst POD_TRACKING_CHAIN_ORDER = [\n SEPOLIA_CHAIN_ID,\n AVALANCHE_FUJI_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID,\n] as const;\n\nconst POD_TRACKING_CHAIN_IDS = new Set<number>(POD_TRACKING_CHAIN_ORDER);\n\n/** Shared PoD inbox on every registered tracking chain. */\nexport const getPodInboxAddress = (chainId: number): string => {\n if (!POD_TRACKING_CHAIN_IDS.has(chainId)) {\n throw new Error(`PoD inbox is not registered for chain ${chainId}`);\n }\n return POD_INBOX_ADDRESS;\n};\n\nconst resolvePodChainRpcUrl = (chainId: number, pluginConfig: CotiPluginConfig): string => {\n if (chainId === SEPOLIA_CHAIN_ID && pluginConfig.sepoliaRpcUrl) {\n return pluginConfig.sepoliaRpcUrl;\n }\n if (chainId === COTI_TESTNET_CHAIN_ID && pluginConfig.cotiTestnetRpcUrl) {\n return pluginConfig.cotiTestnetRpcUrl;\n }\n return getRpcUrlForChain(chainId);\n};\n\nexport const getPodSdkConfig = (): PodSdkConfig => {\n const pluginConfig = getPluginConfig();\n return {\n encryptionNetwork: \"testnet\",\n chains: POD_TRACKING_CHAIN_ORDER.map(chainId => ({\n chainId,\n inboxAddress: POD_INBOX_ADDRESS,\n rpcUrl: resolvePodChainRpcUrl(chainId, pluginConfig),\n })),\n };\n};\n\n/** @deprecated Use getPodSdkConfig() for fresh RPC URLs from plugin config. */\nexport const podSdkConfig: PodSdkConfig = getPodSdkConfig();\n","import { ethers } from \"ethers\";\nimport type { PodFeeEstimate } from \"@coti-io/pod-sdk\";\nimport { getChainConfig } from \"../index\";\nimport type { TokenConfig } from \"../types\";\nimport { logger } from \"../../lib/logger\";\nimport type { PodWithdrawPermit } from \"./podPortalFees\";\nimport {\n buildPodMethodArgs,\n estimatePodExecutionGasWei,\n estimatePodFee,\n formatPodFeeDisplay,\n formatPortalFeeDisplay,\n quotePortalFeeOnly,\n resolvePodPortalMethod,\n resolvePodTxGasPrice,\n} from \"./podPortalFees\";\n\nexport type PodPortalFeeQuote = {\n gasPrice: bigint;\n portalFeeWei: bigint;\n podInboxFeeWei: bigint;\n podCallbackFeeWei: bigint;\n l1ExecutionGasWei: bigint;\n podFeeEstimate: PodFeeEstimate;\n usedDynamicPricing: boolean;\n display: {\n portalFee: string;\n podInboxFee: string;\n l1Gas: string;\n portalFeeSymbol: string;\n };\n};\n\n/** Single source of truth for PoD portal fee quotes — one gasPrice, all components. */\nexport const quotePodPortalTransactionFees = async (params: {\n runner: ethers.ContractRunner;\n chainId: number;\n portalAddress: string;\n pubTok: TokenConfig | undefined;\n amount: string;\n direction: \"to-private\" | \"to-public\";\n withdrawPermit?: PodWithdrawPermit;\n gasPrice?: bigint;\n}): Promise<PodPortalFeeQuote> => {\n const dec = params.pubTok?.decimals ?? 18;\n const amountWei = ethers.parseUnits(params.amount, dec);\n const provider =\n \"provider\" in params.runner && params.runner.provider\n ? (params.runner.provider as ethers.Provider)\n : (params.runner as ethers.Provider);\n const gasPrice = params.gasPrice ?? await resolvePodTxGasPrice(provider);\n const nativeSymbol =\n getChainConfig(params.chainId)?.walletNetwork.nativeCurrency.symbol ?? \"ETH\";\n\n const portalQuote = await quotePortalFeeOnly(\n params.runner,\n params.portalAddress,\n amountWei,\n params.direction,\n gasPrice,\n );\n const method = resolvePodPortalMethod(params.direction, !!params.pubTok?.isNative);\n const wallet = await (params.runner as ethers.Signer).getAddress();\n const args = buildPodMethodArgs({\n direction: params.direction,\n wallet,\n amountWei,\n portalFee: portalQuote.portalFee,\n isNativeDeposit: !!params.pubTok?.isNative,\n withdrawPermit: params.withdrawPermit,\n });\n const podFeeEstimate = await estimatePodFee({\n runner: params.runner,\n portalAddress: params.portalAddress,\n chainId: params.chainId,\n direction: params.direction,\n method,\n args,\n gasPrice,\n });\n const l1ExecutionGasWei = await estimatePodExecutionGasWei({\n chainId: params.chainId,\n portalAddress: params.portalAddress,\n wallet,\n amountWei,\n portalFee: portalQuote.portalFee,\n direction: params.direction,\n isNativeDeposit: !!params.pubTok?.isNative,\n gasPrice,\n podFee: podFeeEstimate,\n withdrawPermit: params.withdrawPermit,\n });\n\n const result: PodPortalFeeQuote = {\n gasPrice,\n portalFeeWei: portalQuote.portalFee,\n podInboxFeeWei: podFeeEstimate.totalFee,\n podCallbackFeeWei: podFeeEstimate.callBackFee,\n l1ExecutionGasWei,\n podFeeEstimate,\n usedDynamicPricing: portalQuote.usedDynamicPricing,\n display: {\n portalFee: formatPortalFeeDisplay(portalQuote.portalFee, portalQuote.usedDynamicPricing),\n podInboxFee: formatPodFeeDisplay(podFeeEstimate.totalFee),\n l1Gas: formatPodFeeDisplay(l1ExecutionGasWei),\n portalFeeSymbol: nativeSymbol,\n },\n };\n\n logger.debug(\"[portal/fees] quotePodPortalTransactionFees\", {\n chainId: params.chainId,\n direction: params.direction,\n portalAddress: params.portalAddress,\n amount: params.amount,\n gasPrice: gasPrice.toString(),\n portalFeeWei: result.portalFeeWei.toString(),\n podInboxFeeWei: result.podInboxFeeWei.toString(),\n l1ExecutionGasWei: l1ExecutionGasWei.toString(),\n });\n\n return result;\n};\n","import { ethers } from \"ethers\";\nimport {\n DataType,\n PodContract,\n encodePodMethodArguments,\n type PodFeeEstimate,\n type PodFeeEstimationConfig,\n type PodMethodArgument,\n} from \"@coti-io/pod-sdk\";\nimport { PRIVACY_PORTAL_ABI } from \"../../contracts/pod\";\nimport { getChainConfig, getRpcUrlForChain } from \"../index\";\nimport { logger } from \"../../lib/logger\";\nimport { getPodSdkConfig } from \"./podSdkConfig\";\nimport { POD_DEFAULT_CALLBACK_DATA_SIZE, POD_INBOX_ADDRESS } from \"../podInbox\";\nimport type { TokenConfig } from \"../types\";\n\nexport interface PodWithdrawPermit {\n wallet: string;\n pTokenAddress: string;\n portalAddress: string;\n amountWei: string;\n deadline: string;\n v: number;\n r: string;\n s: string;\n}\n\nexport type PortalFeeQuote = {\n portalFee: bigint;\n usedDynamicPricing: boolean;\n gasPrice: bigint;\n};\n\nconst resolveFeeRunnerProvider = (runner: ethers.ContractRunner): ethers.Provider => {\n if (\"provider\" in runner && runner.provider) {\n return runner.provider as ethers.Provider;\n }\n return runner as ethers.Provider;\n};\n\n/** 10% headroom applied to spot gas price for both estimate and send. */\nexport const POD_GAS_PRICE_BUFFER_BPS = 1100n;\n\n/** Spot chain gas price via `eth_gasPrice`. */\nexport const getPodGasPrice = async (\n provider: ethers.BrowserProvider | ethers.JsonRpcProvider | ethers.Provider,\n): Promise<bigint> => {\n const rpc = provider as ethers.JsonRpcProvider;\n const gasPriceHex = await rpc.send(\"eth_gasPrice\", []);\n return BigInt(gasPriceHex);\n};\n\n/**\n * Gas price for PoD inbox fee estimation and tx send.\n * Uses `getFeeData().gasPrice` when available, with a 10% buffer so estimate\n * and `tx.gasprice` stay aligned per pod-sdk inbox rules.\n */\nexport const resolvePodTxGasPrice = async (\n provider: ethers.BrowserProvider | ethers.JsonRpcProvider | ethers.Provider,\n): Promise<bigint> => {\n let base: bigint;\n try {\n const feeData = await provider.getFeeData();\n base = feeData.gasPrice ?? await getPodGasPrice(provider);\n } catch {\n base = await getPodGasPrice(provider);\n }\n return (base * POD_GAS_PRICE_BUFFER_BPS) / 1000n;\n};\n\n/** @deprecated Use {@link resolvePodTxGasPrice}. */\nexport const getSepoliaGasPrice = resolvePodTxGasPrice;\n\nexport const quotePortalFeeOnly = async (\n runner: ethers.ContractRunner,\n portalAddress: string,\n amount: bigint,\n direction: \"to-private\" | \"to-public\",\n gasPrice?: bigint,\n): Promise<PortalFeeQuote> => {\n const provider = resolveFeeRunnerProvider(runner);\n const resolvedGasPrice = gasPrice ?? await resolvePodTxGasPrice(provider);\n const portal = new ethers.Contract(portalAddress, PRIVACY_PORTAL_ABI, runner);\n\n if (direction === \"to-private\") {\n const [portalFee, usedDynamicPricing] = await portal.estimateDepositFees(amount);\n const quote = {\n portalFee: BigInt(portalFee.toString()),\n usedDynamicPricing: Boolean(usedDynamicPricing),\n gasPrice: resolvedGasPrice,\n };\n logger.debug(\"[podPortalFees] quotePortalFeeOnly deposit\", {\n portalAddress,\n amount: amount.toString(),\n portalFee: quote.portalFee.toString(),\n usedDynamicPricing: quote.usedDynamicPricing,\n gasPrice: quote.gasPrice.toString(),\n });\n return quote;\n }\n\n const [portalFee, usedDynamicPricing] = await portal.estimateWithdrawFees(amount);\n const quote = {\n portalFee: BigInt(portalFee.toString()),\n usedDynamicPricing: Boolean(usedDynamicPricing),\n gasPrice: resolvedGasPrice,\n };\n logger.debug(\"[podPortalFees] quotePortalFeeOnly withdraw\", {\n portalAddress,\n amount: amount.toString(),\n portalFee: quote.portalFee.toString(),\n usedDynamicPricing: quote.usedDynamicPricing,\n gasPrice: quote.gasPrice.toString(),\n });\n return quote;\n};\n\nexport const formatPortalFeeDisplay = (\n portalFee: bigint,\n _usedDynamicPricing?: boolean,\n): string => ethers.formatEther(portalFee).replace(/\\.?0+$/, \"\") || \"0\";\n\nexport const formatPodFeeDisplay = (totalFee: bigint): string =>\n ethers.formatEther(totalFee).replace(/\\.?0+$/, \"\") || \"0\";\n\nexport const resolvePodFeeEstimationConfig = (\n chainId: number,\n direction: \"to-private\" | \"to-public\",\n gasPrice: bigint,\n): PodFeeEstimationConfig => {\n const limits = getChainConfig(chainId)?.podFeeEstimation?.[direction === \"to-private\" ? \"deposit\" : \"withdraw\"];\n if (!limits) {\n throw new Error(`PoD fee estimation is not configured for chain ${chainId}`);\n }\n const callBackDataSize = limits.callBackDataSize ?? POD_DEFAULT_CALLBACK_DATA_SIZE;\n const config: PodFeeEstimationConfig = {\n forwardGasLimit: limits.forwardGasLimit,\n gasPrice,\n };\n if (limits.callBackGasLimit !== undefined) {\n config.callBackGasLimit = limits.callBackGasLimit;\n config.callBackDataSize = callBackDataSize;\n }\n return config;\n};\n\nexport const resolvePodPortalMethod = (\n direction: \"to-private\" | \"to-public\",\n isNativeDeposit: boolean,\n): string => {\n if (direction === \"to-private\") {\n return isNativeDeposit ? \"depositNative\" : \"deposit\";\n }\n return \"requestWithdrawWithPermit\";\n};\n\nexport const buildPodMethodArgs = (params: {\n direction: \"to-private\" | \"to-public\";\n wallet: string;\n amountWei: bigint;\n portalFee: bigint;\n isNativeDeposit?: boolean;\n withdrawPermit?: PodWithdrawPermit;\n /** Remote PoD fee component for withdraw (`transferFee` arg). */\n remoteFee?: bigint;\n}): PodMethodArgument[] => {\n const {\n direction,\n wallet,\n amountWei,\n portalFee,\n isNativeDeposit = false,\n withdrawPermit,\n remoteFee = 0n,\n } = params;\n\n if (direction === \"to-private\") {\n return [\n { type: DataType.String, value: wallet, isCallBackFee: false },\n { type: DataType.Uint256, value: amountWei.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: portalFee.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: \"0\", isCallBackFee: true },\n ];\n }\n\n if (\n !withdrawPermit ||\n withdrawPermit.wallet.toLowerCase() !== wallet.toLowerCase() ||\n withdrawPermit.amountWei !== amountWei.toString()\n ) {\n const placeholderDeadline = BigInt(Math.floor(Date.now() / 1000) + 60 * 30);\n return [\n { type: DataType.String, value: wallet, isCallBackFee: false },\n { type: DataType.Uint256, value: amountWei.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: portalFee.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: remoteFee.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: \"0\", isCallBackFee: true },\n { type: DataType.Uint256, value: placeholderDeadline.toString(), isCallBackFee: false },\n { type: DataType.Uint8, value: \"0\", isCallBackFee: false },\n { type: DataType.String, value: ethers.ZeroHash, isCallBackFee: false },\n { type: DataType.String, value: ethers.ZeroHash, isCallBackFee: false },\n ];\n }\n\n return [\n { type: DataType.String, value: wallet, isCallBackFee: false },\n { type: DataType.Uint256, value: amountWei.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: portalFee.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: remoteFee.toString(), isCallBackFee: false },\n { type: DataType.Uint256, value: \"0\", isCallBackFee: true },\n { type: DataType.Uint256, value: withdrawPermit.deadline, isCallBackFee: false },\n { type: DataType.Uint8, value: withdrawPermit.v.toString(), isCallBackFee: false },\n { type: DataType.String, value: withdrawPermit.r, isCallBackFee: false },\n { type: DataType.String, value: withdrawPermit.s, isCallBackFee: false },\n ];\n};\n\nexport const createPodContract = (\n portalAddress: string,\n runner: ethers.ContractRunner,\n) =>\n new PodContract(portalAddress, PRIVACY_PORTAL_ABI, runner, {\n config: getPodSdkConfig(),\n inboxAddress: POD_INBOX_ADDRESS,\n });\n\nconst fallbackExecutionGasLimit = (\n chainId: number,\n direction: \"to-private\" | \"to-public\",\n): bigint => {\n const limits = getChainConfig(chainId)?.podFeeEstimation;\n if (!limits) return direction === \"to-private\" ? 850_000n : 900_000n;\n return direction === \"to-private\" ? limits.deposit.forwardGasLimit : limits.withdraw.forwardGasLimit;\n};\n\n/** L1 execution gas cost (gasLimit × gasPrice) for the portal tx, aligned with executor simulation. */\nexport const estimatePodExecutionGasWei = async (params: {\n chainId: number;\n portalAddress: string;\n wallet: string;\n amountWei: bigint;\n portalFee: bigint;\n direction: \"to-private\" | \"to-public\";\n isNativeDeposit: boolean;\n gasPrice: bigint;\n podFee: PodFeeEstimate;\n withdrawPermit?: PodWithdrawPermit;\n}): Promise<bigint> => {\n const fallbackLimit = fallbackExecutionGasLimit(params.chainId, params.direction);\n try {\n const rpcUrl = getRpcUrlForChain(params.chainId);\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const portal = new ethers.Contract(params.portalAddress, PRIVACY_PORTAL_ABI, rpcProvider);\n\n if (params.direction === \"to-private\") {\n const method = resolvePodPortalMethod(\"to-private\", params.isNativeDeposit);\n // The portal requires msg.value to cover the PoD fee on top of portalFee\n // (and the deposit amount for native), otherwise the simulation reverts.\n const nativeAmount = params.isNativeDeposit ? params.amountWei : 0n;\n const simulationValue = nativeAmount + params.portalFee + params.podFee.totalFee;\n const gasLimit = await portal[method].estimateGas(\n params.wallet,\n params.amountWei,\n params.portalFee,\n params.podFee.callBackFee,\n { from: params.wallet, value: simulationValue, gasPrice: params.gasPrice },\n );\n return gasLimit * params.gasPrice;\n }\n\n const permit = params.withdrawPermit;\n const deadline = permit\n ? BigInt(permit.deadline)\n : BigInt(Math.floor(Date.now() / 1000) + 60 * 30);\n const v = permit?.v ?? 0;\n const r = permit?.r ?? ethers.ZeroHash;\n const s = permit?.s ?? ethers.ZeroHash;\n // The contract requires transferFee == msg.value - portalFee, and the\n // transfer fee is the full PoD fee (remote + callback).\n const gasLimit = await portal.requestWithdrawWithPermit.estimateGas(\n params.wallet,\n params.amountWei,\n params.portalFee,\n params.podFee.totalFee,\n params.podFee.callBackFee,\n deadline,\n v,\n r,\n s,\n {\n from: params.wallet,\n value: params.portalFee + params.podFee.totalFee,\n gasPrice: params.gasPrice,\n },\n );\n return gasLimit * params.gasPrice;\n } catch {\n return fallbackLimit * params.gasPrice;\n }\n};\n\nexport const estimatePodFee = async (params: {\n runner: ethers.ContractRunner;\n portalAddress: string;\n chainId: number;\n direction: \"to-private\" | \"to-public\";\n method: string;\n args: PodMethodArgument[];\n gasPrice: bigint;\n}): Promise<PodFeeEstimate> => {\n const pod = createPodContract(params.portalAddress, params.runner);\n const feeCfg = resolvePodFeeEstimationConfig(params.chainId, params.direction, params.gasPrice);\n return pod.estimateFee(params.method, params.args, feeCfg);\n};\n\nexport const estimatePodPortalFees = async (params: {\n runner: ethers.ContractRunner;\n chainId: number;\n portalAddress: string;\n pubTok: TokenConfig | undefined;\n amount: string;\n direction: \"to-private\" | \"to-public\";\n withdrawPermit?: PodWithdrawPermit;\n}): Promise<{\n portalFeeDisplay: string;\n podFeeDisplay: string;\n podInboxFeeDisplay: string;\n l1GasDisplay: string;\n portalFeeWei: bigint;\n podFeeEstimate: PodFeeEstimate;\n gasPrice: bigint;\n usedDynamicPricing: boolean;\n}> => {\n const { quotePodPortalTransactionFees } = await import(\"./fees\");\n const quote = await quotePodPortalTransactionFees(params);\n const combinedPodFeeWei = quote.podInboxFeeWei + quote.l1ExecutionGasWei;\n return {\n portalFeeDisplay: quote.display.portalFee,\n podFeeDisplay: formatPodFeeDisplay(combinedPodFeeWei),\n podInboxFeeDisplay: quote.display.podInboxFee,\n l1GasDisplay: quote.display.l1Gas,\n portalFeeWei: quote.portalFeeWei,\n podFeeEstimate: quote.podFeeEstimate,\n gasPrice: quote.gasPrice,\n usedDynamicPricing: quote.usedDynamicPricing,\n };\n};\n\n/** Build tx gas overrides pinned to {@link gasPrice}, using EIP-1559 when the network supports it. */\nexport const buildPodPortalTxGasOverrides = async (\n runner: ethers.ContractRunner,\n gasPrice: bigint,\n): Promise<Pick<ethers.TransactionRequest, \"type\" | \"gasPrice\" | \"maxFeePerGas\" | \"maxPriorityFeePerGas\">> => {\n const provider = resolveFeeRunnerProvider(runner);\n let supportsEip1559 = false;\n if (provider) {\n try {\n const feeData = await provider.getFeeData();\n supportsEip1559 = feeData.maxFeePerGas != null && feeData.maxPriorityFeePerGas != null;\n } catch {\n supportsEip1559 = false;\n }\n }\n\n if (supportsEip1559) {\n // Effective price = min(maxFeePerGas, baseFee + maxPriorityFeePerGas).\n // Pin both to gasPrice so on-chain tx.gasprice matches the inbox estimate input.\n return {\n type: 2,\n maxFeePerGas: gasPrice,\n maxPriorityFeePerGas: gasPrice,\n };\n }\n\n return { gasPrice };\n};\n\n/** Send a PoD portal tx using SDK fee estimation; pins gas fees to the estimate snapshot. */\nexport const sendPodPortalMethod = async (params: {\n runner: ethers.Signer;\n portalAddress: string;\n chainId: number;\n direction: \"to-private\" | \"to-public\";\n method: string;\n args: PodMethodArgument[];\n gasPrice: bigint;\n portalFee: bigint;\n amountWei?: bigint;\n isNativeDeposit?: boolean;\n gasLimit?: bigint;\n /** Precomputed PoD fee (from {@link estimatePodFee}) to avoid re-estimating. */\n fee?: PodFeeEstimate;\n}): Promise<ethers.ContractTransactionResponse> => {\n const pod = createPodContract(params.portalAddress, params.runner);\n const fee = params.fee ?? await pod.estimateFee(\n params.method,\n params.args,\n resolvePodFeeEstimationConfig(params.chainId, params.direction, params.gasPrice),\n );\n\n const cbIndex = params.args.findIndex(arg => arg.isCallBackFee);\n const encodedArgs = await encodePodMethodArguments(\n params.args.map(arg => ({ ...arg })),\n getPodSdkConfig().encryptionNetwork ?? \"testnet\",\n false,\n );\n if (cbIndex !== -1) {\n encodedArgs[cbIndex].value = fee.callBackFee;\n }\n\n if (params.direction === \"to-public\") {\n // Privacy Portal requires transferFee == msg.value - portalFee (full PoD fee: remote + callback).\n const transferFeeIndex = 3;\n encodedArgs[transferFeeIndex].value = fee.totalFee;\n }\n\n const fn = pod.contract.getFunction(params.method);\n const vals = encodedArgs.map(arg => arg.value);\n const nativeAmount = params.isNativeDeposit && params.amountWei ? params.amountWei : 0n;\n const txValue = nativeAmount + params.portalFee + fee.totalFee;\n const gasOverrides = await buildPodPortalTxGasOverrides(params.runner, params.gasPrice);\n const overrides: ethers.TransactionRequest = {\n value: txValue,\n ...gasOverrides,\n };\n if (params.gasLimit) {\n overrides.gasLimit = params.gasLimit;\n }\n return fn(...vals, overrides);\n};\n","// Configuration\nexport {\n configureCotiPlugin,\n getPluginConfig,\n getSnapRequestParams,\n isSnapInstallEnabled,\n} from './config/plugin';\nexport type {\n CotiPluginConfig,\n AesKeyChainId,\n EncryptedAesBackup,\n GrantResult,\n OnboardingServiceRequest,\n OnboardingServices,\n SaveEncryptedAesBackupRequest,\n} from './config/plugin';\n\n// Logging — silent by default, opt in via configureCotiPlugin({ debug: true })\nexport { logger, setDebugLogging } from './lib/logger';\nexport type { Logger } from './lib/logger';\n\n// Errors\nexport { CotiPluginError, CotiErrorCode, isCotiPluginError, hasCotiErrorCode } from './errors';\n\n// Chain definitions (viem + RPC — derived from CHAIN_CONFIGS)\nexport {\n cotiMainnet,\n cotiTestnet,\n sepolia,\n ethereumMainnet,\n COTI_MAINNET_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID,\n COTI_TESTNET_POD_INBOX,\n POD_INBOX_ADDRESS,\n SEPOLIA_CHAIN_ID,\n ETHEREUM_MAINNET_CHAIN_ID,\n COTI_MAINNET_RPC,\n COTI_TESTNET_RPC,\n SEPOLIA_RPC,\n SEPOLIA_RPC_FALLBACK,\n ETHEREUM_MAINNET_RPC,\n getRpcUrlForChainId,\n} from './chains';\n\n// Chain registry (multi-chain portal strategies)\nexport {\n CHAIN_CONFIGS,\n DEFAULT_CHAIN_ID,\n getChainConfig,\n requireChainConfig,\n getContractAddresses,\n getTokensForChain,\n getExplorerBaseUrlForChain,\n getRpcUrlForChain,\n getRpcUrlsForChain,\n getNetworkNameForChain,\n getUnlockStrategyForChain,\n getWalletNetworkConfigs,\n getWalletNetworkOptions,\n getChainIdConstants,\n resolveIndexPageUi,\n} from './chains';\nexport type { ChainConfig as PortalChainConfig, ResolvedIndexPageUi, UnlockStrategy, PortalStrategy, WalletNetworkConfig, ChainIndexPageUi } from './chains/types';\n\n// PoD portal\nexport {\n SEPOLIA_CHAIN_ID as POD_SEPOLIA_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID as POD_COTI_TESTNET_CHAIN_ID,\n DEFAULT_POD_EXPLORER_BASE_URL,\n buildPodExplorerRequestUrl,\n DEFAULT_POD_BALANCE_STATE,\n PRIVACY_PORTAL_ABI,\n POD_PTOKEN_ABI,\n POD_PORTAL_ADMIN_ABI,\n} from './contracts/pod';\nexport type { PodPortalRequest, PodPortalRequestStatus, PodBalanceState, PodBalanceTrustState } from './contracts/pod';\nexport { loadPodRequests, savePodRequests, podRequestsStorageKey } from './pod/podPortalRequestsStorage';\nexport { estimateCotiBridgeGasFeeDisplay } from './chains/cotiBridgeGasEstimate';\nexport { quoteCotiBridgeFees } from './chains/coti-bridge/fees';\nexport type { CotiBridgeFeeQuote } from './chains/coti-bridge/fees';\nexport { resolvePodRequestStatus } from './chains/portal/podRequestStatus';\nexport {\n executePodPortalTransaction,\n signPodWithdrawPermit,\n getPodInboxAddress,\n getPodSdkConfig,\n getPodGasPrice,\n resolvePodTxGasPrice,\n getSepoliaGasPrice,\n quotePortalFeeOnly,\n quotePodPortalTransactionFees,\n estimatePodPortalFees,\n formatPortalFeeDisplay,\n formatPodFeeDisplay,\n} from './chains/portal/executePodPortalTransaction';\nexport type { PodWithdrawPermit, PodPortalFeeQuote } from './chains/portal/executePodPortalTransaction';\nexport { fetchPodOracleTokenUsdPrice, POD_PRICE_ORACLE_ABI } from './chains/podPriceOracle';\nexport { fetchPodBridgeData, simulatePodPortalFee } from './chains/portal/podPortalAdminData';\n\n// Contracts\nexport { CONTRACT_ADDRESSES, SUPPORTED_TOKENS, MINIMUM_PORTAL_IN_AMOUNTS, ERC20_ABI, getPublicTokensForChain, getPrivateTokensForChain } from './contracts/config';\nexport type { TokenConfig } from './contracts/config';\nexport { TOKEN_ABI, BRIDGE_ABI, BRIDGE_ERC20_ABI, COTI_PRICE_CONSUMER_ABI } from './contracts/abis';\nexport { LIMITS } from './contracts/limits';\n\n// Hooks — Wallet Manager\nexport { useMetamask } from './hooks/useMetamask';\n\n// Hooks — Balance Manager\nexport { usePrivateTokenBalance } from './hooks/usePrivateTokenBalance';\nexport { useBalanceUpdater } from './hooks/useBalanceUpdater';\n\n// Hooks — Bridge Operations\n// NOTE: `usePrivacyBridge` (and its `getInitialPublicTokens`/`getInitialPrivateTokens`\n// helpers + `Token`/`SwapProgressStage` types) are intentionally NOT exported. They are\n// internal to `PrivacyBridgeProvider`; consumers should use the provider + context instead.\nexport { useBridgeData } from './hooks/useBridgeData';\nexport type { BridgeData } from './hooks/useBridgeData';\nexport { useBridgeStatus } from './hooks/useBridgeStatus';\nexport type { BridgeStatus } from './hooks/useBridgeStatus';\nexport { estimateBridgeFee } from './hooks/useEstimateBridgeFees';\nexport type { FeeEstimate } from './hooks/useEstimateBridgeFees';\nexport { fetchBridgeFees, fetchTokenUsdPrice, computeCotiFee, computeErc20Fee, simulateFeeOnChain, getTokenSimulationMeta } from './hooks/useBridgeFees';\nexport type { BridgeFees, SimulationResult } from './hooks/useBridgeFees';\nexport {\n resolvePrivateTokenContractAddress,\n resolvePrivateTokenTransferTarget,\n PRIVATE_ERC20_TRANSFER_256_SIG,\n} from './hooks/privacyBridge';\n\n// Hooks — Network\nexport { useNetworkEnforcer } from './hooks/useNetworkEnforcer';\nexport type { NetworkEnforcerResult } from './hooks/useNetworkEnforcer';\n\n// Context — legacy flat API + bounded slice hooks\nexport {\n PrivacyBridgeProvider,\n usePrivacyBridgeContext,\n usePrivacyBridgeWallet,\n usePrivacyBridgeNetwork,\n usePrivacyBridgeUnlock,\n usePrivacyBridgeTokens,\n usePrivacyBridgeSwap,\n usePrivacyBridgePod,\n usePrivacyBridgeModals,\n} from './context/privacyBridge';\nexport type {\n PrivacyBridgeContextType,\n PrivacyBridgeProviderProps,\n PrivacyBridgeWalletContextValue,\n PrivacyBridgeNetworkContextValue,\n PrivacyBridgeUnlockContextValue,\n PrivacyBridgeTokensContextValue,\n PrivacyBridgeSwapContextValue,\n PrivacyBridgePodContextValue,\n PrivacyBridgeModalsContextValue,\n} from './context/privacyBridge';\nexport {\n PrivateUnlockProvider,\n usePrivateUnlock,\n} from './context/privateUnlock';\nexport type {\n PrivateUnlockControllerValue,\n PrivateUnlockProviderOptions,\n PrivateUnlockProviderProps,\n} from './context/privateUnlock';\n\n// Providers — Multi-Wallet Support\nexport {\n WagmiRainbowKitProvider,\n getWagmiConfig,\n wagmiConfig,\n type WagmiConfigOptions,\n} from './providers/WagmiRainbowKitProvider';\nexport {\n mobileZerionWallet,\n WALLET_CONNECT_FAILURE_EVENT,\n type WalletConnectFailureDetail,\n} from './providers/mobileZerionWallet';\n\n// Hooks — Wallet Type Detection\nexport { useWalletType } from './hooks/useWalletType';\nexport type { WalletTypeInfo, WalletType } from './hooks/useWalletType';\n\n// Hooks — Onboarding progress types\nexport { ONBOARDING_STEPS } from './hooks/useAesKeyProvider';\nexport type {\n AesKeyProviderOptions,\n OnboardingStep,\n OnboardingStepInfo,\n OnboardingProgressCallback,\n} from './hooks/useAesKeyProvider';\n// Components — Onboarding\nexport { OnboardModal, onboardModalDefaultStyles, ONBOARD_MODAL_STYLE_KEYS } from './components/OnboardModal';\nexport type { OnboardModalProps, OnboardModalTheme } from './components/OnboardModal';\n\n// Components — Network\nexport { NetworkGuard } from './components/NetworkGuard';\nexport type { NetworkGuardProps } from './components/NetworkGuard';\n\n// Re-export from RainbowKit for consuming apps\nexport { useConnectModal } from '@rainbow-me/rainbowkit';\n\n// Utilities\nexport { isMultipleWalletsError, MULTIPLE_WALLETS_ERROR_SUBSTRING } from './utils/walletErrors';\nexport { formatTokenBalanceDisplay, truncateDecimalValue, formatBalanceWithNotation, addThousandsSeparators } from './lib/utils';\nexport {\n getEthereumProvider,\n getEip6963MetaMaskProvider,\n getEip6963RabbyProvider,\n resolveMetaMaskInjectedTarget,\n resolveRabbyInjectedTarget,\n resolveConnectedProvider,\n} from './lib/ethereum';\nexport type { EIP1193Provider, ConnectorProviderSource } from './lib/ethereum';\n\n// Chain mute utilities (for suppressing UI reactions during cross-chain onboarding)\nexport { muteChainUpdates, unmuteChainUpdates, isChainUpdatesMuted } from './lib/chainMute';\n","/**\n * Typed error classes for the COTI Wallet Plugin.\n *\n * Replaces string-based error matching (`error.message.includes('...')`) with\n * structured error codes that can be checked via `instanceof` or `.code`.\n */\n\n/**\n * All known error codes emitted by the COTI Wallet Plugin.\n */\nexport enum CotiErrorCode {\n // ─── Wallet / Provider ─────────────────────────────────────────────────\n /** MetaMask (or any EIP-1193 provider) is not installed. */\n METAMASK_NOT_INSTALLED = 'METAMASK_NOT_INSTALLED',\n /** No EIP-1193 provider found on `window.ethereum`. */\n NO_PROVIDER = 'NO_PROVIDER',\n /** User rejected the wallet request (EIP-1193 code 4001). */\n USER_REJECTED = 'USER_REJECTED',\n\n // ─── Snap ──────────────────────────────────────────────────────────────\n /** COTI Snap is not installed or connection attempt failed. */\n SNAP_CONNECT_FAILED = 'SNAP_CONNECT_FAILED',\n /** User dismissed the Snap dialog (e.g., rejected key retrieval). */\n SNAP_DIALOG_REJECTED = 'SNAP_DIALOG_REJECTED',\n /** Snap is required but not available for the current wallet type. */\n SNAP_REQUIRED = 'SNAP_REQUIRED',\n /** Snap key existence check failed after retry. */\n SNAP_KEY_CHECK_FAILED = 'SNAP_KEY_CHECK_FAILED',\n\n // ─── AES Key / Onboarding ─────────────────────────────────────────────\n /** AES key does not match the on-chain account (decryption yields garbage). */\n AES_KEY_MISMATCH = 'AES_KEY_MISMATCH',\n /** AES key is missing or was not provided. */\n AES_KEY_MISSING = 'AES_KEY_MISSING',\n /** Account has never been onboarded to the COTI network. */\n ACCOUNT_NOT_ONBOARDED = 'ACCOUNT_NOT_ONBOARDED',\n /** Onboarding process did not complete or key retrieval failed. */\n ONBOARDING_INCOMPLETE = 'ONBOARDING_INCOMPLETE',\n\n // ─── Network ───────────────────────────────────────────────────────────\n /** Connected to an unsupported chain ID. */\n UNSUPPORTED_NETWORK = 'UNSUPPORTED_NETWORK',\n /** WalletConnect Cloud project ID was not configured. */\n WALLETCONNECT_PROJECT_ID_MISSING = 'WALLETCONNECT_PROJECT_ID_MISSING',\n\n // ─── Bridge / Transaction ──────────────────────────────────────────────\n /** Insufficient token balance for the requested operation. */\n INSUFFICIENT_BALANCE = 'INSUFFICIENT_BALANCE',\n /** ERC20 allowance is too low for the requested bridge amount. */\n INSUFFICIENT_ALLOWANCE = 'INSUFFICIENT_ALLOWANCE',\n /** Bridge or token contract address not found for the current chain. */\n CONTRACT_NOT_FOUND = 'CONTRACT_NOT_FOUND',\n /** On-chain transaction reverted. */\n TRANSACTION_REVERTED = 'TRANSACTION_REVERTED',\n /** Oracle timestamp mismatch (stale price data). */\n ORACLE_TIMESTAMP_MISMATCH = 'ORACLE_TIMESTAMP_MISMATCH',\n\n // ─── API ───────────────────────────────────────────────────────────────\n /** External API (bridge tracker, cap meter) returned a non-success status. */\n API_ERROR = 'API_ERROR',\n\n // ─── Validation ────────────────────────────────────────────────────────\n /** Input validation failed (e.g., invalid AES key format, invalid token amount). */\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n}\n\n/**\n * Base error class for all COTI Wallet Plugin errors.\n *\n * Consumers can check errors via:\n * - `error instanceof CotiPluginError` (type guard)\n * - `error.code === CotiErrorCode.AES_KEY_MISMATCH` (code check)\n *\n * @example\n * ```typescript\n * try {\n * await unlockPrivateBalances();\n * } catch (error) {\n * if (error instanceof CotiPluginError) {\n * switch (error.code) {\n * case CotiErrorCode.AES_KEY_MISMATCH:\n * // show re-onboarding UI\n * break;\n * case CotiErrorCode.SNAP_CONNECT_FAILED:\n * // show snap install modal\n * break;\n * case CotiErrorCode.USER_REJECTED:\n * // user cancelled, do nothing\n * break;\n * }\n * }\n * }\n * ```\n */\nexport class CotiPluginError extends Error {\n /** Structured error code for programmatic matching. */\n public readonly code: CotiErrorCode;\n /** Optional additional context about the error. */\n public readonly detail?: string;\n\n constructor(code: CotiErrorCode, message?: string, detail?: string) {\n super(message ?? code);\n this.name = 'CotiPluginError';\n this.code = code;\n this.detail = detail;\n // Maintains proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, CotiPluginError.prototype);\n }\n}\n\n/**\n * Type guard to check if an unknown error is a CotiPluginError.\n */\nexport function isCotiPluginError(error: unknown): error is CotiPluginError {\n return error instanceof CotiPluginError;\n}\n\n/**\n * Type guard to check if an unknown error has a specific COTI error code.\n */\nexport function hasCotiErrorCode(error: unknown, code: CotiErrorCode): boolean {\n return isCotiPluginError(error) && error.code === code;\n}\n","import type { PodPortalRequest } from \"../contracts/pod\";\nimport { logger } from \"../lib/logger\";\n\nconst STORAGE_PREFIX = \"pod-portal-requests:v1\";\n\nexport const podRequestsStorageKey = (wallet?: string) =>\n `${STORAGE_PREFIX}:${(wallet ?? \"\").toLowerCase()}`;\n\nexport function loadPodRequests(wallet?: string): PodPortalRequest[] {\n try {\n const raw = localStorage.getItem(podRequestsStorageKey(wallet));\n if (!raw) return [];\n const parsed = JSON.parse(raw) as PodPortalRequest[];\n return Array.isArray(parsed) ? parsed.slice(0, 20) : [];\n } catch {\n return [];\n }\n}\n\nexport function savePodRequests(wallet: string | undefined, requests: PodPortalRequest[]) {\n try {\n localStorage.setItem(podRequestsStorageKey(wallet), JSON.stringify(requests.slice(0, 20)));\n } catch (e) {\n logger.warn('savePodRequests failed', e);\n }\n}\n","import { ethers } from \"ethers\";\nimport { getRpcUrlForChain } from \"./index\";\nimport { estimateBridgeFee } from \"../hooks/useEstimateBridgeFees\";\nimport { logger } from \"../lib/logger\";\n\n/**\n * Gas fee string for display on COTI bridge chains (not PoD portal).\n * Mirrors the estimation path in usePrivacyBridge `updateGasFee`.\n */\nexport async function estimateCotiBridgeGasFeeDisplay(params: {\n provider: ethers.BrowserProvider;\n currentChainId: number;\n bridgeAddress: string;\n symbol: string;\n direction: \"to-private\" | \"to-public\";\n amountWei: bigint;\n gasPrice: bigint;\n isErc20Token: boolean;\n /** When set, avoids provider.getSigner() (which may hit a hijacked window.ethereum). */\n fromAddress?: string;\n}): Promise<string> {\n const { provider, currentChainId, bridgeAddress, symbol, direction, amountWei, gasPrice, isErc20Token, fromAddress } = params;\n\n let nativeCotiFee = 0n;\n if (isErc20Token) {\n try {\n const rpcUrl = getRpcUrlForChain(Number((await provider.getNetwork()).chainId));\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const isDeposit = direction === \"to-private\";\n const feeEstimate = await estimateBridgeFee(symbol, \"1\", rpcProvider);\n const feeStr = isDeposit ? feeEstimate.depositFee : feeEstimate.withdrawFee;\n if (feeStr !== \"Error\") {\n nativeCotiFee = ethers.parseEther(feeStr);\n }\n } catch (e) {\n logger.warn('Could not compute dynamic fee for gas estimation', e);\n }\n }\n\n let calldata: string;\n let msgValue = nativeCotiFee;\n\n if (direction === \"to-private\" && isErc20Token) {\n const estimatedFeeWei = 790000n * gasPrice;\n logger.log('ERC20 deposit: using observed gas constant 790000');\n /* v8 ignore next */\n return ethers.formatEther(estimatedFeeWei).replace(/\\.?0+$/, \"\") || \"0\";\n } else if (direction === \"to-private\") {\n const iface = new ethers.Interface([\"function deposit(uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) payable\"]);\n calldata = iface.encodeFunctionData(\"deposit\", [0, 0]);\n msgValue = amountWei;\n } else {\n const iface = new ethers.Interface([\"function withdraw(uint256 amount, uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) payable\"]);\n calldata = iface.encodeFunctionData(\"withdraw\", [amountWei, 0, 0]);\n }\n\n let gasLimit: bigint;\n try {\n const walletAddr = fromAddress ?? await provider.getSigner().then(s => s.getAddress());\n // Use a direct COTI JsonRpcProvider for the display estimate rather than\n // window.ethereum. Routing through MetaMask makes it log every rejected RPC\n // (-32603) to the console even though we catch the error and fall back here.\n // ethers' JsonRpcProvider surfaces the same error quietly via our try/catch.\n const rpcProvider = new ethers.JsonRpcProvider(getRpcUrlForChain(currentChainId));\n gasLimit = await rpcProvider.estimateGas({\n from: walletAddr,\n to: bridgeAddress,\n data: calldata,\n value: msgValue,\n });\n logger.log('eth_estimateGas succeeded', { gasLimit: gasLimit.toString() });\n } catch (estimateErr: any) {\n const isNativeCotiDeposit = !isErc20Token && direction === \"to-private\";\n gasLimit = isNativeCotiDeposit ? 660000n : 500000n;\n logger.warn('eth_estimateGas failed, using realistic fallback', {\n gasLimit: gasLimit.toString(),\n message: estimateErr?.message,\n });\n }\n\n const estimatedFeeWei = gasLimit * gasPrice;\n logger.log('Gas fee estimation', {\n gasPrice: gasPrice.toString(),\n gasLimit: gasLimit.toString(),\n feeCoti: ethers.formatEther(estimatedFeeWei),\n });\n\n /* v8 ignore next */\n return ethers.formatEther(estimatedFeeWei).replace(/\\.?0+$/, \"\") || \"0\";\n}\n","import { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES } from '../contracts/config';\nimport { logger } from '../lib/logger';\n\nconst ERC20_ESTIMATE_FEE_ABI = [\n 'function estimateDepositFee(uint256 amount) view returns (uint256 fee, uint256 cotiLastUpdated, uint256 tokenLastUpdated, uint256 blockTimestamp)',\n 'function estimateWithdrawFee(uint256 amount) view returns (uint256 fee, uint256 cotiLastUpdated, uint256 tokenLastUpdated, uint256 blockTimestamp)',\n] as const;\n\nconst NATIVE_ESTIMATE_FEE_ABI = [\n 'function estimateDepositFee(uint256 amount) view returns (uint256 fee, uint256 cotiLastUpdated, uint256 blockTimestamp)',\n 'function estimateWithdrawFee(uint256 amount) view returns (uint256 fee, uint256 cotiLastUpdated, uint256 blockTimestamp)',\n] as const;\n\nexport interface FeeEstimate {\n depositFee: string;\n withdrawFee: string;\n cotiLastUpdated: string;\n tokenLastUpdated: string;\n blockTimestamp: string;\n}\n\nconst ERROR_ESTIMATE: FeeEstimate = { depositFee: 'Error', withdrawFee: 'Error', cotiLastUpdated: '0', tokenLastUpdated: '0', blockTimestamp: '0' };\n\ninterface TokenMeta {\n bridgeAddressKey: string;\n decimals: number;\n isNative: boolean;\n}\n\nconst TOKEN_META: Record<string, TokenMeta> = {\n COTI: { bridgeAddressKey: 'PrivacyBridgeCotiNative', decimals: 18, isNative: true },\n WETH: { bridgeAddressKey: 'PrivacyBridgeWETH', decimals: 18, isNative: false },\n WBTC: { bridgeAddressKey: 'PrivacyBridgeWBTC', decimals: 8, isNative: false },\n USDT: { bridgeAddressKey: 'PrivacyBridgeUSDT', decimals: 6, isNative: false },\n 'USDC.e': { bridgeAddressKey: 'PrivacyBridgeUSDCe', decimals: 6, isNative: false },\n WADA: { bridgeAddressKey: 'PrivacyBridgeWADA', decimals: 6, isNative: false },\n gCOTI: { bridgeAddressKey: 'PrivacyBridgegCOTI', decimals: 18, isNative: false },\n NIGHT: { bridgeAddressKey: 'PrivacyBridgeNight', decimals: 6, isNative: false },\n};\n\nexport async function estimateBridgeFee(\n symbol: string,\n amount: string,\n provider: ethers.JsonRpcProvider | ethers.BrowserProvider,\n): Promise<FeeEstimate> {\n const meta = TOKEN_META[symbol];\n if (!meta) {\n logger.warn(`No token metadata for symbol: ${symbol}`);\n return ERROR_ESTIMATE;\n }\n\n try {\n const chainId = Number((await provider.getNetwork()).chainId);\n const addresses = CONTRACT_ADDRESSES[chainId as keyof typeof CONTRACT_ADDRESSES];\n if (!addresses) return ERROR_ESTIMATE;\n\n const bridgeAddress = addresses[meta.bridgeAddressKey as keyof typeof addresses];\n if (!bridgeAddress) return ERROR_ESTIMATE;\n\n const abi = meta.isNative ? NATIVE_ESTIMATE_FEE_ABI : ERC20_ESTIMATE_FEE_ABI;\n const contract = new ethers.Contract(bridgeAddress, abi, provider);\n const amountWei = ethers.parseUnits(amount, meta.decimals);\n\n if (meta.isNative) {\n // Native 3-tuple: (fee, cotiLastUpdated, blockTimestamp)\n const [depositResult, withdrawResult] = await Promise.all([\n contract.estimateDepositFee(amountWei).catch(() => [0n, 0n, 0n]),\n contract.estimateWithdrawFee(amountWei).catch(() => [0n, 0n, 0n]),\n ]);\n\n const cotiLastUpdated = depositResult[1].toString();\n return {\n depositFee: ethers.formatEther(depositResult[0]),\n withdrawFee: ethers.formatEther(withdrawResult[0]),\n cotiLastUpdated,\n tokenLastUpdated: cotiLastUpdated,\n blockTimestamp: depositResult[2].toString(),\n };\n } else {\n // ERC20 4-tuple: (fee, cotiLastUpdated, tokenLastUpdated, blockTimestamp)\n const [depositResult, withdrawResult] = await Promise.all([\n contract.estimateDepositFee(amountWei).catch(() => [0n, 0n, 0n, 0n]),\n contract.estimateWithdrawFee(amountWei).catch(() => [0n, 0n, 0n, 0n]),\n ]);\n\n return {\n depositFee: ethers.formatEther(depositResult[0]),\n withdrawFee: ethers.formatEther(withdrawResult[0]),\n cotiLastUpdated: depositResult[1].toString(),\n tokenLastUpdated: depositResult[2].toString(),\n blockTimestamp: depositResult[3].toString(),\n };\n }\n } catch (err) {\n logger.error(`Error estimating bridge fees for ${symbol}:`, err);\n return ERROR_ESTIMATE;\n }\n}\n","import { CHAIN_CONFIGS } from '../chains';\nimport type { TokenConfig } from '../chains/types';\n\nexport type { TokenConfig };\n\nexport const CONTRACT_ADDRESSES: Record<number, Record<string, string>> =\n Object.fromEntries(Object.values(CHAIN_CONFIGS).map(chain => [chain.id, chain.addresses]));\n\nexport const SUPPORTED_TOKENS: TokenConfig[] = Array.from(\n new Map(\n Object.values(CHAIN_CONFIGS)\n .flatMap(chain => chain.tokens)\n .map(token => [`${token.isPrivate ? 'private' : 'public'}:${token.symbol}`, token])\n ).values()\n);\n\nexport {\n getPublicTokensForChain,\n getPrivateTokensForChain,\n} from '../chains';\n\nexport const MINIMUM_PORTAL_IN_AMOUNTS: Record<string, string> = {\n 'WBTC': '0.0000145',\n 'WETH': '0.000497',\n 'WADA': '4',\n 'COTI': '82',\n 'gCOTI': '390',\n 'USDT': '1',\n 'USDC.e': '1'\n};\n\nexport const ERC20_ABI = [\n \"function balanceOf(address owner) view returns (uint256)\",\n \"function allowance(address owner, address spender) view returns (uint256)\",\n \"function approve(address spender, uint256 value) returns (bool)\",\n \"function transfer(address to, uint256 value) returns (bool)\",\n \"function transferFrom(address from, address to, uint256 value) returns (bool)\",\n \"function decimals() view returns (uint8)\",\n \"function symbol() view returns (string)\",\n \"function name() view returns (string)\",\n] as const;\n\nexport { TOKEN_ABI, BRIDGE_ERC20_ABI, BRIDGE_ABI, COTI_PRICE_CONSUMER_ABI } from './abis';\n","export const TOKEN_ABI = [{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct ctUint256\",\"name\":\"ownerValue\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct ctUint256\",\"name\":\"spenderValue\",\"type\":\"tuple\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct ctUint256\",\"name\":\"senderValue\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct ctUint256\",\"name\":\"receiverValue\",\"type\":\"tuple\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"gtUint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferFromGT\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"gtUint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferGT\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"accountEncryptionAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isSpender\",\"type\":\"bool\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"gtUint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ownerCiphertext\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"spenderCiphertext\",\"type\":\"tuple\"}],\"internalType\":\"struct IPrivateERC20.Allowance\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"value\",\"type\":\"tuple\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"gtUint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approveGT\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"gtUint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"amount\",\"type\":\"tuple\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"gtUint256\",\"name\":\"gtAmount\",\"type\":\"uint256\"}],\"name\":\"burnGt\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"amount\",\"type\":\"tuple\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"gtUint256\",\"name\":\"gtAmount\",\"type\":\"uint256\"}],\"name\":\"mintGt\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isSpender\",\"type\":\"bool\"}],\"name\":\"reencryptAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offBoardAddress\",\"type\":\"address\"}],\"name\":\"setAccountEncryptionAddress\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"value\",\"type\":\"tuple\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"amount\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"transferAndCall\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"ctUint128\",\"name\":\"ciphertextHigh\",\"type\":\"uint256\"},{\"internalType\":\"ctUint128\",\"name\":\"ciphertextLow\",\"type\":\"uint256\"}],\"internalType\":\"struct ctUint256\",\"name\":\"ciphertext\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct itUint256\",\"name\":\"value\",\"type\":\"tuple\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"gtBool\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}];\n\nexport const BRIDGE_ABI = [{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_privateCoti\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_feeRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rescueRecipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressBlacklisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BridgePaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositBelowMinimum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositDisabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsRescueableAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeRecipientNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAccumulatedFees\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientCotiFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeeConfiguration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLimitConfiguration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeCotiFeeNotApplicable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"OracleTimestampMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawBelowMinimum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawFeesMustBeOverridden\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"Blacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CotiFeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"grossAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"netAmount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"DepositEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"feeType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fixedFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"percentageBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"DynamicFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"feeType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newFeeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"FeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minDeposit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxDeposit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minWithdraw\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"name\":\"LimitsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"NativeCotiFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeRescued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"OperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"OperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOracle\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"PriceOracleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"UnBlacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"grossAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"netAmount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FEE_DIVISOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_FEE_UNITS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPERATOR_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accumulatedCotiFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accumulatedFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addToBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"blacklisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cotiAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"computeCotiFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cotiOracleTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenOracleTimestamp\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositFeeBasisPoints\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositMaxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositPercentageBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cotiAmount\",\"type\":\"uint256\"}],\"name\":\"estimateDepositFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"cotiAmount\",\"type\":\"uint256\"}],\"name\":\"estimateWithdrawFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBridgeBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isDepositEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxWithdrawAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minWithdrawAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeCotiFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"priceOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"privateCoti\",\"outputs\":[{\"internalType\":\"contract PrivateCOTI\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"removeFromBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"removeOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rescueRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"setDepositDynamicFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_feeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"setDepositFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_enabled\",\"type\":\"bool\"}],\"name\":\"setIsDepositEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minWithdraw\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxWithdraw\",\"type\":\"uint256\"}],\"name\":\"setLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"setNativeCotiFee\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setPriceOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"setWithdrawDynamicFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_feeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"setWithdrawFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalUserLiability\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiOracleTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenOracleTimestamp\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawCotiFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeBasisPoints\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawMaxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawPercentageBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}] as const;\n\nexport const BRIDGE_ERC20_ABI = [{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_privateWeth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_feeRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rescueRecipient\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressBlacklisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountTooSmall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BridgePaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotRescueBridgeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DecimalsMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositBelowMinimum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositDisabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DepositExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EthTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeRecipientNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientAccumulatedFees\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBridgeLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientCotiFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientEthBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeeConfiguration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLimitConfiguration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPrivateTokenAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidScalingFactor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NativeFeeRequiredForTransferAndCallWithdraw\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"OracleTimestampMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawBelowMinimum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawExceedsMaximum\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawFeesMustBeOverridden\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"Blacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CotiFeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"grossAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"netAmount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"DepositEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"feeType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fixedFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"percentageBps\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"DynamicFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ERC20Rescued\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"feeType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newFeeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"FeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minDeposit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxDeposit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minWithdraw\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxWithdraw\",\"type\":\"uint256\"}],\"name\":\"LimitsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"NativeCotiFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"OperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"OperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOracle\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"PriceOracleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"}],\"name\":\"UnBlacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"grossAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"netAmount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FEE_DIVISOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_FEE_UNITS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPERATOR_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accumulatedCotiFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accumulatedFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"addToBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"blacklisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"_tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"computeErc20Fee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiOracleTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenOracleTimestamp\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositFeeBasisPoints\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositMaxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositPercentageBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenAmount\",\"type\":\"uint256\"}],\"name\":\"estimateDepositFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenAmount\",\"type\":\"uint256\"}],\"name\":\"estimateWithdrawFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenLastUpdated\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isDepositEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxWithdrawAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minWithdrawAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeCotiFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"priceOracle\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"privateToken\",\"outputs\":[{\"internalType\":\"contract IPrivateERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"removeFromBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"removeOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"rescueERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rescueRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"setDepositDynamicFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_feeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"setDepositFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_enabled\",\"type\":\"bool\"}],\"name\":\"setIsDepositEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minWithdraw\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxWithdraw\",\"type\":\"uint256\"}],\"name\":\"setLimits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setNativeCotiFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setPriceOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fixedFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_percentageBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"setWithdrawDynamicFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_feeBasisPoints\",\"type\":\"uint256\"}],\"name\":\"setWithdrawFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokenSymbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalUserLiability\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"cotiOracleTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenOracleTimestamp\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawCotiFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFeeBasisPoints\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFixedFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawMaxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawPercentageBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}] as const;\n\nexport const BRIDGE_NATIVE_ABI = BRIDGE_ABI;\n\nexport const COTI_PRICE_CONSUMER_ABI = [\n { \"inputs\": [{ \"internalType\": \"address\", \"name\": \"_ref\", \"type\": \"address\" }, { \"internalType\": \"uint256\", \"name\": \"_maxStaleness\", \"type\": \"uint256\" }], \"stateMutability\": \"nonpayable\", \"type\": \"constructor\" },\n { \"inputs\": [{ \"internalType\": \"uint256\", \"name\": \"lastUpdated\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"threshold\", \"type\": \"uint256\" }], \"name\": \"StaleOracleData\", \"type\": \"error\" },\n { \"inputs\": [{ \"internalType\": \"uint256\", \"name\": \"provided\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"minimum\", \"type\": \"uint256\" }], \"name\": \"StalenessTooLow\", \"type\": \"error\" },\n { \"anonymous\": false, \"inputs\": [{ \"indexed\": false, \"internalType\": \"uint256\", \"name\": \"oldValue\", \"type\": \"uint256\" }, { \"indexed\": false, \"internalType\": \"uint256\", \"name\": \"newValue\", \"type\": \"uint256\" }], \"name\": \"MaxStalenessUpdated\", \"type\": \"event\" },\n { \"inputs\": [], \"name\": \"MIN_STALENESS\", \"outputs\": [{ \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [{ \"internalType\": \"string\", \"name\": \"_base\", \"type\": \"string\" }], \"name\": \"getPrice\", \"outputs\": [{ \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [{ \"internalType\": \"string\", \"name\": \"_base\", \"type\": \"string\" }], \"name\": \"getPriceData\", \"outputs\": [{ \"components\": [{ \"internalType\": \"uint256\", \"name\": \"rate\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"lastUpdatedBase\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"lastUpdatedQuote\", \"type\": \"uint256\" }], \"internalType\": \"struct IStdReference.ReferenceData\", \"name\": \"\", \"type\": \"tuple\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [{ \"internalType\": \"string\", \"name\": \"_base\", \"type\": \"string\" }], \"name\": \"getPriceWithMeta\", \"outputs\": [{ \"internalType\": \"uint256\", \"name\": \"rate\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"lastUpdated\", \"type\": \"uint256\" }, { \"internalType\": \"uint256\", \"name\": \"blockTimestamp\", \"type\": \"uint256\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [], \"name\": \"maxStaleness\", \"outputs\": [{ \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [], \"name\": \"owner\", \"outputs\": [{ \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [], \"name\": \"ref\", \"outputs\": [{ \"internalType\": \"contract IStdReference\", \"name\": \"\", \"type\": \"address\" }], \"stateMutability\": \"view\", \"type\": \"function\" },\n { \"inputs\": [{ \"internalType\": \"uint256\", \"name\": \"_maxStaleness\", \"type\": \"uint256\" }], \"name\": \"setMaxStaleness\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }\n] as const;\n","import { ethers } from \"ethers\";\nimport { CONTRACT_ADDRESSES } from \"../../contracts/config\";\nimport { estimateCotiBridgeGasFeeDisplay } from \"../cotiBridgeGasEstimate\";\nimport { estimateBridgeFee } from \"../../hooks/useEstimateBridgeFees\";\nimport { getPublicTokensForChain, getRpcUrlForChain } from \"../index\";\nimport { resolveConfiguredAddress } from \"../portal/helpers\";\nimport { logger } from \"../../lib/logger\";\n\nexport type CotiBridgeFeeQuote = {\n portalFeeCoti: string | null;\n estimatedGasFee: string | null;\n feeDebugInfo: {\n cotiLastUpdated: string;\n tokenLastUpdated: string;\n blockTimestamp: string;\n } | null;\n};\n\nconst resolveBridgeAddress = (\n chainId: number,\n symbol: string,\n pubTok: ReturnType<typeof getPublicTokensForChain>[number] | undefined,\n): string | undefined => {\n const addresses = CONTRACT_ADDRESSES[chainId];\n if (!addresses) return undefined;\n\n const bridgeAddress = resolveConfiguredAddress(addresses, pubTok?.bridgeAddressKey);\n if (bridgeAddress) return bridgeAddress;\n\n if (symbol === \"WETH\") return addresses.PrivacyBridgeWETH;\n if (symbol === \"WBTC\") return addresses.PrivacyBridgeWBTC;\n if (symbol === \"USDT\") return addresses.PrivacyBridgeUSDT;\n if (symbol === \"USDC.e\") return addresses.PrivacyBridgeUSDCe;\n if (symbol === \"WADA\") return addresses.PrivacyBridgeWADA;\n if (symbol === \"gCOTI\") return addresses.PrivacyBridgegCOTI;\n return addresses.PrivacyBridgeCotiNative;\n};\n\n/** COTI bridge portal + gas fee quotes (isolated from PoD). */\nexport const quoteCotiBridgeFees = async (params: {\n chainId: number;\n symbol: string;\n direction: \"to-private\" | \"to-public\";\n amount: string;\n walletAddress?: string;\n}): Promise<CotiBridgeFeeQuote> => {\n const { chainId, symbol, direction, amount, walletAddress } = params;\n const currentAmount = amount && parseFloat(amount) > 0 ? amount : \"0\";\n if (currentAmount === \"0\") {\n return { portalFeeCoti: null, estimatedGasFee: null, feeDebugInfo: null };\n }\n\n const rpcUrl = getRpcUrlForChain(chainId);\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl, chainId);\n const pubTok = getPublicTokensForChain(chainId).find(\n t => t.symbol === symbol && !t.isPrivate,\n );\n const bridgeAddress = resolveBridgeAddress(chainId, symbol, pubTok);\n if (!bridgeAddress) {\n return { portalFeeCoti: null, estimatedGasFee: null, feeDebugInfo: null };\n }\n\n const isWeth = symbol === \"WETH\";\n const isWbtc = symbol === \"WBTC\";\n const isUsdt = symbol === \"USDT\";\n const isUsdcE = symbol === \"USDC.e\";\n const isWada = symbol === \"WADA\";\n const isGCoti = symbol === \"gCOTI\";\n const isNight = symbol === \"NIGHT\";\n const isErc20Token = isWeth || isWbtc || isUsdt || isUsdcE || isWada || isGCoti || isNight;\n\n let publicDecimals = pubTok?.decimals ?? 18;\n let privateDecimals = pubTok?.decimals ?? 18;\n if (!pubTok) {\n if (isWbtc) { publicDecimals = 8; privateDecimals = 8; }\n else if (isUsdt || isUsdcE || isWada) { publicDecimals = 6; privateDecimals = 6; }\n }\n\n const decimals = direction === \"to-private\" ? publicDecimals : privateDecimals;\n const amountWei = ethers.parseUnits(\"1\", decimals);\n\n let gasPrice = 1_000_000_000n;\n try {\n const gasPriceHex = await rpcProvider.send(\"eth_gasPrice\", []);\n gasPrice = BigInt(gasPriceHex);\n } catch {\n logger.warn(\"eth_gasPrice failed, using default (1 Gwei).\");\n }\n\n const [feeEstimate, gasDisplay] = await Promise.all([\n estimateBridgeFee(symbol, currentAmount, rpcProvider),\n estimateCotiBridgeGasFeeDisplay({\n provider: rpcProvider as unknown as ethers.BrowserProvider,\n currentChainId: chainId,\n bridgeAddress,\n symbol,\n direction,\n amountWei,\n gasPrice,\n isErc20Token,\n fromAddress: walletAddress,\n }),\n ]);\n\n const fee = direction === \"to-private\" ? feeEstimate.depositFee : feeEstimate.withdrawFee;\n if (fee === \"Error\") {\n return { portalFeeCoti: null, estimatedGasFee: gasDisplay, feeDebugInfo: null };\n }\n\n const display = fee.replace(/\\.?0+$/, \"\") || \"0\";\n return {\n portalFeeCoti: display === \"0\" ? null : display,\n estimatedGasFee: gasDisplay,\n feeDebugInfo: {\n cotiLastUpdated: feeEstimate.cotiLastUpdated,\n tokenLastUpdated: feeEstimate.tokenLastUpdated,\n blockTimestamp: feeEstimate.blockTimestamp,\n },\n };\n};\n","import { getChainConfig, getPublicTokensForChain } from \"../index\";\nimport type { TokenConfig } from \"../types\";\n\n/** Treat blank config entries as unset (factory placeholders are often `\"\"`). */\nexport function resolveConfiguredAddress(\n addresses: Record<string, string> | undefined,\n key: string | undefined,\n): string | undefined {\n if (!addresses || !key) return undefined;\n const value = addresses[key]?.trim();\n return value || undefined;\n}\n\n/** PoD Privacy Portal public token (not the legacy COTI bridge). */\nexport function isPodPortalPublicToken(\n chainId: number,\n token: TokenConfig | undefined,\n): boolean {\n if (!token || token.isPrivate) return false;\n if (getChainConfig(chainId)?.portalStrategy !== \"pod-privacy-portal\") return false;\n return !!token.bridgeAddressKey?.startsWith(\"PrivacyPortal\");\n}\n\n/** Show chain native balance even though config stores the wrapped ERC-20 address. */\nexport function usesNativePublicBalance(token: TokenConfig): boolean {\n return !!token.isNative;\n}\n\n/** Portal In skips ERC-20 approve for native deposits (and legacy native COTI). */\nexport function skipsPublicDepositApproval(\n token: TokenConfig | undefined,\n direction: \"to-private\" | \"to-public\",\n): boolean {\n if (direction !== \"to-private\" || !token) return false;\n if (token.isNative) return true;\n return token.symbol === \"COTI\" && !token.addressKey;\n}\n\nexport function findPublicTokenConfig(\n chainId: number,\n symbol: string,\n): TokenConfig | undefined {\n return getPublicTokensForChain(chainId).find(t => t.symbol === symbol && !t.isPrivate);\n}\n\nexport function resolvePodPortalAddresses(params: {\n addresses: Record<string, string>;\n pubCfg: TokenConfig;\n privCfg: TokenConfig | undefined;\n}) {\n const { addresses, pubCfg, privCfg } = params;\n const portalAddress = resolveConfiguredAddress(addresses, pubCfg.bridgeAddressKey);\n const underlyingAddress = resolveConfiguredAddress(addresses, pubCfg.addressKey);\n const pTokenAddress = privCfg?.addressKey\n ? resolveConfiguredAddress(addresses, privCfg.addressKey)\n : undefined;\n if (!portalAddress || !underlyingAddress || !pTokenAddress) return null;\n return { portalAddress, underlyingAddress, pTokenAddress };\n}\n\nexport function podPortalNotConfiguredError(chainId: number, symbol: string): string {\n const chainName = getChainConfig(chainId)?.name ?? \"this network\";\n return `PoD portal is not configured for ${symbol} on ${chainName}. Deploy the portal and set PrivacyPortal* / p.* addresses in chain config.`;\n}\n","import { ethers } from \"ethers\";\nimport { PodRequest, type RequestTrackingResponse } from \"@coti-io/pod-sdk\";\nimport { getPrivateTokensForChain, getPublicTokensForChain, getNetworkNameForChain, getRpcUrlForChain } from \"../index\";\nimport { CONTRACT_ADDRESSES } from \"../../contracts/config\";\nimport { POD_PTOKEN_ABI, PRIVACY_PORTAL_ABI, type PodPortalRequest } from \"../../contracts/pod\";\nimport { getPodSdkConfig } from \"./podSdkConfig\";\nimport {\n logPodTrackingDiagnostics,\n type PodStatusResolution,\n} from \"./podRequestTrackingDiagnostics\";\nimport { logger } from \"../../lib/logger\";\n\nconst hasPodExecutionError = (execution: RequestTrackingResponse[\"execution\"]) => {\n if (!execution) return false;\n const errorCode = execution.errorCode;\n if (errorCode === undefined || errorCode === null) return false;\n return BigInt(errorCode) !== 0n;\n};\n\nconst getFailedRequestHex = async (\n provider: ethers.Provider,\n request: PodPortalRequest,\n pTokenAddress: string,\n) => {\n if (!request.requestId) {\n /* v8 ignore next -- unreachable: resolvePodRequestStatus guards requestId before calling */\n return \"0x\";\n }\n const pToken = new ethers.Contract(pTokenAddress, POD_PTOKEN_ABI, provider);\n const failedRaw = await pToken.failedRequests(request.requestId).catch(() => \"0x\");\n return typeof failedRaw === \"string\" ? failedRaw : ethers.hexlify(failedRaw);\n};\n\nexport async function resolvePodRequestStatus(request: PodPortalRequest) {\n if (!request.requestId) {\n logger.warn(\n `[PoD][resolveStatus] Missing requestId for tx ${request.sourceTxHash}. ` +\n \"PoD cannot be tracked — DepositRequested event may not have been parsed.\",\n );\n return {\n status: \"source-mined\" as const,\n message: \"PoD request ID not found. Cannot track progress.\",\n refreshPrivateBalances: false,\n };\n }\n\n const chainId = request.chainId;\n const addresses = CONTRACT_ADDRESSES[chainId];\n if (!addresses) return null;\n\n const rpcUrl = getRpcUrlForChain(chainId);\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const sym = request.token.replace(/^p\\./, \"\");\n const pubCfg = getPublicTokensForChain(chainId).find(t => t.symbol === sym && !t.isPrivate);\n const privCfg =\n getPrivateTokensForChain(chainId).find(t => t.symbol === `p.${sym}`) ??\n getPrivateTokensForChain(chainId).find(t => t.symbol === request.token);\n const portalKey = pubCfg?.bridgeAddressKey ?? privCfg?.bridgeAddressKey;\n const pTokenAddress = privCfg?.addressKey ? addresses[privCfg.addressKey] : undefined;\n const portalAddress = portalKey ? addresses[portalKey] : undefined;\n if (!pTokenAddress || !portalAddress) {\n logger.warn(\"[PoD][resolveStatus] Could not resolve portal/pToken for request\", {\n chainId,\n token: request.token,\n requestId: request.requestId,\n portalKey,\n pTokenAddress,\n portalAddress,\n });\n return null;\n }\n\n const sourceChainName = getNetworkNameForChain(chainId);\n\n const failedHex = await getFailedRequestHex(provider, request, pTokenAddress);\n if (failedHex !== \"0x\") {\n return {\n status: \"callback-errored\" as const,\n message: \"PoD callback failed. Balance is untrusted until the callback is replayed.\",\n refreshPrivateBalances: false,\n };\n }\n\n const sdkConfig = getPodSdkConfig();\n let tracking: RequestTrackingResponse;\n try {\n const tracker = new PodRequest(sdkConfig);\n tracking = await tracker.trackRequest(chainId, request.requestId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(\"[PoD][trackRequest] SDK trackRequest failed\", {\n sourceTxHash: request.sourceTxHash,\n requestId: request.requestId,\n chainId,\n message,\n sdkConfig: sdkConfig.chains.map(c => ({\n chainId: c.chainId,\n inboxAddress: c.inboxAddress,\n rpcUrl: c.rpcUrl,\n })),\n });\n throw error;\n }\n\n let resolution: PodStatusResolution = \"no-change\";\n let result: {\n status: PodPortalRequest[\"status\"];\n message: string;\n refreshPrivateBalances: boolean;\n } | null = null;\n\n if (hasPodExecutionError(tracking.execution)) {\n resolution = \"failed\";\n result = {\n status: \"failed\",\n message: tracking.execution?.errorMessage || \"PoD request execution failed.\",\n refreshPrivateBalances: false,\n };\n } else if (request.kind === \"deposit\" && tracking.response?.minedOnTarget) {\n resolution = \"succeeded\";\n result = {\n status: \"succeeded\",\n message: `PoD mint callback completed on ${sourceChainName}.`,\n refreshPrivateBalances: true,\n };\n } else if (request.kind === \"withdraw\" && request.withdrawalId) {\n const iface = new ethers.Interface(PRIVACY_PORTAL_ABI);\n const latest = await provider.getBlockNumber();\n const fromBlock = request.fromBlock ?? Math.max(0, latest - 20_000);\n const logs = await provider.getLogs({\n address: portalAddress,\n fromBlock,\n toBlock: latest,\n topics: [iface.getEvent(\"WithdrawalReleased\")!.topicHash, request.withdrawalId],\n });\n if (logs.length > 0) {\n resolution = \"succeeded\";\n result = {\n status: \"succeeded\",\n message: `Withdraw released on ${sourceChainName}.`,\n refreshPrivateBalances: true,\n };\n }\n }\n\n if (!result && tracking.response) {\n resolution = \"callback-generated\";\n result = {\n status: \"callback-generated\",\n message: `PoD callback was generated and is waiting to complete on ${sourceChainName}.`,\n refreshPrivateBalances: false,\n };\n }\n\n if (!result && tracking.minedOnTarget) {\n resolution = \"target-mined\";\n result = {\n status: \"target-mined\",\n message: \"PoD request was mined on COTI and is waiting for callback generation.\",\n refreshPrivateBalances: false,\n };\n }\n\n if (\n !result &&\n (request.status === \"source-mined\" || request.status === \"pod-pending\")\n ) {\n resolution = \"pod-pending\";\n result = {\n status: \"pod-pending\",\n message: \"PoD request submitted. Waiting to be indexed and processed.\",\n refreshPrivateBalances: false,\n };\n }\n\n logPodTrackingDiagnostics({\n request,\n tracking,\n sdkConfig,\n resolution,\n resolvedMessage: result?.message,\n failedHex,\n });\n\n return result;\n}\n","import type { RequestTrackingResponse } from \"@coti-io/pod-sdk\";\nimport type { PodSdkConfig } from \"@coti-io/pod-sdk\";\nimport { buildPodExplorerRequestUrl, type PodPortalRequest } from \"../../contracts/pod\";\nimport { logger } from \"../../lib/logger\";\n\nexport type PodStatusResolution =\n | \"callback-errored\"\n | \"failed\"\n | \"succeeded\"\n | \"callback-generated\"\n | \"target-mined\"\n | \"pod-pending\"\n | \"source-mined-no-id\"\n | \"no-change\";\n\nexport type SerializedTracking = {\n requestId: string;\n sourceChainId: string;\n targetChainId: string;\n timestamp: string;\n minedOnTarget: boolean;\n isTwoWay: boolean;\n localGasLimit: string;\n remoteGasLimit: string;\n execution: {\n errorCode: string;\n errorMessage: string;\n } | null;\n response: SerializedTracking | null;\n};\n\nconst chainIdToExplorerSlug = (chainId: number | bigint | string) => {\n const id = Number(chainId);\n if (id === 11155111) return \"sepolia\";\n if (id === 7082400) return \"coti\";\n if (id === 43113) return \"fuji\";\n return String(id);\n};\n\nexport const serializeTrackingResponse = (\n tracking: RequestTrackingResponse,\n): SerializedTracking => ({\n requestId: tracking.requestId ?? \"unknown\",\n sourceChainId: tracking.sourceChainId != null ? tracking.sourceChainId.toString() : \"unknown\",\n targetChainId: tracking.targetChainId != null ? tracking.targetChainId.toString() : \"unknown\",\n timestamp: tracking.timestamp != null ? tracking.timestamp.toString() : \"unknown\",\n minedOnTarget: Boolean(tracking.minedOnTarget),\n isTwoWay: Boolean(tracking.isTwoWay),\n localGasLimit: tracking.localGasLimit != null ? tracking.localGasLimit.toString() : \"0\",\n remoteGasLimit: tracking.remoteGasLimit != null ? tracking.remoteGasLimit.toString() : \"0\",\n execution:\n tracking.execution?.errorCode != null && tracking.execution.errorCode !== undefined\n ? {\n errorCode: BigInt(tracking.execution.errorCode).toString(),\n errorMessage: tracking.execution.errorMessage ?? \"\",\n }\n : null,\n response: tracking.response ? serializeTrackingResponse(tracking.response) : null,\n});\n\n/** Human-readable explanation of why a request is still in `pod-pending`. */\nexport const explainPodPendingReason = (\n tracking: RequestTrackingResponse,\n kind: PodPortalRequest[\"kind\"],\n): string => {\n if (tracking.execution?.errorCode != null && BigInt(tracking.execution.errorCode) !== 0n) {\n return (\n `PoD target execution failed on chain ${tracking.targetChainId}: ` +\n `${tracking.execution.errorMessage || `error code ${tracking.execution.errorCode}`}.`\n );\n }\n\n if (!tracking.minedOnTarget) {\n const target = tracking.targetChainId != null ? tracking.targetChainId.toString() : \"unknown\";\n return (\n `Sepolia deposit is confirmed and the request exists in the source PoD inbox, but the ` +\n `relayer has not mined it on the target chain yet (targetChainId=${target}, ` +\n `incomingRequests still empty). This step is handled by off-chain PoD infrastructure — ` +\n `the UI cannot advance until the COTI inbox ingests the message.`\n );\n }\n\n if (tracking.isTwoWay && !tracking.response) {\n return (\n `Request was mined on COTI (targetChainId=${tracking.targetChainId}) but the two-way ` +\n `callback response has not been generated yet.`\n );\n }\n\n if (tracking.response && !tracking.response.minedOnTarget) {\n if (kind === \"deposit\") {\n return (\n `Callback was generated on COTI but has not been mined back on Sepolia yet ` +\n `(mint callback pending on source chain).`\n );\n }\n return \"Callback was generated but has not completed on the source chain yet.\";\n }\n\n return \"PoD tracker returned no progress fields; request may still be queued.\";\n};\n\nexport const summarizeSdkConfig = (config: PodSdkConfig) =>\n config.chains.map(chain => ({\n chainId: chain.chainId,\n inboxAddress: chain.inboxAddress,\n rpcUrl: chain.rpcUrl,\n }));\n\nlet loggedSdkConfigSignature = \"\";\n\nexport const logPodTrackingDiagnostics = (params: {\n request: PodPortalRequest;\n tracking: RequestTrackingResponse;\n sdkConfig: PodSdkConfig;\n resolution: PodStatusResolution;\n resolvedMessage?: string;\n failedHex?: string;\n}) => {\n const { request, tracking, sdkConfig, resolution, resolvedMessage, failedHex } = params;\n const serialized = serializeTrackingResponse(tracking);\n const pendingReason =\n resolution === \"pod-pending\" ? explainPodPendingReason(tracking, request.kind) : undefined;\n const explorerUrl = request.requestId\n ? buildPodExplorerRequestUrl(request.requestId, chainIdToExplorerSlug(request.chainId))\n : undefined;\n\n const configSignature = sdkConfig.chains\n .map(c => `${c.chainId}:${c.inboxAddress}`)\n .sort()\n .join(\"|\");\n if (configSignature !== loggedSdkConfigSignature) {\n loggedSdkConfigSignature = configSignature;\n logger.log(\"[PoD][trackRequest] SDK inbox config (logged once per session)\", {\n encryptionNetwork: sdkConfig.encryptionNetwork,\n chains: summarizeSdkConfig(sdkConfig),\n });\n }\n\n logger.log(\"[PoD][trackRequest] status resolution\", {\n sourceTxHash: request.sourceTxHash,\n requestId: request.requestId,\n kind: request.kind,\n token: request.token,\n amount: request.amount,\n previousStatus: request.status,\n resolution,\n resolvedMessage,\n pendingReason,\n explorerUrl,\n failedHex: failedHex && failedHex !== \"0x\" ? failedHex : null,\n tracking: serialized,\n nextExpected:\n resolution === \"pod-pending\" && !tracking.minedOnTarget\n ? \"target-mined (minedOnTarget=true on COTI inbox)\"\n : resolution === \"target-mined\"\n ? \"callback-generated (tracking.response populated)\"\n : resolution === \"callback-generated\"\n ? \"succeeded (tracking.response.minedOnTarget=true on Sepolia)\"\n : undefined,\n });\n};\n","import { ethers } from \"ethers\";\nimport { PRIVACY_PORTAL_ABI, POD_PTOKEN_ABI, SEPOLIA_CHAIN_ID, type PodPortalRequest } from \"../../contracts/pod\";\nimport type { SwapProgressStage } from \"../../hooks/usePrivacyBridge\";\nimport { logger } from \"../../lib/logger\";\nimport {\n diagnoseBlockingPodRequest,\n formatBlockingPodLogSummary,\n summarizeInFlightLocalPodRequests,\n type BlockingPodRequestDiagnostics,\n} from \"./podPTokenBlockingDiagnostics\";\nimport {\n buildPodMethodArgs,\n estimatePodFee,\n resolvePodTxGasPrice,\n quotePortalFeeOnly,\n resolvePodPortalMethod,\n sendPodPortalMethod,\n type PodWithdrawPermit,\n} from \"./podPortalFees\";\n\nexport type { PodWithdrawPermit } from \"./podPortalFees\";\nexport { getPodInboxAddress, getPodSdkConfig, podSdkConfig } from \"./podSdkConfig\";\nexport {\n getPodGasPrice,\n getSepoliaGasPrice,\n resolvePodTxGasPrice,\n quotePortalFeeOnly,\n formatPortalFeeDisplay,\n formatPodFeeDisplay,\n estimatePodFee,\n estimatePodPortalFees,\n} from \"./podPortalFees\";\nexport { quotePodPortalTransactionFees } from \"./fees\";\nexport type { PodPortalFeeQuote } from \"./fees\";\n\nconst getErrorMessage = (error: unknown) =>\n error && typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\"\n ? error.message\n : \"\";\n\nconst pTokenErrorIface = new ethers.Interface(POD_PTOKEN_ABI);\n\nconst extractRevertData = (error: unknown): string | null => {\n if (!error || typeof error !== \"object\") return null;\n const err = error as Record<string, unknown>;\n const candidates = [\n err.data,\n (err.error as Record<string, unknown> | undefined)?.data,\n (err.info as { error?: { data?: unknown } } | undefined)?.error?.data,\n ];\n for (const raw of candidates) {\n if (typeof raw === \"string\" && raw.startsWith(\"0x\")) return raw;\n if (raw && typeof raw === \"object\" && \"data\" in raw) {\n const nested = (raw as { data: unknown }).data;\n if (typeof nested === \"string\" && nested.startsWith(\"0x\")) return nested;\n }\n }\n return null;\n};\n\nconst parseTransferAlreadyPendingRevert = (\n error: unknown,\n): { requestId: string } | null => {\n const revertData = extractRevertData(error);\n if (!revertData?.startsWith(\"0xbd8a45bc\")) return null;\n try {\n const parsed = pTokenErrorIface.parseError(revertData);\n if (parsed?.name !== \"TransferAlreadyPending\") return null;\n const requestId = parsed.args[2];\n return typeof requestId === \"string\" ? { requestId } : null;\n } catch {\n return null;\n }\n};\n\nconst pendingProbeFromRevert = (\n error: unknown,\n source: PodPTokenPendingSource,\n probeErrors: string[],\n): PodPTokenPendingProbe | null => {\n const pendingRevert = parseTransferAlreadyPendingRevert(error);\n if (!pendingRevert) return null;\n return {\n pending: true,\n callbackErrored: false,\n source,\n probeErrors,\n pendingRequestId: pendingRevert.requestId,\n rawResponse: {\n transferAlreadyPending: true,\n requestId: pendingRevert.requestId,\n },\n };\n};\n\nconst findParsedEvent = (receipt: ethers.TransactionReceipt, iface: ethers.Interface, eventName: string) => {\n for (const log of receipt.logs) {\n try {\n const parsed = iface.parseLog({ topics: log.topics as string[], data: log.data });\n if (parsed?.name === eventName) return parsed;\n } catch {\n // Ignore logs from other contracts.\n }\n }\n return null;\n};\n\nconst splitSignature = (signature: string) => {\n const parsed = ethers.Signature.from(signature);\n return { v: parsed.v, r: parsed.r, s: parsed.s };\n};\n\n/** Sepolia ERC-20 pTokens (e.g. p.MTT): flat 2-limb ciphertext + pending flag. */\nconst POD_PTOKEN_FLAT_STATUS_ABI = [\n \"function balanceOfWithStatus(address account) view returns (tuple(uint256 ciphertextHigh, uint256 ciphertextLow),bool)\",\n] as const;\n\n/** Native / WETH-style pTokens expose plain uint256 balances in status helpers. */\nconst POD_PTOKEN_PLAIN_STATUS_ABI = [\n \"function balanceOfWithStatus(address account) view returns (uint256,bool)\",\n] as const;\n\ntype PodPTokenPendingSource =\n | \"balanceWithState\"\n | \"flatBalanceOfWithStatus\"\n | \"balanceOfWithStatus\"\n | \"plainBalanceOfWithStatus\";\n\ntype PodPTokenPendingProbe = {\n pending: boolean;\n callbackErrored: boolean;\n source: PodPTokenPendingSource;\n probeErrors: string[];\n /** Decoded from TransferAlreadyPending when the status view reverts instead of returning. */\n pendingRequestId?: string;\n /** Full contract return value from the successful status probe (JSON-safe). */\n rawResponse?: unknown;\n};\n\nconst serializePodBalanceStatusResponse = (value: unknown): unknown => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n if (Array.isArray(value)) {\n return value.map(serializePodBalanceStatusResponse);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, serializePodBalanceStatusResponse(entry)]),\n );\n }\n return value;\n};\n\ntype EthersContractResult = Record<string | number, unknown>;\n\nconst readContractResultField = (result: EthersContractResult, name: string, index: number): unknown =>\n result[name] ?? result[index];\n\nconst buildBalanceWithStateRaw = (response: EthersContractResult) => ({\n balance: serializePodBalanceStatusResponse(readContractResultField(response, \"balance\", 0)),\n pending: readContractResultField(response, \"pending\", 1),\n callbackErrored: readContractResultField(response, \"callbackErrored\", 2),\n});\n\nconst buildBalanceOfWithStatusRaw = (response: EthersContractResult) => ({\n balance: serializePodBalanceStatusResponse(\n readContractResultField(response, \"balance\", 0) ?? readContractResultField(response, \"0\", 0),\n ),\n pending: readContractResultField(response, \"pending\", 1) ?? readContractResultField(response, \"1\", 1),\n});\n\nconst formatBalanceStatusRawForLog = (source: PodPTokenPendingSource, rawResponse: unknown): string | undefined => {\n if (rawResponse === undefined) return undefined;\n try {\n return JSON.stringify(rawResponse);\n } catch {\n return String(rawResponse);\n }\n};\n\nconst logBalanceStatusRawResponse = (\n level: \"debug\" | \"warn\",\n source: PodPTokenPendingSource,\n rawResponse: unknown,\n) => {\n const formatted = formatBalanceStatusRawForLog(source, rawResponse);\n if (!formatted) return;\n const message = `[PoD][pToken readiness] ${source} raw contract response: ${formatted}`;\n if (level === \"warn\") {\n logger.warn(message);\n return;\n }\n logger.debug(message);\n};\n\ntype PodPTokenReadinessDebugContext = {\n portalAddress?: string;\n tokenSymbol?: string;\n chainId?: number;\n provider?: ethers.Provider | null;\n};\n\nconst getContractProvider = (contract: ethers.Contract): ethers.Provider | null => {\n const runner = contract.runner;\n if (runner && typeof runner === \"object\" && \"provider\" in runner && runner.provider) {\n const provider = runner.provider as ethers.Provider;\n if (typeof provider.getBlockNumber === \"function\" && typeof provider.getLogs === \"function\") {\n return provider;\n }\n }\n return null;\n};\n\nconst logPodPTokenReadinessProbe = async (\n pToken: ethers.Contract,\n account: string,\n pTokenAddress: string,\n action: \"deposit\" | \"withdraw\",\n probe: PodPTokenPendingProbe,\n debugContext?: PodPTokenReadinessDebugContext,\n) => {\n logger.debug(\"[PoD][pToken readiness] on-chain probe\", {\n action,\n account,\n pTokenAddress,\n pending: probe.pending,\n callbackErrored: probe.callbackErrored,\n source: probe.source,\n probeErrors: probe.probeErrors,\n balanceStatusRawResponse: probe.rawResponse,\n ...debugContext,\n inFlightLocalPodRequests: summarizeInFlightLocalPodRequests(account),\n });\n logBalanceStatusRawResponse(\"debug\", probe.source, probe.rawResponse);\n};\n\nconst logPodPTokenReadinessBlocked = async (\n pToken: ethers.Contract,\n account: string,\n pTokenAddress: string,\n action: \"deposit\" | \"withdraw\",\n probe: PodPTokenPendingProbe,\n reason: \"pending\" | \"callback-errored\",\n debugContext?: PodPTokenReadinessDebugContext,\n) => {\n let diagnostics: BlockingPodRequestDiagnostics = {\n blockingRequest: null,\n candidateRequests: [],\n inFlightLocalPodRequests: summarizeInFlightLocalPodRequests(account),\n };\n\n try {\n diagnostics = await diagnoseBlockingPodRequest({\n account,\n pTokenAddress,\n blockedAction: action,\n portalAddress: debugContext?.portalAddress,\n tokenSymbol: debugContext?.tokenSymbol,\n chainId: debugContext?.chainId,\n provider: debugContext?.provider ?? getContractProvider(pToken),\n callbackErrored: reason === \"callback-errored\",\n });\n } catch (error) {\n logger.debug(\"[PoD][pToken readiness] blocking-request diagnostics failed\", {\n action,\n account,\n pTokenAddress,\n error: getErrorMessage(error) || String(error),\n });\n }\n\n const { blockingRequest, candidateRequests, inFlightLocalPodRequests, eventScan } = diagnostics;\n const summary = formatBlockingPodLogSummary(blockingRequest, action);\n\n logger.warn(`[PoD][pToken readiness] ${summary}`);\n logBalanceStatusRawResponse(\"warn\", probe.source, probe.rawResponse);\n logger.warn(\"[PoD][pToken readiness] blocked new request\", {\n reason,\n action,\n account,\n pTokenAddress,\n balanceStatusRawResponse: probe.rawResponse,\n onChain: {\n pending: probe.pending,\n callbackErrored: probe.callbackErrored,\n source: probe.source,\n probeErrors: probe.probeErrors,\n },\n ...debugContext,\n blockingRequest,\n candidateRequests,\n inFlightLocalPodRequests,\n eventScan,\n hint:\n reason === \"pending\"\n ? blockingRequest?.requestId\n ? `Blocked by PoD request ${blockingRequest.requestId}. Wait for it to complete or inspect blockingRequest.explorerUrl.`\n : \"The pToken contract reports an in-flight PoD callback for this wallet. Inspect candidateRequests / inFlightLocalPodRequests.\"\n : blockingRequest?.requestId\n ? `Blocked by failed PoD callback for request ${blockingRequest.requestId}. Replay the callback before trying again.`\n : \"A prior PoD callback failed on-chain; replay the callback before depositing or withdrawing again.\",\n });\n\n return diagnostics;\n};\n\nconst resolveBlockingRequestId = (\n account: string,\n probe: PodPTokenPendingProbe,\n diagnostics: BlockingPodRequestDiagnostics,\n): string | undefined =>\n probe.pendingRequestId\n ?? diagnostics.blockingRequest?.requestId\n ?? summarizeInFlightLocalPodRequests(account).find(entry => entry.requestId)?.requestId;\n\nconst readPodPTokenPendingState = async (\n pToken: ethers.Contract,\n account: string,\n): Promise<PodPTokenPendingProbe> => {\n const probeErrors: string[] = [];\n const pTokenAddress = await pToken.getAddress();\n\n try {\n const response = await pToken.balanceWithState(account);\n const [, pending, callbackErrored] = response;\n return {\n pending: Boolean(pending),\n callbackErrored: Boolean(callbackErrored),\n source: \"balanceWithState\",\n probeErrors,\n rawResponse: buildBalanceWithStateRaw(response as EthersContractResult),\n };\n } catch (error) {\n const pendingFromRevert = pendingProbeFromRevert(error, \"balanceWithState\", probeErrors);\n if (pendingFromRevert) return pendingFromRevert;\n probeErrors.push(`balanceWithState: ${getErrorMessage(error) || String(error)}`);\n }\n\n const flatStatusToken = new ethers.Contract(\n pTokenAddress,\n POD_PTOKEN_FLAT_STATUS_ABI,\n pToken.runner as ethers.ContractRunner,\n );\n try {\n const response = await flatStatusToken.balanceOfWithStatus(account);\n const pending = readContractResultField(response as EthersContractResult, \"pending\", 1);\n return {\n pending: Boolean(pending),\n callbackErrored: false,\n source: \"flatBalanceOfWithStatus\",\n probeErrors,\n rawResponse: buildBalanceOfWithStatusRaw(response as EthersContractResult),\n };\n } catch (error) {\n const pendingFromRevert = pendingProbeFromRevert(error, \"flatBalanceOfWithStatus\", probeErrors);\n if (pendingFromRevert) return pendingFromRevert;\n probeErrors.push(`flatBalanceOfWithStatus: ${getErrorMessage(error) || String(error)}`);\n }\n\n try {\n const response = await pToken.balanceOfWithStatus(account);\n const pending = readContractResultField(response as EthersContractResult, \"pending\", 1);\n return {\n pending: Boolean(pending),\n callbackErrored: false,\n source: \"balanceOfWithStatus\",\n probeErrors,\n rawResponse: buildBalanceOfWithStatusRaw(response as EthersContractResult),\n };\n } catch (error) {\n const pendingFromRevert = pendingProbeFromRevert(error, \"balanceOfWithStatus\", probeErrors);\n if (pendingFromRevert) return pendingFromRevert;\n probeErrors.push(`balanceOfWithStatus: ${getErrorMessage(error) || String(error)}`);\n }\n\n const plainToken = new ethers.Contract(\n pTokenAddress,\n POD_PTOKEN_PLAIN_STATUS_ABI,\n pToken.runner as ethers.ContractRunner,\n );\n try {\n const response = await plainToken.balanceOfWithStatus(account);\n const pending = readContractResultField(response as EthersContractResult, \"pending\", 1);\n return {\n pending: Boolean(pending),\n callbackErrored: false,\n source: \"plainBalanceOfWithStatus\",\n probeErrors,\n rawResponse: buildBalanceOfWithStatusRaw(response as EthersContractResult),\n };\n } catch (error) {\n const pendingFromRevert = pendingProbeFromRevert(error, \"plainBalanceOfWithStatus\", probeErrors);\n if (pendingFromRevert) return pendingFromRevert;\n throw error;\n }\n};\n\nconst assertPodPTokenReady = async (\n pToken: ethers.Contract,\n account: string,\n action: \"deposit\" | \"withdraw\",\n debugContext?: PodPTokenReadinessDebugContext,\n) => {\n const pTokenAddress = await pToken.getAddress();\n let probe: PodPTokenPendingProbe;\n\n try {\n probe = await readPodPTokenPendingState(pToken, account);\n } catch (stateError: unknown) {\n const message = getErrorMessage(stateError);\n logger.warn(\"[PoD][pToken readiness] could not verify on-chain state\", {\n action,\n account,\n pTokenAddress,\n ...debugContext,\n error: message || String(stateError),\n inFlightLocalPodRequests: summarizeInFlightLocalPodRequests(account),\n });\n throw Object.assign(\n new Error(\"Could not verify the pToken request state. Please refresh and try again.\"),\n { cause: stateError },\n );\n }\n\n await logPodPTokenReadinessProbe(pToken, account, pTokenAddress, action, probe, debugContext);\n\n if (probe.callbackErrored) {\n const diagnostics = await logPodPTokenReadinessBlocked(pToken, account, pTokenAddress, action, probe, \"callback-errored\", debugContext);\n const blockingRequestId = resolveBlockingRequestId(account, probe, diagnostics);\n throw new Error(\n blockingRequestId\n ? `This pToken balance is untrusted because PoD callback failed for request ${blockingRequestId}. Replay the callback before using this token.`\n : \"This pToken balance is untrusted because a previous PoD callback failed. Replay the callback before using this token.\",\n );\n }\n\n if (probe.pending) {\n const diagnostics = await logPodPTokenReadinessBlocked(pToken, account, pTokenAddress, action, probe, \"pending\", debugContext);\n const blockingRequestId = resolveBlockingRequestId(account, probe, diagnostics);\n throw new Error(\n blockingRequestId\n ? `A PoD request is already pending for this wallet (request ${blockingRequestId}). Wait for it to complete before starting another ${action}.`\n : `A PoD request is already pending for this wallet. Wait for it to complete before starting another ${action}.`,\n );\n }\n};\n\nexport async function signPodWithdrawPermit(params: {\n signer: ethers.JsonRpcSigner;\n pTokenAddress: string;\n portalAddress: string;\n amountWei: bigint;\n deadline?: bigint;\n chainId?: number;\n tokenSymbol?: string;\n}): Promise<PodWithdrawPermit> {\n const { signer, pTokenAddress, portalAddress, amountWei } = params;\n const wallet = await signer.getAddress();\n const pToken = new ethers.Contract(pTokenAddress, POD_PTOKEN_ABI, signer);\n const signingChainId = params.chainId ?? Number((await signer.provider!.getNetwork()).chainId);\n const resolvedTokenSymbol = params.tokenSymbol ?? await pToken.symbol().catch(() => undefined);\n\n await assertPodPTokenReady(pToken, wallet, \"withdraw\", {\n portalAddress,\n chainId: signingChainId,\n tokenSymbol: resolvedTokenSymbol,\n provider: signer.provider ?? null,\n });\n\n const name = await pToken.name();\n const nonce = await pToken.nonces(wallet);\n const deadline = params.deadline ?? BigInt(Math.floor(Date.now() / 1000) + 60 * 30);\n const signature = await signer.signTypedData(\n {\n name,\n version: \"1\",\n chainId: signingChainId,\n verifyingContract: pTokenAddress,\n },\n {\n TransferPermit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n },\n {\n owner: wallet,\n spender: portalAddress,\n to: portalAddress,\n value: amountWei,\n nonce,\n deadline,\n },\n );\n const { v, r, s } = splitSignature(signature);\n\n return {\n wallet,\n pTokenAddress,\n portalAddress,\n amountWei: amountWei.toString(),\n deadline: deadline.toString(),\n v,\n r,\n s,\n };\n}\n\nexport async function executePodPortalTransaction(params: {\n txAmount: string;\n txDirection: \"to-private\" | \"to-public\";\n signer: ethers.JsonRpcSigner;\n provider: ethers.BrowserProvider;\n portalAddress: string;\n underlyingAddress: string;\n pTokenAddress: string;\n tokenSymbol: string;\n decimals: number;\n chainId?: number;\n isNativeDeposit?: boolean;\n withdrawPermit?: PodWithdrawPermit;\n onProgress?: (stage: SwapProgressStage, txHash?: string) => void;\n}): Promise<{ txHash: string; request: PodPortalRequest; receipt: ethers.TransactionReceipt }> {\n const {\n txAmount,\n txDirection,\n signer,\n provider,\n portalAddress,\n underlyingAddress,\n pTokenAddress,\n tokenSymbol,\n decimals,\n chainId = SEPOLIA_CHAIN_ID,\n isNativeDeposit = false,\n withdrawPermit,\n onProgress,\n } = params;\n\n if (!portalAddress || !underlyingAddress || !pTokenAddress) {\n throw new Error(\"PoD portal is not configured for this token\");\n }\n\n const wallet = await signer.getAddress();\n const amountWei = ethers.parseUnits(txAmount, decimals);\n const pToken = new ethers.Contract(pTokenAddress, POD_PTOKEN_ABI, signer);\n const portalIface = new ethers.Interface(PRIVACY_PORTAL_ABI);\n const gasPrice = await resolvePodTxGasPrice(provider);\n\n if (txDirection === \"to-private\") {\n await assertPodPTokenReady(pToken, wallet, \"deposit\", {\n portalAddress,\n tokenSymbol,\n chainId,\n provider: provider ?? signer.provider ?? null,\n });\n\n const method = resolvePodPortalMethod(\"to-private\", isNativeDeposit);\n const portalQuote = await quotePortalFeeOnly(signer, portalAddress, amountWei, \"to-private\", gasPrice);\n const podArgs = buildPodMethodArgs({\n direction: \"to-private\",\n wallet,\n amountWei,\n portalFee: portalQuote.portalFee,\n isNativeDeposit,\n });\n const podFee = await estimatePodFee({\n runner: signer,\n portalAddress,\n chainId,\n direction: \"to-private\",\n method,\n args: podArgs,\n gasPrice,\n });\n\n let gasLimit: bigint | undefined;\n try {\n const portal = new ethers.Contract(portalAddress, PRIVACY_PORTAL_ABI, signer);\n const nativeAmount = isNativeDeposit ? amountWei : 0n;\n const estimated = await portal[method].estimateGas(\n wallet,\n amountWei,\n portalQuote.portalFee,\n podFee.callBackFee,\n { value: nativeAmount + portalQuote.portalFee + podFee.totalFee, gasPrice },\n );\n gasLimit = (estimated * 130n) / 100n;\n } catch (estErr: unknown) {\n logger.warn(\n `⚠️ PoD ${method} gas estimation reverted — broadcasting with fallback gas limit so the revert is inspectable on-chain`,\n (estErr as Error)?.message,\n );\n gasLimit = 2_000_000n;\n }\n\n const tx = await sendPodPortalMethod({\n runner: signer,\n portalAddress,\n chainId,\n direction: \"to-private\",\n method,\n args: podArgs,\n gasPrice,\n portalFee: portalQuote.portalFee,\n amountWei,\n isNativeDeposit,\n gasLimit,\n fee: podFee,\n });\n\n onProgress?.(\"transfer-start\", tx.hash);\n\n const receipt = await tx.wait();\n if (!receipt || receipt.status !== 1) {\n const failed = new Error(\"PoD deposit transaction failed\") as Error & { txHash?: string };\n failed.txHash = tx.hash;\n throw failed;\n }\n\n const event = findParsedEvent(receipt, portalIface, \"DepositRequested\");\n const requestId = event?.args?.mintRequestId as string | undefined;\n\n return {\n txHash: tx.hash,\n receipt,\n request: {\n id: tx.hash,\n kind: \"deposit\",\n chainId,\n sourceTxHash: tx.hash,\n requestId,\n wallet,\n token: tokenSymbol,\n amount: txAmount,\n status: \"source-mined\",\n message: requestId ? \"PoD mint request submitted.\" : \"Source transaction mined; request id not found.\",\n createdAt: Date.now(),\n updatedAt: Date.now(),\n fromBlock: receipt.blockNumber,\n },\n };\n }\n\n await assertPodPTokenReady(pToken, wallet, \"withdraw\", {\n portalAddress,\n tokenSymbol,\n chainId,\n provider: provider ?? signer.provider ?? null,\n });\n\n if (\n !withdrawPermit ||\n withdrawPermit.wallet.toLowerCase() !== wallet.toLowerCase() ||\n withdrawPermit.pTokenAddress.toLowerCase() !== pTokenAddress.toLowerCase() ||\n withdrawPermit.portalAddress.toLowerCase() !== portalAddress.toLowerCase() ||\n withdrawPermit.amountWei !== amountWei.toString()\n ) {\n throw new Error(\"PoD withdraw approval signature is missing or stale. Please approve again.\");\n }\n\n const method = resolvePodPortalMethod(\"to-public\", false);\n const portalQuote = await quotePortalFeeOnly(signer, portalAddress, amountWei, \"to-public\", gasPrice);\n const podArgs = buildPodMethodArgs({\n direction: \"to-public\",\n wallet,\n amountWei,\n portalFee: portalQuote.portalFee,\n withdrawPermit,\n });\n const podFee = await estimatePodFee({\n runner: signer,\n portalAddress,\n chainId,\n direction: \"to-public\",\n method,\n args: podArgs,\n gasPrice,\n });\n\n let gasLimit: bigint | undefined;\n try {\n const portal = new ethers.Contract(portalAddress, PRIVACY_PORTAL_ABI, signer);\n // transferFee must equal msg.value - portalFee, i.e. the full PoD fee.\n const estimated = await portal.requestWithdrawWithPermit.estimateGas(\n wallet,\n amountWei,\n portalQuote.portalFee,\n podFee.totalFee,\n podFee.callBackFee,\n BigInt(withdrawPermit.deadline),\n withdrawPermit.v,\n withdrawPermit.r,\n withdrawPermit.s,\n { value: portalQuote.portalFee + podFee.totalFee, gasPrice },\n );\n gasLimit = (estimated * 130n) / 100n;\n } catch (estErr: unknown) {\n logger.warn(\n \"⚠️ PoD withdraw gas estimation reverted — broadcasting with fallback gas limit so the revert is inspectable on-chain\",\n (estErr as Error)?.message,\n );\n gasLimit = 3_000_000n;\n }\n\n const tx = await sendPodPortalMethod({\n runner: signer,\n portalAddress,\n chainId,\n direction: \"to-public\",\n method,\n args: podArgs,\n gasPrice,\n portalFee: portalQuote.portalFee,\n gasLimit,\n fee: podFee,\n });\n\n onProgress?.(\"transfer-start\", tx.hash);\n\n const receipt = await tx.wait();\n if (!receipt || receipt.status !== 1) {\n const failed = new Error(\"Sepolia withdraw transaction failed\") as Error & { txHash?: string };\n failed.txHash = tx.hash;\n throw failed;\n }\n\n const event = findParsedEvent(receipt, portalIface, \"WithdrawalRequested\");\n return {\n txHash: tx.hash,\n receipt,\n request: {\n id: tx.hash,\n kind: \"withdraw\",\n chainId,\n sourceTxHash: tx.hash,\n requestId: event?.args?.transferRequestId as string | undefined,\n withdrawalId: event?.args?.withdrawalId as string | undefined,\n wallet,\n token: tokenSymbol,\n amount: txAmount,\n status: \"source-mined\",\n message: \"PoD withdraw request submitted.\",\n createdAt: Date.now(),\n updatedAt: Date.now(),\n fromBlock: receipt.blockNumber,\n },\n };\n}\n","import { ethers } from \"ethers\";\nimport { PodRequest } from \"@coti-io/pod-sdk\";\nimport {\n COTI_TESTNET_CHAIN_ID,\n SEPOLIA_CHAIN_ID,\n buildPodExplorerRequestUrl,\n POD_PTOKEN_ABI,\n PRIVACY_PORTAL_ABI,\n type PodPortalRequest,\n} from \"../../contracts/pod\";\nimport { loadPodRequests } from \"../../pod/podPortalRequestsStorage\";\nimport { AVALANCHE_FUJI_CHAIN_ID } from \"../index\";\nimport type { PodSdkConfig } from \"@coti-io/pod-sdk\";\n\nconst TERMINAL_POD_REQUEST_STATUSES = new Set<PodPortalRequest[\"status\"]>([\n \"succeeded\",\n \"failed\",\n \"callback-errored\",\n \"burn-debt\",\n]);\n\nconst pTokenIface = new ethers.Interface(POD_PTOKEN_ABI);\nconst portalIface = new ethers.Interface(PRIVACY_PORTAL_ABI);\n\nexport type BlockingPodRequestCandidate = {\n source: \"local-storage\" | \"pToken-transfer-event\" | \"portal-deposit-event\" | \"portal-withdraw-event\" | \"pToken-callback-failed-event\";\n confidence: \"high\" | \"medium\" | \"low\";\n kind?: PodPortalRequest[\"kind\"];\n requestId?: string;\n withdrawalId?: string;\n sourceTxHash?: string;\n status?: PodPortalRequest[\"status\"];\n token?: string;\n amount?: string;\n chainId?: number;\n blockNumber?: number;\n explorerUrl?: string;\n podTracking?: {\n minedOnTarget: boolean;\n hasResponse: boolean;\n responseMinedOnTarget: boolean;\n executionError?: string;\n stillInFlight: boolean;\n };\n};\n\nexport type BlockingPodRequestDiagnostics = {\n blockingRequest: BlockingPodRequestCandidate | null;\n candidateRequests: BlockingPodRequestCandidate[];\n inFlightLocalPodRequests: ReturnType<typeof summarizeInFlightLocalPodRequests>;\n eventScan?: {\n providerAvailable: boolean;\n lookbackBlocks: number;\n portalDeposits: number;\n portalWithdraws: number;\n pTokenTransfers: number;\n pTokenCallbackFailures: number;\n errors: string[];\n };\n};\n\nexport const formatBlockingPodLogSummary = (\n blockingRequest: BlockingPodRequestCandidate | null,\n action: \"deposit\" | \"withdraw\",\n) => {\n if (!blockingRequest?.requestId) {\n return `PoD ${action} blocked: wallet has on-chain pending=true but no requestId was resolved (check eventScan / candidateRequests in the log object below).`;\n }\n\n const parts = [\n `PoD ${action} blocked by request ${blockingRequest.requestId}`,\n blockingRequest.kind ? `kind=${blockingRequest.kind}` : null,\n blockingRequest.source ? `source=${blockingRequest.source}` : null,\n blockingRequest.token ? `token=${blockingRequest.token}` : null,\n blockingRequest.amount ? `amount=${blockingRequest.amount}` : null,\n blockingRequest.withdrawalId ? `withdrawalId=${blockingRequest.withdrawalId}` : null,\n blockingRequest.sourceTxHash ? `sourceTx=${blockingRequest.sourceTxHash}` : null,\n blockingRequest.explorerUrl ? `explorer=${blockingRequest.explorerUrl}` : null,\n ].filter(Boolean);\n\n return parts.join(\" | \");\n};\n\nconst chainIdToExplorerSlug = (chainId: number) => {\n if (chainId === SEPOLIA_CHAIN_ID) return \"sepolia\";\n if (chainId === COTI_TESTNET_CHAIN_ID) return \"coti\";\n if (chainId === AVALANCHE_FUJI_CHAIN_ID) return \"fuji\";\n return String(chainId);\n};\n\nconst withExplorerUrl = (candidate: BlockingPodRequestCandidate): BlockingPodRequestCandidate => {\n if (!candidate.requestId || !candidate.chainId) return candidate;\n return {\n ...candidate,\n explorerUrl: buildPodExplorerRequestUrl(\n candidate.requestId,\n chainIdToExplorerSlug(candidate.chainId),\n ),\n };\n};\n\nconst tokenMatchesContext = (requestToken: string | undefined, tokenSymbol: string | undefined) => {\n if (!tokenSymbol || !requestToken) return true;\n const normalizedContext = tokenSymbol.replace(/^p\\./, \"\");\n const normalizedRequest = requestToken.replace(/^p\\./, \"\");\n return normalizedContext === normalizedRequest;\n};\n\nexport const summarizeInFlightLocalPodRequests = (wallet: string) => {\n const merged = [...loadPodRequests(wallet), ...loadPodRequests(\"\")];\n const seen = new Set<string>();\n\n return merged\n .filter(request => !TERMINAL_POD_REQUEST_STATUSES.has(request.status))\n .filter(request => {\n if (seen.has(request.id)) return false;\n seen.add(request.id);\n return true;\n })\n .map(request => ({\n id: request.id,\n kind: request.kind,\n status: request.status,\n requestId: request.requestId,\n withdrawalId: request.withdrawalId,\n token: request.token,\n amount: request.amount,\n chainId: request.chainId,\n sourceTxHash: request.sourceTxHash,\n message: request.message,\n updatedAt: request.updatedAt,\n }));\n};\n\nconst summarizeLocalCandidates = (\n wallet: string,\n chainId?: number,\n tokenSymbol?: string,\n): BlockingPodRequestCandidate[] => {\n const merged = [...loadPodRequests(wallet), ...loadPodRequests(\"\")];\n const seen = new Set<string>();\n\n return merged\n .filter(request => !TERMINAL_POD_REQUEST_STATUSES.has(request.status))\n .filter(request => {\n if (seen.has(request.id)) return false;\n seen.add(request.id);\n return true;\n })\n .filter(request => (chainId === undefined ? true : request.chainId === chainId))\n .filter(request => tokenMatchesContext(request.token, tokenSymbol))\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .map(request => withExplorerUrl({\n source: \"local-storage\",\n confidence: request.requestId ? \"high\" : \"medium\",\n kind: request.kind,\n requestId: request.requestId,\n withdrawalId: request.withdrawalId,\n sourceTxHash: request.sourceTxHash,\n status: request.status,\n token: request.token,\n amount: request.amount,\n chainId: request.chainId,\n }));\n};\n\nconst isPodRequestStillInFlight = (\n kind: PodPortalRequest[\"kind\"] | undefined,\n tracking: Awaited<ReturnType<PodRequest[\"trackRequest\"]>>,\n) => {\n if (tracking.execution?.errorCode && BigInt(tracking.execution.errorCode) !== 0n) {\n return false;\n }\n if (kind === \"deposit\") {\n return !tracking.response?.minedOnTarget;\n }\n if (kind === \"withdraw\") {\n return !tracking.response?.minedOnTarget;\n }\n return !tracking.minedOnTarget || !tracking.response?.minedOnTarget;\n};\n\nconst enrichWithPodTracking = async (\n candidate: BlockingPodRequestCandidate,\n): Promise<BlockingPodRequestCandidate> => {\n if (!candidate.requestId || !candidate.chainId) return candidate;\n\n try {\n const { getPodSdkConfig } = await import(\"./podSdkConfig\");\n const tracker = new PodRequest(getPodSdkConfig() as PodSdkConfig);\n const tracking = await tracker.trackRequest(candidate.chainId, candidate.requestId);\n const stillInFlight = isPodRequestStillInFlight(candidate.kind, tracking);\n return {\n ...candidate,\n confidence: stillInFlight ? \"high\" : \"low\",\n podTracking: {\n minedOnTarget: tracking.minedOnTarget,\n hasResponse: tracking.response !== null,\n responseMinedOnTarget: tracking.response?.minedOnTarget ?? false,\n executionError: tracking.execution?.errorMessage,\n stillInFlight,\n },\n };\n } catch {\n return candidate;\n }\n};\n\nconst POD_EVENT_LOOKBACK_STEPS = [10_000n, 50_000n, 100_000n] as const;\n\nconst fetchLogsWithLookback = async (\n provider: ethers.Provider,\n query: ethers.Filter,\n lookbackSteps: readonly bigint[] = POD_EVENT_LOOKBACK_STEPS,\n) => {\n const latest = BigInt(await provider.getBlockNumber());\n const errors: string[] = [];\n\n for (const lookback of lookbackSteps) {\n const fromBlock = latest > lookback ? latest - lookback : 0n;\n try {\n const logs = await provider.getLogs({ ...query, fromBlock, toBlock: latest });\n return { logs, lookbackBlocks: Number(lookback), errors };\n } catch (error) {\n errors.push(`${lookback} blocks: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n return { logs: [] as ethers.Log[], lookbackBlocks: Number(lookbackSteps[lookbackSteps.length - 1]), errors };\n};\n\nconst paddedAddressTopic = (address: string) =>\n ethers.zeroPadValue(ethers.getAddress(address), 32);\n\nconst fetchRecentPTokenEvents = async (\n provider: ethers.Provider,\n pTokenAddress: string,\n account: string,\n): Promise<{ candidates: BlockingPodRequestCandidate[]; errors: string[]; lookbackBlocks: number }> => {\n const accountTopic = paddedAddressTopic(account);\n const errors: string[] = [];\n\n const [transferFrom, transferTo, callbackFailed] = await Promise.all([\n fetchLogsWithLookback(provider, {\n address: pTokenAddress,\n topics: [pTokenIface.getEvent(\"TransferRequestSubmitted\")!.topicHash, accountTopic],\n }),\n fetchLogsWithLookback(provider, {\n address: pTokenAddress,\n topics: [pTokenIface.getEvent(\"TransferRequestSubmitted\")!.topicHash, null, accountTopic],\n }),\n fetchLogsWithLookback(provider, {\n address: pTokenAddress,\n topics: [pTokenIface.getEvent(\"RequestCallbackFailed\")!.topicHash, accountTopic],\n }),\n ]);\n\n errors.push(...transferFrom.errors, ...transferTo.errors, ...callbackFailed.errors);\n const lookbackBlocks = Math.max(\n transferFrom.lookbackBlocks,\n transferTo.lookbackBlocks,\n callbackFailed.lookbackBlocks,\n );\n\n const transferLogs = [...transferFrom.logs, ...transferTo.logs]\n .sort((a, b) => Number(b.blockNumber) - Number(a.blockNumber));\n\n const transferCandidates = transferLogs.map(log => {\n const parsed = pTokenIface.parseLog({ topics: log.topics as string[], data: log.data });\n return withExplorerUrl({\n source: \"pToken-transfer-event\",\n confidence: \"medium\",\n kind: \"withdraw\",\n requestId: parsed?.args?.requestId as string | undefined,\n blockNumber: log.blockNumber,\n sourceTxHash: log.transactionHash,\n });\n });\n\n const callbackCandidates = callbackFailed.logs.map(log => {\n const parsed = pTokenIface.parseLog({ topics: log.topics as string[], data: log.data });\n return withExplorerUrl({\n source: \"pToken-callback-failed-event\",\n confidence: \"high\",\n requestId: parsed?.args?.requestId as string | undefined,\n blockNumber: log.blockNumber,\n sourceTxHash: log.transactionHash,\n });\n });\n\n return {\n candidates: [...callbackCandidates, ...transferCandidates],\n errors,\n lookbackBlocks,\n };\n};\n\nconst fetchRecentPortalEvents = async (\n provider: ethers.Provider,\n portalAddress: string,\n account: string,\n chainId: number,\n): Promise<{ candidates: BlockingPodRequestCandidate[]; errors: string[]; lookbackBlocks: number }> => {\n const accountTopic = paddedAddressTopic(account);\n const errors: string[] = [];\n\n const [depositScan, withdrawScan] = await Promise.all([\n fetchLogsWithLookback(provider, {\n address: portalAddress,\n topics: [portalIface.getEvent(\"DepositRequested\")!.topicHash, accountTopic],\n }),\n fetchLogsWithLookback(provider, {\n address: portalAddress,\n topics: [portalIface.getEvent(\"WithdrawalRequested\")!.topicHash, null, accountTopic],\n }),\n ]);\n\n errors.push(...depositScan.errors, ...withdrawScan.errors);\n const lookbackBlocks = Math.max(depositScan.lookbackBlocks, withdrawScan.lookbackBlocks);\n\n const depositCandidates = depositScan.logs.map(log => {\n const parsed = portalIface.parseLog({ topics: log.topics as string[], data: log.data });\n return withExplorerUrl({\n source: \"portal-deposit-event\",\n confidence: \"medium\",\n kind: \"deposit\",\n requestId: parsed?.args?.mintRequestId as string | undefined,\n amount: parsed?.args?.amount?.toString(),\n chainId,\n blockNumber: log.blockNumber,\n sourceTxHash: log.transactionHash,\n });\n });\n\n const withdrawCandidates = withdrawScan.logs.map(log => {\n const parsed = portalIface.parseLog({ topics: log.topics as string[], data: log.data });\n return withExplorerUrl({\n source: \"portal-withdraw-event\",\n confidence: \"medium\",\n kind: \"withdraw\",\n requestId: parsed?.args?.transferRequestId as string | undefined,\n withdrawalId: parsed?.args?.withdrawalId as string | undefined,\n amount: parsed?.args?.amount?.toString(),\n chainId,\n blockNumber: log.blockNumber,\n sourceTxHash: log.transactionHash,\n });\n });\n\n return {\n candidates: [...depositCandidates, ...withdrawCandidates]\n .sort((a, b) => (b.blockNumber ?? 0) - (a.blockNumber ?? 0)),\n errors,\n lookbackBlocks,\n };\n};\n\nconst dedupeCandidates = (candidates: BlockingPodRequestCandidate[]) => {\n const seen = new Set<string>();\n return candidates.filter(candidate => {\n const key = [\n candidate.requestId ?? \"\",\n candidate.withdrawalId ?? \"\",\n candidate.sourceTxHash ?? \"\",\n candidate.source,\n ].join(\":\");\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\nconst pickBlockingRequest = (\n candidates: BlockingPodRequestCandidate[],\n blockedAction: \"deposit\" | \"withdraw\",\n): BlockingPodRequestCandidate | null => {\n if (candidates.length === 0) return null;\n\n const localMatches = candidates\n .filter(candidate => candidate.source === \"local-storage\" && candidate.requestId)\n .sort((a, b) => (b.chainId ?? 0) - (a.chainId ?? 0));\n if (localMatches[0]) return localMatches[0];\n\n const stillInFlight = candidates.filter(candidate => candidate.podTracking?.stillInFlight !== false);\n const pool = stillInFlight.length > 0 ? stillInFlight : candidates;\n\n const callbackFailure = pool.find(candidate => candidate.source === \"pToken-callback-failed-event\");\n if (callbackFailure) return callbackFailure;\n\n const actionKind = blockedAction === \"deposit\" ? \"deposit\" : \"withdraw\";\n const actionMatch = pool\n .filter(candidate => candidate.kind === actionKind && candidate.requestId)\n .sort((a, b) => (b.blockNumber ?? 0) - (a.blockNumber ?? 0))[0];\n if (actionMatch) return actionMatch;\n\n return pool\n .filter(candidate => candidate.requestId)\n .sort((a, b) => (b.blockNumber ?? 0) - (a.blockNumber ?? 0))[0] ?? pool[0] ?? null;\n};\n\nexport async function diagnoseBlockingPodRequest(params: {\n account: string;\n pTokenAddress: string;\n blockedAction: \"deposit\" | \"withdraw\";\n portalAddress?: string;\n tokenSymbol?: string;\n chainId?: number;\n provider?: ethers.Provider | null;\n callbackErrored?: boolean;\n}): Promise<BlockingPodRequestDiagnostics> {\n const {\n account,\n pTokenAddress,\n blockedAction,\n portalAddress,\n tokenSymbol,\n chainId,\n provider,\n callbackErrored = false,\n } = params;\n\n const inFlightLocalPodRequests = summarizeInFlightLocalPodRequests(account);\n let candidates = summarizeLocalCandidates(account, chainId, tokenSymbol);\n const eventScan: BlockingPodRequestDiagnostics[\"eventScan\"] = {\n providerAvailable: !!provider,\n lookbackBlocks: 0,\n portalDeposits: 0,\n portalWithdraws: 0,\n pTokenTransfers: 0,\n pTokenCallbackFailures: 0,\n errors: [],\n };\n\n if (provider) {\n const pTokenScan = await fetchRecentPTokenEvents(provider, pTokenAddress, account);\n eventScan.errors.push(...pTokenScan.errors);\n eventScan.lookbackBlocks = Math.max(eventScan.lookbackBlocks, pTokenScan.lookbackBlocks);\n eventScan.pTokenTransfers = pTokenScan.candidates.filter(candidate => candidate.source === \"pToken-transfer-event\").length;\n eventScan.pTokenCallbackFailures = pTokenScan.candidates.filter(candidate => candidate.source === \"pToken-callback-failed-event\").length;\n\n const onChainCandidates = pTokenScan.candidates.map(event => withExplorerUrl({\n ...event,\n chainId: chainId ?? event.chainId,\n }));\n\n candidates = dedupeCandidates([...candidates, ...onChainCandidates]);\n\n if (portalAddress && chainId !== undefined) {\n const portalScan = await fetchRecentPortalEvents(provider, portalAddress, account, chainId);\n eventScan.errors.push(...portalScan.errors);\n eventScan.lookbackBlocks = Math.max(eventScan.lookbackBlocks, portalScan.lookbackBlocks);\n eventScan.portalDeposits = portalScan.candidates.filter(candidate => candidate.source === \"portal-deposit-event\").length;\n eventScan.portalWithdraws = portalScan.candidates.filter(candidate => candidate.source === \"portal-withdraw-event\").length;\n candidates = dedupeCandidates([...candidates, ...portalScan.candidates]);\n }\n }\n\n const enrichedCandidates = provider\n ? await Promise.all(\n candidates\n .filter(candidate => candidate.requestId && candidate.chainId !== undefined)\n .map(candidate => enrichWithPodTracking(candidate).catch(() => candidate)),\n )\n : [];\n\n const enrichedByKey = new Map(\n enrichedCandidates.map(candidate => [\n `${candidate.requestId}:${candidate.source}`,\n candidate,\n ]),\n );\n\n candidates = candidates.map(candidate => {\n const enriched = enrichedByKey.get(`${candidate.requestId}:${candidate.source}`);\n return enriched ?? candidate;\n });\n\n if (callbackErrored) {\n candidates = candidates.map(candidate =>\n candidate.source === \"pToken-callback-failed-event\"\n ? { ...candidate, confidence: \"high\" as const }\n : candidate,\n );\n }\n\n const blockingRequest = pickBlockingRequest(candidates, blockedAction);\n\n return {\n blockingRequest,\n candidateRequests: candidates,\n inFlightLocalPodRequests,\n eventScan,\n };\n}\n","import { ethers } from \"ethers\";\nimport { getChainConfig } from \"./index\";\nimport { getRpcUrlsForChain } from \"./rpcUrls\";\nimport { logger } from \"../lib/logger\";\n\n/**\n * PoDPriceOracle deployed alongside the PoD privacy portals (Band adapter on\n * Sepolia, Chainlink adapter on Fuji). Prices are 18-decimal USD per whole\n * token; adapters return 0 (never revert) when a feed is unset or stale.\n */\nexport const POD_PRICE_ORACLE_ABI = [\n \"function getLivePrice(address token) view returns (uint256 priceUsd)\",\n \"function getLivePrices(address tokenA, address tokenB) view returns (uint256 priceA, uint256 priceB)\",\n];\n\n/**\n * Resolves the underlying ERC-20 the oracle prices for a token symbol.\n * Native symbols (ETH, AVAX) resolve through their wrapped collateral\n * (WETH, WAVAX) via the token's `addressKey`; private symbols (p.X)\n * resolve through their public counterpart.\n */\nfunction resolveOracleTokenAddress(symbol: string, chainId: number): string | null {\n const config = getChainConfig(chainId);\n if (!config) return null;\n const publicSymbol = symbol.startsWith(\"p.\") ? symbol.slice(2) : symbol;\n const token = config.tokens.find(t => t.symbol === publicSymbol && !t.isPrivate);\n if (!token?.addressKey) return null;\n return config.addresses[token.addressKey] ?? null;\n}\n\n/**\n * Fetches the live USD price for a token symbol from the chain's PoDPriceOracle.\n *\n * @param symbol - Token symbol from the chain config (e.g. \"ETH\", \"USDC\", \"AVAX\", \"p.USDC\")\n * @param chainId - Host chain id (Sepolia 11155111 or Fuji 43113)\n * @param provider - Optional ethers provider; defaults to the chain's configured RPCs\n * @returns USD price as a number, or null when the chain has no oracle,\n * the symbol is unknown, or the feed is unset/stale (oracle returns 0)\n */\nexport async function fetchPodOracleTokenUsdPrice(\n symbol: string,\n chainId: number,\n provider?: ethers.JsonRpcProvider | ethers.BrowserProvider,\n): Promise<number | null> {\n const oracleAddress = getChainConfig(chainId)?.priceOracleAddress;\n if (!oracleAddress) {\n logger.warn(`No PoD price oracle configured for chain ${chainId}`);\n return null;\n }\n const tokenAddress = resolveOracleTokenAddress(symbol, chainId);\n if (!tokenAddress) {\n logger.warn(`No oracle token mapping for symbol ${symbol} on chain ${chainId}`);\n return null;\n }\n\n const rpcUrls = provider ? [] : getRpcUrlsForChain(chainId);\n const providers = provider ? [provider] : rpcUrls.map(url => new ethers.JsonRpcProvider(url));\n\n let lastError: unknown;\n for (const rpcProvider of providers) {\n try {\n const oracle = new ethers.Contract(oracleAddress, POD_PRICE_ORACLE_ABI, rpcProvider);\n const raw: bigint = await oracle.getLivePrice(tokenAddress);\n if (raw === 0n) {\n logger.warn(`PoD price oracle has no live feed for ${symbol} on chain ${chainId}`);\n return null;\n }\n return Number(ethers.formatEther(raw));\n } catch (err) {\n lastError = err;\n }\n }\n const message = lastError instanceof Error ? lastError.message : String(lastError);\n logger.error(`Error fetching PoD oracle USD price for ${symbol} on chain ${chainId}: ${message}`);\n return null;\n}\n","import { ethers } from \"ethers\";\nimport { POD_PORTAL_ADMIN_ABI } from \"../../contracts/pod\";\nimport { getChainConfig } from \"../index\";\nimport { getRpcUrlsForChain } from \"../rpcUrls\";\nimport { fetchPodOracleTokenUsdPrice } from \"../podPriceOracle\";\nimport { logger } from \"../../lib/logger\";\nimport type { ChainConfig, TokenConfig } from \"../types\";\nimport type { BridgeData } from \"../../hooks/useBridgeData\";\nimport type { SimulationResult } from \"../../hooks/useBridgeFees\";\n\nconst ERC20_BALANCE_ABI = [\"function balanceOf(address) view returns (uint256)\"];\n\n/** Same percentage scale as the COTI bridges (500 bps = 0.05%). */\nconst FEE_DIVISOR = 1_000_000n;\n\n/** Deployed portals use uint128.max as the \"no max fee cap\" sentinel. */\nexport const POD_NO_MAX_FEE_SENTINEL = (1n << 128n) - 1n;\n\n/** Formats a fee config value, mapping the no-cap sentinel to \"0\" (COTI convention). */\nconst formatFee = (value: bigint): string =>\n value >= POD_NO_MAX_FEE_SENTINEL ? \"0\" : ethers.formatEther(value);\n\nasync function fetchPortalRow(\n token: TokenConfig,\n config: ChainConfig,\n provider: ethers.JsonRpcProvider,\n nativeSymbol: string,\n): Promise<BridgeData> {\n const portalAddress = config.addresses[token.bridgeAddressKey!];\n const privateToken = config.tokens.find(\n t => t.isPrivate && t.bridgeAddressKey === token.bridgeAddressKey\n );\n const base = {\n bridgeName: `${token.symbol} PoD Portal`,\n bridgeAddress: portalAddress,\n publicToken: token.symbol,\n publicTokenIcon: token.icon,\n privateToken: privateToken?.symbol || \"N/A\",\n privateTokenIcon: privateToken?.icon || \"\",\n tokenDecimals: token.decimals,\n feeTokenSymbol: nativeSymbol,\n // PoD portals have no deposit/withdraw limits\n minDepositAmount: \"N/A\",\n maxDepositAmount: \"N/A\",\n minWithdrawAmount: \"N/A\",\n maxWithdrawAmount: \"N/A\",\n accumulatedFees: \"0\",\n nativeCotiFee: \"0\",\n // No readable pause flag on the portal (pausing goes through a controller)\n isPaused: false,\n isLoading: false,\n };\n\n try {\n const portal = new ethers.Contract(portalAddress, POD_PORTAL_ADMIN_ABI, provider);\n const [depCfg, wdCfg, accFees, balance] = await Promise.all([\n portal.getFeeConfig(true),\n portal.getFeeConfig(false),\n portal.accumulatedPortalFees().catch(() => 0n),\n token.isNative\n ? provider.getBalance(portalAddress)\n : token.addressKey && config.addresses[token.addressKey]\n ? new ethers.Contract(config.addresses[token.addressKey], ERC20_BALANCE_ABI, provider)\n .balanceOf(portalAddress).catch(() => 0n)\n : Promise.resolve(0n),\n ]);\n return {\n ...base,\n depositFixedFee: formatFee(depCfg[0]),\n depositPercentageBps: depCfg[1].toString(),\n depositMaxFee: formatFee(depCfg[2]),\n withdrawFixedFee: formatFee(wdCfg[0]),\n withdrawPercentageBps: wdCfg[1].toString(),\n withdrawMaxFee: formatFee(wdCfg[2]),\n accumulatedCotiFees: ethers.formatEther(accFees),\n bridgeBalance: ethers.formatUnits(balance, token.decimals),\n error: null,\n };\n } catch (err) {\n logger.error(`Error fetching PoD portal data for ${token.symbol}:`, err);\n return {\n ...base,\n depositFixedFee: \"Error\",\n depositPercentageBps: \"Error\",\n depositMaxFee: \"Error\",\n withdrawFixedFee: \"Error\",\n withdrawPercentageBps: \"Error\",\n withdrawMaxFee: \"Error\",\n accumulatedCotiFees: \"0\",\n bridgeBalance: \"0\",\n error: \"Failed to fetch portal data\",\n };\n }\n}\n\n/**\n * Live backoffice reader for PoD privacy portals (Sepolia/Fuji).\n * Reads the deposit/withdraw fee configs, accumulated portal fees and portal\n * balance for every public token with a configured portal, shaped as\n * {@link BridgeData} rows. Fee values are native-coin denominated; the row's\n * `feeTokenSymbol` carries the display symbol (ETH/AVAX).\n */\nexport async function fetchPodBridgeData(chainId: number): Promise<BridgeData[]> {\n const config = getChainConfig(chainId);\n if (!config || config.portalStrategy !== \"pod-privacy-portal\") return [];\n const nativeSymbol = config.walletNetwork.nativeCurrency.symbol;\n const publicTokens = config.tokens.filter(\n t => !t.isPrivate && t.bridgeAddressKey && config.addresses[t.bridgeAddressKey]\n );\n\n let lastError: unknown;\n for (const rpcUrl of getRpcUrlsForChain(chainId)) {\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n try {\n await provider.getBlockNumber(); // probe before fanning out\n return await Promise.all(\n publicTokens.map(token => fetchPortalRow(token, config, provider, nativeSymbol))\n );\n } catch (err) {\n lastError = err;\n }\n }\n logger.error(`Error fetching PoD bridge data for chain ${chainId}:`, lastError);\n return [];\n}\n\n/**\n * Local mirror of the assumed PoD portal fee math for the backoffice\n * simulate panel: max(fixedFee, valueInNative * bps / 1e6), capped at maxFee\n * (0 = no cap). ERC-20 amounts are converted to native units via the chain's\n * PoDPriceOracle live prices.\n *\n * @param chainId - PoD chain id (Sepolia 11155111 / Fuji 43113)\n * @param tokenSymbol - Public token symbol from the chain config (e.g. \"ETH\", \"USDC\")\n * @param amount - Token amount (human-readable)\n * @param fixedFee - Floor fee in native coin (human-readable)\n * @param percentageBps - Basis points relative to FEE_DIVISOR (raw number string)\n * @param maxFee - Cap fee in native coin (human-readable, \"0\" = no cap)\n */\nexport async function simulatePodPortalFee(\n chainId: number,\n tokenSymbol: string,\n amount: string,\n fixedFee: string,\n percentageBps: string,\n maxFee: string,\n): Promise<SimulationResult> {\n try {\n const config = getChainConfig(chainId);\n if (!config) return { fee: \"—\", explanation: \"Unsupported chain\" };\n const token = config.tokens.find(t => t.symbol === tokenSymbol && !t.isPrivate);\n if (!token) return { fee: \"—\", explanation: \"Unknown token\" };\n\n // Fees are charged in the native coin; convert ERC-20 amounts via oracle prices.\n const amountWei = ethers.parseUnits(amount, token.decimals);\n let valueInNative: bigint;\n if (token.isNative) {\n valueInNative = amountWei;\n } else {\n const nativeSymbol = config.walletNetwork.nativeCurrency.symbol;\n const [tokenUsd, nativeUsd] = await Promise.all([\n fetchPodOracleTokenUsdPrice(tokenSymbol, chainId),\n fetchPodOracleTokenUsdPrice(nativeSymbol, chainId),\n ]);\n if (!tokenUsd || !nativeUsd) {\n // Mirrors the portal: without a live oracle price it skips dynamic\n // pricing and charges the fixed fee (verified on Fuji MTT:\n // estimateDepositFees returns fixedFee with usedDynamicPricing=false).\n const fixed = ethers.parseEther(fixedFee || \"0\");\n const cap = ethers.parseEther(maxFee || \"0\");\n const fee = cap > 0n && fixed > cap ? cap : fixed;\n return {\n fee: parseFloat(ethers.formatEther(fee)).toFixed(6),\n explanation: \"Fixed fee applied (no live oracle price)\",\n };\n }\n const tokenUsdWei = ethers.parseEther(tokenUsd.toString());\n const nativeUsdWei = ethers.parseEther(nativeUsd.toString());\n const amount18 = amountWei * 10n ** BigInt(18 - token.decimals);\n valueInNative = (amount18 * tokenUsdWei) / nativeUsdWei;\n }\n\n const fixedFeeWei = ethers.parseEther(fixedFee || \"0\");\n const maxFeeWei = ethers.parseEther(maxFee || \"0\");\n const bps = BigInt(parseInt(percentageBps || \"0\", 10));\n\n const percentageFee = (valueInNative * bps) / FEE_DIVISOR;\n let fee = percentageFee > fixedFeeWei ? percentageFee : fixedFeeWei;\n if (maxFeeWei > 0n && fee > maxFeeWei) fee = maxFeeWei;\n\n const explanation =\n maxFeeWei > 0n && fee === maxFeeWei && fee !== fixedFeeWei\n ? \"Max fee cap applied\"\n : fee === fixedFeeWei\n ? \"Fixed fee floor applied\"\n : \"Percentage fee applied\";\n return { fee: parseFloat(ethers.formatEther(fee)).toFixed(6), explanation };\n } catch (err) {\n logger.error(\"simulatePodPortalFee error:\", err);\n return { fee: \"—\", explanation: \"Simulation failed\" };\n }\n}\n","export const LIMITS: Record<string, { min: number; max: number }> = {\n 'USDC.e': { min: 5, max: 100000 },\n 'WETH': { min: 0.0003, max: 50 },\n 'WBTC': { min: 0.01, max: 5 },\n 'COTI': { min: 0.1, max: 250000 },\n};\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { ethers } from 'ethers';\nimport { getPluginConfig } from '../config/plugin';\nimport { getMetaMaskProvider } from '../lib/ethereum';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from '../lib/logger';\nimport { truncateAddress } from '../lib/format';\nimport { isChainUpdatesMuted } from '../lib/chainMute';\nimport { getMetaMaskMobileEthAccountsDelayMs } from '../lib/metaMaskMobile';\nimport {\n getChainIdConstants,\n getNetworkNameForChain,\n getWalletNetworkConfigs,\n} from '../chains';\n\nconst { COTI_MAINNET_ID, COTI_TESTNET_ID, SEPOLIA_ID } = getChainIdConstants();\n\ninterface UseMetamaskCallbacks {\n onNetworkChanged?: () => Promise<void>;\n onAccountChanged?: (account: string) => Promise<void>;\n onDisconnect?: () => void;\n onSnapCheck?: (account: string) => void;\n}\n\n/**\n * Custom hook to manage Metamask wallet interactions, including network management and connection.\n * \n * This hook provides a unified interface for:\n * 1. **Network Identification**: Detecting the current network and mapping it to a human-readable name.\n * 2. **Network Switching**: Requesting the wallet to switch chains (and adding the chain if missing).\n * 3. **Wallet Connection**: Handling the permissions request and account retrieval flow.\n * 4. **State Refresh**: Triggering manual updates of the network and account state.\n * 5. **Event Listeners**: Handling accountsChanged and chainChanged events automatically.\n * \n * @param callbacks - Object containing optional callbacks for various events.\n * @returns {Object} An object containing helper functions and constants.\n */\nexport const useMetamask = ({\n onNetworkChanged,\n onAccountChanged,\n onDisconnect,\n onSnapCheck\n}: UseMetamaskCallbacks = {}) => {\n const [networkName, setNetworkName] = useState('Unknown Network');\n const [chainId, setChainId] = useState<string | null>(null);\n const isInitialCheckDone = useRef(false);\n\n /**\n * Checks the provided provider's network and updates the local network name state.\n * \n * @param provider - The Ethers.js provider to check.\n */\n const checkNetwork = useCallback(async (provider: ethers.BrowserProvider) => {\n const network = await provider.getNetwork();\n const id = Number(network.chainId);\n setChainId(id.toString());\n\n setNetworkName(getNetworkNameForChain(id));\n }, []);\n\n\n /**\n * Requests a network switch to the target chain ID. \n * Attempts to add the network if it doesn't exist in the wallet.\n * \n * @param targetChainId - The Hex chain ID to switch to.\n * @returns True if successful, false otherwise.\n */\n const switchNetwork = async (targetChainId: string): Promise<boolean> => {\n const eth = getMetaMaskProvider();\n if (!eth) return false;\n\n try {\n // Try to switch to the network\n await eth.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: targetChainId }],\n });\n\n // Trigger callback if provided (e.g., to refresh balances)\n if (onNetworkChanged) {\n await onNetworkChanged();\n }\n return true;\n } catch (switchError: any) {\n // This error code indicates that the chain has not been added to MetaMask.\n if (switchError.code === 4902) {\n const networkConfig = getWalletNetworkConfigs()[targetChainId];\n if (!networkConfig) {\n logger.error(`Unsupported chain for wallet_addEthereumChain: ${targetChainId}`);\n return false;\n }\n try {\n // Add the network\n await eth.request({\n method: 'wallet_addEthereumChain',\n params: [networkConfig],\n });\n\n // After adding, MetaMask should auto-switch, but we can try again to be safe\n try {\n await eth.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: targetChainId }],\n });\n } catch (retrySwitchError) {\n // If this fails, MetaMask likely already switched during the add\n logger.log('Network added successfully, proceeding.');\n }\n\n // Trigger callback\n if (onNetworkChanged) {\n await onNetworkChanged();\n }\n return true;\n } catch (addError) {\n logger.error(`Failed to add ${networkConfig.chainName}:`, addError);\n return false;\n }\n } else {\n logger.error('Failed to switch network:', switchError);\n return false;\n }\n }\n };\n\n /**\n * Connects to the user's Metamask wallet.\n * Requests permissions, gets accounts, ensures the correct network, and triggers state updates.\n *\n * @param onConnect - Callback to execute with the connected account address.\n * @returns `true` when an account was connected and `onConnect` completed; `false` on rejection, empty accounts, or provider errors.\n */\n const connectWallet = async (onConnect: (account: string) => Promise<void>): Promise<boolean> => {\n const eth = getMetaMaskProvider();\n if (!eth) {\n throw new CotiPluginError(CotiErrorCode.METAMASK_NOT_INSTALLED, 'MetaMask or compatible wallet not found');\n }\n\n try {\n // 1. Request Account Access\n await eth.request({\n method: 'wallet_requestPermissions',\n params: [{ eth_accounts: {} }]\n });\n\n // 2. Get Selected Accounts\n const accounts = await eth.request({ method: 'eth_requestAccounts' }) as string[];\n\n if (!accounts || accounts.length === 0) return false;\n\n // Check network, default to Mainnet if on wrong network\n const provider = new ethers.BrowserProvider(eth);\n const network = await provider.getNetwork();\n\n const envDefaultNetwork = getPluginConfig().defaultNetworkId;\n\n /*\n if (envDefaultNetwork) {\n // STRICT MODE: If env var is set (CI/CD deployments), enforce that specific network\n if (network.chainId !== BigInt(envDefaultNetwork)) {\n logger.log(`Enforcing strict network switch to ${envDefaultNetwork}`);\n const success = await switchNetwork(envDefaultNetwork);\n if (!success) {\n logger.error(`Failed to switch to required network (${envDefaultNetwork})`);\n }\n }\n } else { */\n /*\n // PERMISSIVE MODE (Local Dev): Allow either, default to Mainnet if neither\n if (network.chainId !== BigInt(COTI_MAINNET_ID) && network.chainId !== BigInt(COTI_TESTNET_ID) && network.chainId !== BigInt(SEPOLIA_ID)) {\n const success = await switchNetwork(COTI_MAINNET_ID);\n if (!success) {\n logger.error(\"Failed to switch to mainnet default\");\n }\n }\n } */\n\n // 4. Update State via callback\n /* v8 ignore next 2 -- unreachable: empty accounts return above at line 176 */\n if (accounts.length > 0) {\n await onConnect(accounts[0]);\n return true;\n }\n return false;\n } catch (error) {\n logger.error('Error connecting to MetaMask:', error);\n return false;\n }\n };\n\n /**\n * Refreshes the network state and triggers the change callback.\n * Useful for manual refreshes or periodic checks.\n */\n const refreshNetworkState = useCallback(async () => {\n const eth = getMetaMaskProvider();\n if (!eth) return;\n try {\n const provider = new ethers.BrowserProvider(eth);\n await checkNetwork(provider);\n\n if (onNetworkChanged) {\n await onNetworkChanged();\n }\n } catch (error) {\n logger.error('Error refreshing network state:', error);\n }\n }, [checkNetwork, onNetworkChanged]);\n\n // Handle initial check and event listeners\n useEffect(() => {\n const setup = () => {\n const eth = getMetaMaskProvider();\n if (!eth) return;\n\n const handleAccountsChanged = (accounts: string[]) => {\n if (accounts.length > 0) {\n if (onAccountChanged) onAccountChanged(accounts[0]);\n } else {\n if (onDisconnect) onDisconnect();\n }\n };\n\n const handleChainChanged = () => {\n // Skip reload if chain updates are muted (cross-chain onboarding in progress).\n // The onboarding flow temporarily switches to COTI and back; reloading would\n // disrupt the UI and lose the onboarding state.\n if (isChainUpdatesMuted()) {\n logger.log('🔇 [useMetamask] chainChanged ignored (muted for onboarding)');\n return;\n }\n // Prefer a soft resync via the callback instead of a full page reload.\n // A hard reload drops wagmi/RainbowKit connections (reconnectOnMount: false),\n // which forced users to reconnect after every network switch. Only fall back\n // to a reload when no handler is wired (legacy injected-only integrations).\n if (onNetworkChanged) {\n void onNetworkChanged();\n return;\n }\n window.location.reload();\n };\n\n eth.on?.('accountsChanged', handleAccountsChanged);\n eth.on?.('chainChanged', handleChainChanged);\n\n // Deferred via setTimeout so MetaMask Mobile's JSON-RPC relay\n // is fully ready before we send eth_accounts. Without the defer, this\n // request races with any eth_accounts call triggered by user interaction\n // (e.g. tapping Unlock) on the very first page load, overflowing\n // MetaMask Mobile's request coalescer. The flag is set synchronously\n // so that re-renders during the same tick do not schedule duplicates.\n if (!isInitialCheckDone.current) {\n isInitialCheckDone.current = true;\n const deferMs = getMetaMaskMobileEthAccountsDelayMs();\n setTimeout(() => {\n logger.log(`🔄 useMetamask: Performing initial eth_accounts check (defer=${deferMs}ms)`);\n (eth.request({ method: 'eth_accounts' }) as Promise<string[]>).then((accounts) => {\n logger.log(\n '🔄 useMetamask: eth_accounts result:',\n accounts.length === 0\n ? 'no accounts'\n : `${accounts.length} account(s), primary: ${truncateAddress(accounts[0])}`,\n );\n if (accounts.length > 0) {\n if (onAccountChanged) onAccountChanged(accounts[0]);\n logger.log('🔄 useMetamask: triggering checkSnapConnection');\n if (onSnapCheck) onSnapCheck(accounts[0]);\n } else {\n logger.log('ℹ️ useMetamask: No accounts returned by eth_accounts');\n }\n }).catch((err: any) => logger.error('❌ useMetamask: eth_accounts failed', err));\n }, deferMs);\n }\n\n return () => {\n eth.removeListener?.('accountsChanged', handleAccountsChanged);\n eth.removeListener?.('chainChanged', handleChainChanged);\n };\n };\n\n // Run setup immediately if provider is already available\n const cleanup = setup();\n\n // Also listen for late injection (MetaMask not yet loaded when page mounted)\n const handleEthereumInitialized = () => {\n logger.log('🔄 useMetamask: ethereum#initialized fired, re-running setup');\n setup();\n };\n window.addEventListener('ethereum#initialized', handleEthereumInitialized, { once: true });\n\n return () => {\n window.removeEventListener('ethereum#initialized', handleEthereumInitialized);\n cleanup?.();\n };\n }, [onAccountChanged, onDisconnect, onSnapCheck]);\n\n /**\n * Registers a one-time listener for the `ethereum#initialized` event.\n * This event is fired by MetaMask after it injects `window.ethereum` into the page.\n *\n * @param callback - Function to invoke when the event fires.\n */\n const registerEthereumInitializedListener = (callback: () => void) => {\n window.addEventListener('ethereum#initialized', callback, { once: true });\n };\n\n return {\n networkName,\n chainId,\n checkNetwork,\n switchNetwork,\n connectWallet,\n refreshNetworkState,\n registerEthereumInitializedListener,\n COTI_MAINNET_ID,\n COTI_TESTNET_ID,\n SEPOLIA_ID\n };\n};\n","/**\n * Typed EIP-1193 provider interface for window.ethereum access.\n * Eliminates `as any` casts throughout the codebase.\n */\n\nexport interface EIP1193Provider {\n request: (args: { method: string; params?: unknown[] | Record<string, unknown> }) => Promise<any>;\n isMetaMask?: boolean;\n isRabby?: boolean;\n isPhantom?: boolean;\n on?: (event: string, handler: (...args: any[]) => void) => void;\n removeListener?: (event: string, handler: (...args: any[]) => void) => void;\n providers?: EIP1193Provider[];\n}\n\nexport interface InjectedWalletTarget {\n id: string;\n name: string;\n provider: EIP1193Provider;\n}\n\nconst METAMASK_MISSING_PROVIDER: EIP1193Provider = {\n request() {\n return Promise.reject(\n Object.assign(new Error('MetaMask extension not found via EIP-6963'), { code: 4900 }),\n );\n },\n};\n\nlet eip6963MetaMaskProvider: EIP1193Provider | null = null;\nlet eip6963RabbyProvider: EIP1193Provider | null = null;\nlet eip6963ListenerRegistered = false;\n\nconst RABBY_MISSING_PROVIDER: EIP1193Provider = {\n request() {\n return Promise.reject(\n Object.assign(new Error('Rabby extension not found via EIP-6963'), { code: 4900 }),\n );\n },\n};\n\nfunction registerEip6963Discovery(): void {\n if (typeof window === 'undefined' || eip6963ListenerRegistered) {\n return;\n }\n eip6963ListenerRegistered = true;\n\n window.addEventListener('eip6963:announceProvider', ((event: CustomEvent) => {\n const info = event?.detail?.info;\n const provider = event?.detail?.provider;\n if (info?.rdns === 'io.metamask' || info?.rdns === 'io.metamask.flask') {\n eip6963MetaMaskProvider = provider;\n }\n if (info?.rdns === 'io.rabby') {\n eip6963RabbyProvider = provider;\n }\n }) as EventListener);\n\n window.dispatchEvent(new Event('eip6963:requestProvider'));\n}\n\nregisterEip6963Discovery();\n\n/**\n * Returns the EIP-6963 discovered MetaMask provider when available.\n */\nexport function getEip6963MetaMaskProvider(): EIP1193Provider | null {\n registerEip6963Discovery();\n return eip6963MetaMaskProvider;\n}\n\nexport function getEip6963RabbyProvider(): EIP1193Provider | null {\n registerEip6963Discovery();\n return eip6963RabbyProvider;\n}\n\nfunction findMetaMaskInProviders(providers: EIP1193Provider[]): EIP1193Provider | undefined {\n return providers.find(\n (p) =>\n p.isMetaMask &&\n !p.isRabby &&\n !p.isPhantom,\n );\n}\n\n/** Ask installed extensions to re-announce via EIP-6963 (safe to call repeatedly). */\nexport function requestEip6963Providers(): void {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new Event('eip6963:requestProvider'));\n }\n}\n\n/**\n * Resolves the MetaMask injected target for wagmi/RainbowKit.\n * Never returns undefined — wagmi's injected() connector falls back to\n * window.ethereum (often Rabby) when target() is undefined.\n */\nexport function resolveMetaMaskInjectedTarget(): InjectedWalletTarget {\n requestEip6963Providers();\n\n const eip6963 = getEip6963MetaMaskProvider();\n if (eip6963) {\n return { id: 'io.metamask', name: 'MetaMask', provider: eip6963 };\n }\n\n try {\n const eth = getEthereumProvider();\n if (eth?.providers?.length) {\n const mm = findMetaMaskInProviders(eth.providers);\n if (mm) {\n return { id: 'io.metamask', name: 'MetaMask', provider: mm };\n }\n }\n } catch {\n /* window.ethereum may throw when extensions fight over the global */\n }\n\n return {\n id: 'io.metamask',\n name: 'MetaMask',\n provider: METAMASK_MISSING_PROVIDER,\n };\n}\n\n/**\n * Resolves the Rabby injected target for wagmi/RainbowKit.\n * Never returns undefined — avoids wagmi falling back to a generic injected provider.\n */\nexport function resolveRabbyInjectedTarget(): InjectedWalletTarget {\n requestEip6963Providers();\n\n const eip6963 = getEip6963RabbyProvider();\n if (eip6963) {\n return { id: 'rabby', name: 'Rabby Wallet', provider: eip6963 };\n }\n\n try {\n const eth = getEthereumProvider();\n if (eth?.isRabby) {\n return { id: 'rabby', name: 'Rabby Wallet', provider: eth };\n }\n } catch {\n /* window.ethereum may throw when extensions fight over the global */\n }\n\n return {\n id: 'rabby',\n name: 'Rabby Wallet',\n provider: RABBY_MISSING_PROVIDER,\n };\n}\n\n/**\n * Resolves the MetaMask inpage provider, preferring EIP-6963 over window.ethereum.\n * Use for Snap RPCs when multiple wallet extensions may hijack window.ethereum.\n */\nexport function getMetaMaskProvider(): EIP1193Provider | null {\n const eip6963 = getEip6963MetaMaskProvider();\n if (eip6963) {\n return eip6963;\n }\n\n try {\n if (typeof window === 'undefined' || !window.ethereum) {\n return null;\n }\n\n const eth = window.ethereum as unknown as EIP1193Provider;\n if (eth.providers?.length) {\n const mm = findMetaMaskInProviders(eth.providers);\n if (mm) {\n return mm;\n }\n }\n\n if (eth.isMetaMask && !eth.isRabby && !eth.isPhantom) {\n return eth;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Returns the typed EIP-1193 provider from `window.ethereum`, or null if unavailable.\n * Use this instead of `window.ethereum as any` throughout the codebase.\n * Handles the case where window.ethereum access may throw due to property\n * redefinition conflicts between wallet extensions.\n */\nexport function getEthereumProvider(): EIP1193Provider | null {\n try {\n if (typeof window === 'undefined' || !window.ethereum) {\n return null;\n }\n return window.ethereum as unknown as EIP1193Provider;\n } catch {\n return null;\n }\n}\n\n/** Minimal wagmi-connector shape needed to resolve its EIP-1193 provider. */\nexport interface ConnectorProviderSource {\n getProvider?: (params?: { chainId?: number }) => Promise<unknown>;\n}\n\n/**\n * Resolves the EIP-1193 provider for the wallet the user actually connected.\n * Prefers the wagmi connector's provider (the exact wallet chosen via\n * RainbowKit), then the EIP-6963 MetaMask provider, and only then the\n * window.ethereum global — which belongs to whichever extension won the\n * injection race when multiple wallets are installed, so signing through it\n * can pop up a wallet the user never connected.\n */\nexport async function resolveConnectedProvider(\n connector?: ConnectorProviderSource | null,\n): Promise<EIP1193Provider | null> {\n if (connector?.getProvider) {\n try {\n const provider = await connector.getProvider();\n if (provider) return provider as EIP1193Provider;\n } catch {\n /* connector may be mid-reconnect — fall through to discovery */\n }\n }\n return getMetaMaskProvider() ?? getEthereumProvider();\n}\n","/**\n * Extended formatting utilities for Ethereum addresses and values.\n */\n\n/**\n * Truncates an Ethereum address to show first and last N characters.\n * The total visible characters (excluding \"...\") equals `length`.\n *\n * @param address - A full Ethereum address (42 characters including \"0x\").\n * @param length - Number of visible characters to keep (split between start and end). Default: 10.\n * @returns The truncated address (e.g., \"0xAbCd...ef12\").\n *\n * @example\n * truncateAddress(\"0x1234567890abcdef1234567890abcdef12345678\", 10)\n * // => \"0x123...45678\"\n */\nexport function truncateAddress(address: string, length: number = 10): string {\n if (!address || address.length <= length) {\n return address;\n }\n\n const start = Math.ceil(length / 2);\n const end = Math.floor(length / 2);\n\n return `${address.slice(0, start)}...${address.slice(-end)}`;\n}\n","/**\n * Module-level flag to suppress UI chain-change reactions during onboarding.\n * When muted, consuming apps should ignore provider chainChanged events\n * so the UI stays on the original chain while onboarding executes on COTI.\n */\nlet muted = false;\n\nexport function muteChainUpdates() { muted = true; }\nexport function unmuteChainUpdates() { muted = false; }\nexport function isChainUpdatesMuted() { return muted; }\n","/**\n * MetaMask Mobile in-app browser helpers.\n *\n * MetaMask Mobile's JSON-RPC relay has a known coalescer bug: concurrent\n * read-only or wallet RPC calls can overflow the call stack (\"could not\n * coalesce error / Maximum call stack size exceeded\"). ethers/coti-ethers can\n * fire many parallel probes during `generateOrRecoverAes()`.\n */\n\nimport { logger } from './logger';\nimport { getPluginConfig } from '../config/plugin';\nimport { getEthereumProvider, getMetaMaskProvider, type EIP1193Provider } from './ethereum';\n\ntype RequestFn = (args: { method: string; params?: unknown[] }) => Promise<unknown>;\ntype WalletProviderLike = {\n request: (args: { method: string; params?: unknown[] | Record<string, unknown> }) => Promise<unknown>;\n};\n\n/** Read-only RPC methods that must be serialized on MetaMask Mobile. */\nexport const MOBILE_READ_ONLY_RPC_METHODS = new Set([\n 'eth_chainId',\n 'eth_accounts',\n 'eth_getBalance',\n 'eth_call',\n 'eth_blockNumber',\n 'eth_gasPrice',\n 'eth_getTransactionCount',\n 'eth_getCode',\n 'eth_getStorageAt',\n]);\n\n/** Wallet-interactive RPC methods that must hit MetaMask one at a time. */\nexport const MOBILE_WALLET_RPC_METHODS = new Set([\n 'personal_sign',\n 'eth_sign',\n 'eth_signTypedData',\n 'eth_signTypedData_v3',\n 'eth_signTypedData_v4',\n 'eth_sendTransaction',\n 'wallet_switchEthereumChain',\n 'wallet_addEthereumChain',\n]);\n\n/** Detect MetaMask Mobile's embedded dApp browser. */\nexport function isMetaMaskMobileBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n const ua = navigator.userAgent;\n if (/MetaMaskMobile/i.test(ua)) return true;\n // Mobile WebView with injected MetaMask provider (no desktop extension).\n if (/android|iphone|ipod|ipad/i.test(ua) && typeof window !== 'undefined') {\n const eth = (window as Window & { ethereum?: { isMetaMask?: boolean } }).ethereum;\n if (eth?.isMetaMask) return true;\n }\n return false;\n}\n\n/**\n * On MetaMask Mobile in-app browser, wagmi's MetaMask connector can return the\n * SDK relay provider. `personal_sign` through that relay hangs without opening\n * the native sign sheet, so wallet-interactive onboarding must use inpage\n * `window.ethereum`.\n */\nexport function resolveMetaMaskMobileWalletProvider(\n connectorProvider: WalletProviderLike | null | undefined,\n): WalletProviderLike {\n if (isMetaMaskMobileBrowser()) {\n const native = getMetaMaskProvider() ?? getEthereumProvider();\n if (native) {\n return native as EIP1193Provider;\n }\n }\n if (!connectorProvider) {\n throw new Error('Could not get provider from wallet connector.');\n }\n return connectorProvider;\n}\n\n/** Delay before the first `eth_accounts` probe on MetaMask Mobile (ms). */\nexport function getMetaMaskMobileEthAccountsDelayMs(): number {\n return isMetaMaskMobileBrowser() ? 500 : 0;\n}\n\nconst MOBILE_RPC_CACHE_MS = 30_000;\nconst mobileReadOnlyCache = new Map<string, { value: unknown; at: number }>();\nconst mobileReadOnlyInflight = new Map<string, Promise<unknown>>();\nconst mobileWalletInflight = new Map<string, Promise<unknown>>();\nlet mobileReadOnlyMutex: Promise<void> = Promise.resolve();\nlet mobileWalletMutex: Promise<void> = Promise.resolve();\n\nfunction mobileReadOnlyCacheKey(method: string, params: unknown[]): string {\n return `${method}:${JSON.stringify(params)}`;\n}\n\nfunction mobileWalletCacheKey(method: string, params: unknown[]): string {\n return `${method}:${JSON.stringify(params)}`;\n}\n\n/** Clears cached/in-flight mobile RPC state. Call after chain changes. */\nexport function clearMetaMaskMobileRpcCache(): void {\n mobileReadOnlyCache.clear();\n mobileReadOnlyInflight.clear();\n mobileWalletInflight.clear();\n mobileReadOnlyMutex = Promise.resolve();\n mobileWalletMutex = Promise.resolve();\n}\n\n/**\n * Global mutex + cache for read-only RPC on MetaMask Mobile. Identical\n * in-flight calls share one promise; different calls queue behind one mutex.\n */\nexport async function guardedMobileReadOnlyRpc(\n provider: { request: RequestFn },\n method: string,\n params: unknown[] = [],\n): Promise<unknown> {\n if (!isMetaMaskMobileBrowser()) {\n return provider.request({ method, params });\n }\n\n const cacheKey = mobileReadOnlyCacheKey(method, params);\n const now = Date.now();\n const cached = mobileReadOnlyCache.get(cacheKey);\n if (cached && now - cached.at < MOBILE_RPC_CACHE_MS) {\n return cached.value;\n }\n\n const inflight = mobileReadOnlyInflight.get(cacheKey);\n if (inflight) {\n return inflight;\n }\n\n const promise = (async () => {\n const prev = mobileReadOnlyMutex;\n let release!: () => void;\n mobileReadOnlyMutex = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await prev;\n\n try {\n const cachedAfterWait = mobileReadOnlyCache.get(cacheKey);\n if (cachedAfterWait && Date.now() - cachedAfterWait.at < MOBILE_RPC_CACHE_MS) {\n return cachedAfterWait.value;\n }\n\n const value = await provider.request({ method, params });\n mobileReadOnlyCache.set(cacheKey, { value, at: Date.now() });\n return value;\n } finally {\n mobileReadOnlyInflight.delete(cacheKey);\n release();\n }\n })();\n\n mobileReadOnlyInflight.set(cacheKey, promise);\n return promise;\n}\n\n/**\n * Serialize wallet-interactive RPC on MetaMask Mobile (`personal_sign`, txs,\n * chain switching). Identical in-flight calls share one promise; other calls\n * queue behind one global mutex.\n */\nexport async function guardedMobileWalletRpc(\n provider: { request: RequestFn },\n method: string,\n params: unknown[] = [],\n): Promise<unknown> {\n if (!isMetaMaskMobileBrowser()) {\n return provider.request({ method, params });\n }\n\n const cacheKey = mobileWalletCacheKey(method, params);\n const inflight = mobileWalletInflight.get(cacheKey);\n if (inflight) {\n return inflight;\n }\n\n const promise = (async () => {\n const prev = mobileWalletMutex;\n let release!: () => void;\n mobileWalletMutex = new Promise<void>((resolve) => {\n release = resolve;\n });\n\n await prev;\n\n try {\n if (getPluginConfig().debug === true) {\n logger.log(`[Onboarding:wallet-send] ${method}`);\n }\n return await provider.request({ method, params });\n } finally {\n mobileWalletInflight.delete(cacheKey);\n release();\n }\n })();\n\n mobileWalletInflight.set(cacheKey, promise);\n return promise;\n}\n\n/** @see guardedMobileReadOnlyRpc */\nexport async function guardedEthChainId(provider: { request: RequestFn }): Promise<string> {\n return (await guardedMobileReadOnlyRpc(provider, 'eth_chainId', [])) as string;\n}\n\n/** @see guardedMobileReadOnlyRpc */\nexport async function guardedEthGetBalance(\n provider: { request: RequestFn },\n params: unknown[] = [],\n): Promise<string> {\n return (await guardedMobileReadOnlyRpc(provider, 'eth_getBalance', params)) as string;\n}\n\n/** @see guardedMobileReadOnlyRpc */\nexport async function guardedEthAccounts(\n provider: { request: RequestFn },\n): Promise<string[]> {\n return (await guardedMobileReadOnlyRpc(provider, 'eth_accounts', [])) as string[];\n}\n\n/** JSON-RPC over HTTP, used for read-only calls during mobile onboarding. */\nexport async function mobileHttpJsonRpc(\n rpcUrl: string,\n method: string,\n params: unknown[] = [],\n): Promise<unknown> {\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),\n });\n const json = (await response.json()) as {\n result?: unknown;\n error?: { message?: string; code?: number };\n };\n if (json.error) {\n throw Object.assign(new Error(json.error.message ?? 'RPC error'), { code: json.error.code });\n }\n return json.result;\n}\n\nexport interface OnboardingDebugEntry {\n ts: number;\n tag: string;\n detail?: string;\n}\n\n/** Collects timestamped onboarding events for MetaMask Mobile diagnostics. */\nexport class OnboardingDebugTrace {\n private entries: OnboardingDebugEntry[] = [];\n\n push(tag: string, detail?: string): void {\n const entry: OnboardingDebugEntry = { ts: Date.now(), tag, detail };\n this.entries.push(entry);\n if (getPluginConfig().debug === true) {\n logger.log(`[Onboarding:${tag}]${detail ? ` ${detail}` : ''}`);\n }\n }\n\n clear(): void {\n this.entries = [];\n }\n\n toLines(): string[] {\n const t0 = this.entries[0]?.ts ?? Date.now();\n return this.entries.map((e) => {\n const offsetMs = e.ts - t0;\n const detail = e.detail ? ` — ${e.detail}` : '';\n return `+${offsetMs}ms ${e.tag}${detail}`;\n });\n }\n\n getEntries(): readonly OnboardingDebugEntry[] {\n return this.entries;\n }\n}\n\n/** Maps MetaMask Mobile coalescer failures to a user-friendly message. */\nexport function formatOnboardingError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const payloadMethod =\n error && typeof error === 'object' && 'payload' in error\n ? (error as { payload?: { method?: string } }).payload?.method\n : undefined;\n\n if (\n message.includes('Maximum call stack size exceeded')\n || message.includes('maximum call stack exceeded')\n || message.includes('could not coalesce')\n || payloadMethod === 'eth_accounts'\n || payloadMethod === 'eth_chainId'\n || payloadMethod === 'eth_getBalance'\n || payloadMethod === 'eth_call'\n || payloadMethod === 'personal_sign'\n || payloadMethod === 'eth_sendTransaction'\n ) {\n return [\n 'MetaMask Mobile provider error (wallet RPC conflict).',\n 'Wait a moment and tap Retry, or refresh the page once and try again.',\n 'Enable plugin debug logging (configureCotiPlugin({ debug: true })) for a step-by-step trace.',\n ].join(' ');\n }\n\n const trimmed = message.trim();\n return trimmed || 'Onboarding failed. Try again or refresh the page.';\n}\n","import { useCallback } from 'react';\nimport { ethers } from 'ethers';\nimport { decryptCtUint64, decryptCtUint256 } from '../crypto/decryption';\nimport { withRpcFallback } from '../lib/rpcProvider';\nimport { getPluginConfig } from '../config/plugin';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from '../lib/logger';\nimport type { CtUint256 } from '../types/ciphertext';\nimport { isZeroCtUint256 } from '../types/ciphertext';\n\nexport interface PrivateBalanceDecryptOptions {\n decryptCtUint64?: (value: bigint | string | number, chainId?: number | string, accountAddress?: string) => Promise<bigint | null>;\n decryptCtUint256?: (value: CtUint256, chainId?: number | string, accountAddress?: string) => Promise<bigint | null>;\n}\n\n/** Native PoD pTokens whose balanceOf returns a plain uint256 (legacy deployments). */\nconst PLAIN_BALANCE_ABI = [\n \"function balanceOf(address account) view returns (uint256)\",\n];\n\n/** PoD and COTI private ERC-20 balances: flat ctUint256 (ciphertextHigh, ciphertextLow). */\nconst FLAT_BALANCE_ABI = [\n \"function balanceOf(address) view returns (tuple(uint256 ciphertextHigh, uint256 ciphertextLow))\",\n];\n\n/**\n * Fetches and decrypts confidential token balances.\n *\n * Encrypted 256-bit balances always use flat ctUint256. Native PoD pTokens\n * (p.ETH, p.AVAX) are requested via {@link isPlainBalance}, but the actual\n * on-chain shape is detected from the return data: current deployments store\n * encrypted ctUint256 (64 bytes) while legacy ones stored plain uint256 (32 bytes).\n */\nexport const usePrivateTokenBalance = () => {\n const fetchPrivateBalance = useCallback(async (\n userAddress: string,\n aesKey: string,\n contractAddress: string,\n version: 64 | 256,\n decimals: number = 18,\n _readChainId?: number,\n isPlainBalance: boolean = false,\n decryptOptions?: PrivateBalanceDecryptOptions,\n ): Promise<string> => {\n if (!contractAddress) {\n return '0.00';\n }\n const canUseSnapDecrypt = !!decryptOptions?.decryptCtUint64 || !!decryptOptions?.decryptCtUint256;\n if (!isPlainBalance && !aesKey && !canUseSnapDecrypt) {\n return '0.00';\n }\n if (_readChainId == null && !window.ethereum) {\n return '0.00';\n }\n\n try {\n const useRpcRead = _readChainId != null;\n\n const readBalance = async (runner: ethers.ContractRunner): Promise<string> => {\n const decryptFlatCt256 = async (high: bigint, low: bigint): Promise<string> => {\n const flatBalance = { ciphertextHigh: high, ciphertextLow: low };\n if (isZeroCtUint256(flatBalance)) return '0.00';\n\n const decryptedVal = aesKey\n ? decryptCtUint256(flatBalance, aesKey, { decimals })\n : await decryptOptions?.decryptCtUint256?.(flatBalance, _readChainId, userAddress) ?? null;\n if (decryptedVal === null) {\n throw new CotiPluginError(CotiErrorCode.AES_KEY_MISMATCH, 'AES key mismatch: Error decrypting. Re-onboarding required.');\n }\n return ethers.formatUnits(decryptedVal, decimals);\n };\n\n if (isPlainBalance) {\n // Native pTokens are configured as plain, but current PoD deployments\n // actually store encrypted ctUint256. Read the raw return data and pick\n // the decode path from its shape: 32 bytes = plain uint256, 64 bytes =\n // ctUint256 (ciphertextHigh, ciphertextLow).\n const iface = new ethers.Interface(PLAIN_BALANCE_ABI);\n const rawReturn = await runner.provider!.call({\n to: contractAddress,\n data: iface.encodeFunctionData('balanceOf', [userAddress]),\n });\n const returnByteLength = (rawReturn.length - 2) / 2;\n\n if (returnByteLength > 32) {\n logger.log('[fetchPrivateBalance] plain-configured token returned ctUint256 — decrypting', { contractAddress, returnByteLength });\n if (!aesKey && !decryptOptions?.decryptCtUint256) return '0.00';\n const [high, low] = ethers.AbiCoder.defaultAbiCoder().decode(['uint256', 'uint256'], rawReturn);\n return decryptFlatCt256(high, low);\n }\n\n const [balance] = iface.decodeFunctionResult('balanceOf', rawReturn);\n return ethers.formatUnits(balance, decimals);\n }\n\n if (version === 64) {\n const contract = new ethers.Contract(contractAddress, [\n \"function balanceOf(address) view returns (uint256)\",\n ], runner);\n const encryptedBalance = await contract['balanceOf(address)'](userAddress);\n\n if (!encryptedBalance || encryptedBalance.toString() === '0') return '0.00';\n\n const decryptedVal = aesKey\n ? decryptCtUint64(encryptedBalance, aesKey, { decimals })\n : await decryptOptions?.decryptCtUint64?.(encryptedBalance, _readChainId, userAddress) ?? null;\n if (decryptedVal === null) {\n throw new CotiPluginError(CotiErrorCode.AES_KEY_MISMATCH, 'AES key mismatch: Error decrypting. Re-onboarding required.');\n }\n return ethers.formatUnits(decryptedVal, decimals);\n }\n\n const flatContract = new ethers.Contract(contractAddress, FLAT_BALANCE_ABI, runner);\n const encryptedBalance = await flatContract.balanceOf(userAddress);\n if (!encryptedBalance) return '0.00';\n\n const high = encryptedBalance.ciphertextHigh ?? encryptedBalance[0] ?? 0n;\n const low = encryptedBalance.ciphertextLow ?? encryptedBalance[1] ?? 0n;\n return decryptFlatCt256(high, low);\n };\n\n if (useRpcRead) {\n return await withRpcFallback(_readChainId, readBalance);\n }\n\n const runner = await (async () => {\n const browserProvider = new ethers.BrowserProvider(window.ethereum!);\n const envDefaultNetwork = getPluginConfig().defaultNetworkId;\n if (envDefaultNetwork) {\n const network = await browserProvider.getNetwork();\n if (Number(network.chainId) !== Number(envDefaultNetwork)) {\n logger.warn(`[FetchPrivate] Skipping: Wrong Network`);\n return null;\n }\n }\n // Balance reads are view calls only — use the provider directly.\n // getSigner() would invoke eth_accounts/eth_requestAccounts, which\n // pops up unconnected wallet extensions when several are installed.\n return browserProvider;\n })();\n\n if (!runner) {\n return '0.00';\n }\n\n return await readBalance(runner);\n } catch (error: unknown) {\n if (error instanceof CotiPluginError) {\n throw error;\n }\n logger.error(`❌ Failed to fetch/decrypt for ${contractAddress}`, error);\n return '0.00';\n }\n }, []);\n\n return { fetchPrivateBalance };\n};\n","/**\n * Decryption utilities for COTI confidential token balances.\n *\n * Ported from coti-snap/packages/snap/src/utils/token.ts (decryptBalance)\n * Uses @coti-io/coti-sdk-typescript for the underlying AES decryption.\n */\n\nimport {\n decryptUint,\n decryptUint256,\n} from '@coti-io/coti-sdk-typescript';\nimport type { CtUint64, CtUint256 } from '../types/ciphertext';\nimport { isCtUint256, isZeroCtUint256 } from '../types/ciphertext';\nimport { normalizeAesKey } from './aesKey';\nimport { logger } from '../lib/logger';\n\n/** Options for decryption behavior. */\nexport interface DecryptionOptions {\n /** Decimal places for formatting (0-18). Default: 18 */\n decimals?: number;\n /** Threshold multiplier for sanity check. Default: 1_000_000_000_000n (1e12) */\n insaneThresholdBase?: bigint;\n}\n\nconst DEFAULT_INSANE_THRESHOLD_BASE = 1_000_000_000_000n;\n\n/**\n * Normalizes a decimals value to a safe integer in range [0, 36].\n */\nfunction normalizeDecimals(decimals?: number | null): number {\n if (decimals === undefined || decimals === null) {\n return 18;\n }\n if (!Number.isFinite(decimals)) {\n return 18;\n }\n if (decimals < 0) {\n return 0;\n }\n if (decimals > 36) {\n return 36;\n }\n return Math.floor(decimals);\n}\n\n/**\n * Sanity check: returns true if the value exceeds plausible bounds.\n * A decrypted value is considered \"insane\" if it exceeds\n * `thresholdBase * 10^decimals`.\n *\n * @param value - The decrypted bigint value to check.\n * @param decimals - Token decimal places (0-36). Default: 18.\n * @param thresholdBase - Base threshold multiplier. Default: 1e12.\n * @returns True if the value exceeds the sanity threshold.\n */\nexport function isInsaneDecryptedValue(\n value: bigint,\n decimals?: number,\n thresholdBase?: bigint,\n): boolean {\n const safeDecimals = normalizeDecimals(decimals);\n const base = thresholdBase ?? DEFAULT_INSANE_THRESHOLD_BASE;\n const threshold = base * 10n ** BigInt(safeDecimals);\n return value > threshold;\n}\n\n/**\n * Checks if a value is zero (bigint, number, or string \"0\").\n */\nfunction isZeroValue(value: unknown): boolean {\n if (typeof value === 'bigint') {\n return value === 0n;\n }\n if (typeof value === 'number') {\n return value === 0;\n }\n if (typeof value === 'string') {\n return value === '0';\n }\n return false;\n}\n\n/**\n * Decrypts a 64-bit ciphertext value.\n * Returns the plaintext bigint, or null if AES key is missing/mismatched\n * or the decrypted value exceeds the sanity threshold.\n *\n * @param ciphertext - The 64-bit ciphertext (a single bigint).\n * @param aesKey - The user's AES key (hex string, with or without 0x prefix).\n * @param options - Optional decryption configuration.\n * @returns The decrypted plaintext bigint, or null on failure.\n */\nexport function decryptCtUint64(\n ciphertext: CtUint64,\n aesKey: string,\n options?: DecryptionOptions,\n): bigint | null {\n try {\n if (isZeroValue(ciphertext)) {\n return 0n;\n }\n\n const normalizedKey = normalizeAesKey(aesKey);\n const rawDecrypted = decryptUint(ciphertext, normalizedKey);\n const decrypted =\n typeof rawDecrypted === 'bigint' ? rawDecrypted : BigInt(rawDecrypted);\n\n if (\n isInsaneDecryptedValue(\n decrypted,\n options?.decimals,\n options?.insaneThresholdBase,\n )\n ) {\n return null;\n }\n\n return decrypted;\n } catch (error) {\n logger.error(\n '[decryptCtUint64] failed:',\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\n/**\n * Decrypts a 256-bit ciphertext value (four 64-bit segments).\n * Returns the reconstructed 256-bit plaintext bigint, or null on failure.\n *\n * Supports two on-chain representations:\n * - Nested: `{ high: { high, low }, low: { high, low } }`\n * - Flat: `{ ciphertextHigh, ciphertextLow }`\n *\n * @param ciphertext - The 256-bit ciphertext structure.\n * @param aesKey - The user's AES key (hex string, with or without 0x prefix).\n * @param options - Optional decryption configuration.\n * @returns The decrypted 256-bit plaintext bigint, or null on failure.\n */\nexport function decryptCtUint256(\n ciphertext: CtUint256,\n aesKey: string,\n options?: DecryptionOptions,\n): bigint | null {\n try {\n if (isZeroCtUint256(ciphertext)) {\n return 0n;\n }\n\n // Normalize to the flat { ciphertextHigh, ciphertextLow } shape that\n // decryptUint256 (v1.0.6+) expects. The nested on-chain shape stores the\n // same two 256-bit limbs in { high: { high, low }, low: { high, low } }.\n let flat: { ciphertextHigh: bigint; ciphertextLow: bigint };\n const ct = ciphertext as Record<string, unknown>;\n if ('ciphertextHigh' in ct && 'ciphertextLow' in ct) {\n flat = { ciphertextHigh: ct.ciphertextHigh as bigint, ciphertextLow: ct.ciphertextLow as bigint };\n } else if ('high' in ct && 'low' in ct) {\n // Nested shape: reconstruct two uint256 values from the four limbs.\n const h = ct.high as Record<string, bigint>;\n const l = ct.low as Record<string, bigint>;\n // Reconstruct two uint256 values from the four 128-bit limbs\n flat = {\n ciphertextHigh: (BigInt(h.high ?? 0n) << 128n) | BigInt(h.low ?? 0n),\n ciphertextLow: (BigInt(l.high ?? 0n) << 128n) | BigInt(l.low ?? 0n),\n };\n } else {\n // Tuple/array shape [ciphertextHigh, ciphertextLow]\n const arr = ciphertext as unknown as (bigint | number | string)[];\n flat = { ciphertextHigh: BigInt(arr[0] ?? 0), ciphertextLow: BigInt(arr[1] ?? 0) };\n }\n const decrypted = decryptUint256(flat, normalizeAesKey(aesKey));\n if (\n isInsaneDecryptedValue(\n decrypted,\n options?.decimals,\n options?.insaneThresholdBase,\n )\n ) {\n return null;\n }\n\n return decrypted;\n } catch (error) {\n logger.error(\n '[decryptCtUint256] failed:',\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\n/**\n * Unified decryption entry point that auto-detects the ciphertext variant.\n * If `variant` is not specified, uses `isCtUint256` to determine the type.\n *\n * @param balance - The ciphertext value (64-bit or 256-bit).\n * @param aesKey - The user's AES key (hex string, with or without 0x prefix).\n * @param variant - Explicit variant override (64 or 256). Auto-detected if omitted.\n * @param options - Optional decryption configuration.\n * @returns The decrypted plaintext bigint, or null on failure.\n */\nexport function decryptBalance(\n balance: CtUint64 | CtUint256,\n aesKey: string,\n variant?: 64 | 256,\n options?: DecryptionOptions,\n): bigint | null {\n const resolvedVariant =\n variant ?? (isCtUint256(balance) ? 256 : 64);\n\n if (resolvedVariant === 256) {\n return decryptCtUint256(balance as CtUint256, aesKey, options);\n }\n\n return decryptCtUint64(balance as CtUint64, aesKey, options);\n}\n\n/**\n * Formats a decrypted bigint into a human-readable decimal string.\n * Divides by 10^decimals and removes trailing zeros.\n *\n * @param value - The decrypted plaintext bigint.\n * @param decimals - The number of decimal places for the token.\n * @returns A formatted decimal string (e.g., \"1.5\" for value=1500000000000000000n, decimals=18).\n */\nexport function formatDecryptedBalance(\n value: bigint,\n decimals: number,\n): string {\n if (value === 0n) {\n return '0';\n }\n\n const safeDecimals = normalizeDecimals(decimals);\n\n if (safeDecimals === 0) {\n return value.toString();\n }\n\n const divisor = 10n ** BigInt(safeDecimals);\n const integerPart = value / divisor;\n const remainder = value % divisor;\n\n if (remainder === 0n) {\n return integerPart.toString();\n }\n\n const remainderStr = remainder.toString().padStart(safeDecimals, '0');\n const trimmed = remainderStr.replace(/0+$/, '');\n\n return `${integerPart}.${trimmed}`;\n}\n","/**\n * Ciphertext type definitions and type guards.\n *\n * NOTE: isCtUint256Shape and isZeroCtUint256 were added to @coti-io/coti-sdk-typescript\n * in v1.0.8. They are inlined here so the plugin works with older SDK versions\n * installed in consumer apps.\n */\n\n/** A single 64-bit encrypted value (uint256 containing ciphertext + randomness) */\nexport type CtUint64 = bigint;\n\n/**\n * A 256-bit encrypted value composed of four 64-bit segments.\n * Supports two on-chain representations:\n * - Flat: { ciphertextHigh, ciphertextLow } (two uint256 values)\n * - Nested: { high: { high, low }, low: { high, low } } (four uint256 values)\n */\nexport type CtUint256 =\n | { ciphertextHigh: bigint; ciphertextLow: bigint }\n | { high: { high: bigint; low: bigint }; low: { high: bigint; low: bigint } };\n\n/**\n * Type guard: checks if a value conforms to any supported CtUint256 shape.\n *\n * Recognizes three representations:\n * - Nested: { high: { high, low }, low: { high, low } }\n * - Flat: { ciphertextHigh, ciphertextLow }\n * - Tuple/array: [ciphertextHigh, ciphertextLow] (ethers.js Result tuples)\n */\nexport function isCtUint256(value: unknown): value is CtUint256 {\n if (!value || typeof value !== 'object') return false;\n const r = value as Record<string, unknown>;\n const arr = value as ArrayLike<unknown>;\n\n // Nested: { high: { high, low }, low: { high, low } }\n if (\n r.high !== null && typeof r.high === 'object' &&\n r.low !== null && typeof r.low === 'object'\n ) {\n const h = r.high as Record<string, unknown>;\n const l = r.low as Record<string, unknown>;\n if (\n 'high' in h && 'low' in h &&\n 'high' in l && 'low' in l\n ) return true;\n }\n\n // Flat: { ciphertextHigh, ciphertextLow }\n if ('ciphertextHigh' in r && 'ciphertextLow' in r) return true;\n\n // Tuple/array with at least 2 elements\n if (typeof (arr as { length?: unknown }).length === 'number' && (arr as { length: number }).length >= 2) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Type guard: checks if a CtUint256 value is all zeros.\n *\n * Returns true when:\n * - The value itself is zero (0n, 0, or \"0\")\n * - All fields in the nested structure are zero\n * - Both fields in the flat/tuple structure are zero\n *\n * Returns false for null/undefined values.\n */\nexport function isZeroCtUint256(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n\n const isZero = (v: unknown) => v === 0n || v === 0 || v === '0';\n\n if (typeof value === 'bigint' || typeof value === 'number' || typeof value === 'string') {\n return isZero(value);\n }\n\n if (typeof value !== 'object') return false;\n\n const r = value as Record<string, unknown>;\n const arr = value as ArrayLike<unknown>;\n\n // Nested: { high: { high, low }, low: { high, low } }\n if (\n r.high !== null && typeof r.high === 'object' &&\n r.low !== null && typeof r.low === 'object'\n ) {\n const h = r.high as Record<string, unknown>;\n const l = r.low as Record<string, unknown>;\n if ('high' in h && 'low' in h && 'high' in l && 'low' in l) {\n return isZero(h.high) && isZero(h.low) && isZero(l.high) && isZero(l.low);\n }\n }\n\n // Flat: { ciphertextHigh, ciphertextLow }\n if ('ciphertextHigh' in r && 'ciphertextLow' in r) {\n return isZero(r.ciphertextHigh) && isZero(r.ciphertextLow);\n }\n\n // Tuple/array: [ciphertextHigh, ciphertextLow]\n const len = typeof (arr as { length?: unknown }).length === 'number'\n ? (arr as { length: number }).length\n : -1;\n if (len >= 2) {\n return isZero(arr[0]) && isZero(arr[1]);\n }\n\n return false;\n}\n","/**\n * AES key normalization and validation utilities for COTI confidential operations.\n *\n * NOTE: This module is intentionally self-contained and does NOT import\n * normalizeAesKey from @coti-io/coti-sdk-typescript. The SDK is an external peer\n * dependency resolved at runtime from the consumer app's node_modules, and older\n * SDK releases (< 1.0.8) do not export normalizeAesKey. Inlining the logic here\n * removes the version-skew dependency and prevents the runtime crash:\n * \"normalizeSdkAesKey is not a function\"\n */\n\n/**\n * Strips \"0x\" prefix and converts to lowercase.\n * Accepts the canonical 32-char (128-bit) hex string used by COTI crypto.\n *\n * @param aesKey - The AES key string, optionally prefixed with \"0x\".\n * @returns The normalized lowercase 32-character hex string.\n * @throws Error if the key contains non-hex characters or has incorrect length.\n */\nexport function normalizeAesKey(aesKey: string | null | undefined): string {\n if (!aesKey) {\n throw new Error('AES key is required');\n }\n\n const trimmed = aesKey.startsWith('0x') ? aesKey.slice(2) : aesKey;\n const lowered = trimmed.toLowerCase();\n\n if (!/^[0-9a-f]+$/.test(lowered)) {\n throw new Error('Invalid AES key: contains non-hexadecimal characters');\n }\n\n if (lowered.length !== 32) {\n throw new Error(\n `Invalid AES key: expected 32 hex characters (128-bit), got ${lowered.length}`,\n );\n }\n\n return lowered;\n}\n\n/**\n * Validates that a string is a valid AES key (32 hex chars after normalization).\n * Returns the normalized key or throws with a descriptive error.\n *\n * @param aesKey - The AES key to validate. May be null or undefined.\n * @returns The normalized lowercase 32-character hex string.\n * @throws Error if the key is null, undefined, empty, or invalid.\n */\nexport function validateAesKey(aesKey: string | null | undefined): string {\n return normalizeAesKey(aesKey);\n}\n","import { ethers } from \"ethers\";\nimport { getPluginConfig } from \"../config/plugin\";\nimport { COTI_TESTNET_CHAIN_ID } from \"../chains/coti\";\nimport { getRpcUrlsForChain } from \"../chains/rpcUrls\";\nimport { SEPOLIA_CHAIN_ID } from \"../chains/sepolia\";\nimport { logger } from \"./logger\";\n\n/** Plugin override first, then chain primary + configured fallbacks (deduped). */\nexport const resolveRpcUrlsForChain = (chainId?: number | string | null): string[] => {\n const base = getRpcUrlsForChain(chainId);\n const numericId = chainId == null ? undefined : Number(chainId);\n if (numericId == null || !Number.isFinite(numericId)) return base;\n\n const plugin = getPluginConfig();\n let override: string | undefined;\n if (numericId === SEPOLIA_CHAIN_ID && plugin.sepoliaRpcUrl) {\n override = plugin.sepoliaRpcUrl;\n } else if (numericId === COTI_TESTNET_CHAIN_ID && plugin.cotiTestnetRpcUrl) {\n override = plugin.cotiTestnetRpcUrl;\n }\n if (!override) return base;\n return [...new Set([override, ...base])];\n};\n\nconst collectErrorText = (error: unknown): string => {\n if (!error) return \"\";\n if (typeof error === \"string\") return error;\n if (error instanceof Error) return error.message;\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n};\n\n/** True for rate limits, timeouts, and other errors worth retrying on the next RPC URL. */\nexport const isTransientRpcError = (error: unknown): boolean => {\n const text = collectErrorText(error);\n if (\n text.includes(\"Too Many Requests\")\n || text.includes(\"rate limit\")\n || text.includes(\"-32005\")\n || text.includes(\"ECONNRESET\")\n || text.includes(\"ETIMEDOUT\")\n || text.includes(\"timeout\")\n || text.includes(\"503\")\n || text.includes(\"502\")\n ) {\n return true;\n }\n if (error && typeof error === \"object\") {\n const code = (error as { code?: unknown }).code;\n if (code === \"SERVER_ERROR\" || code === \"TIMEOUT\" || code === \"NETWORK_ERROR\") {\n return true;\n }\n }\n return false;\n};\n\nexport const createJsonRpcProvider = (url: string, chainId: number) =>\n new ethers.JsonRpcProvider(url, chainId);\n\n/** Picks the first RPC endpoint that responds to `getNetwork()`. */\nexport const createResilientJsonRpcProvider = async (\n chainId: number,\n): Promise<ethers.JsonRpcProvider> => {\n const urls = resolveRpcUrlsForChain(chainId);\n let lastError: unknown;\n for (const url of urls) {\n const provider = createJsonRpcProvider(url, chainId);\n try {\n await provider.getNetwork();\n return provider;\n } catch (error) {\n lastError = error;\n if (!isTransientRpcError(error)) throw error;\n logger.warn(`[rpc] ${url} unavailable for chain ${chainId}, trying fallback`);\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error(`No RPC available for chain ${chainId}`);\n};\n\n/** Runs `fn` against each configured RPC until one succeeds or all fail. */\nexport const withRpcFallback = async <T>(\n chainId: number,\n fn: (provider: ethers.JsonRpcProvider) => Promise<T>,\n): Promise<T> => {\n const urls = resolveRpcUrlsForChain(chainId);\n let lastError: unknown;\n for (const url of urls) {\n const provider = createJsonRpcProvider(url, chainId);\n try {\n return await fn(provider);\n } catch (error) {\n lastError = error;\n if (!isTransientRpcError(error)) throw error;\n logger.warn(`[rpc] ${url} request failed for chain ${chainId}, trying fallback`);\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error(`All RPC endpoints failed for chain ${chainId}`);\n};\n","import { useCallback, useRef } from 'react';\nimport { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES, ERC20_ABI, getPublicTokensForChain, getPrivateTokensForChain } from '../contracts/config';\nimport { createResilientJsonRpcProvider } from '../lib/rpcProvider';\nimport type { Token } from './usePrivacyBridge';\nimport type { AesKeyProviderOptions } from './useAesKeyProvider';\nimport type { PrivateBalanceDecryptOptions } from './usePrivateTokenBalance';\nimport { formatTokenBalanceDisplay } from '../lib/utils';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from '../lib/logger';\nimport type { UpdateAccountStateOptions } from '../context/privacyBridge/sessionShared';\nimport {\n isAesKeyValidatedForUnlock,\n markAesKeyValidatedForUnlock,\n} from '../crypto/aesKeyValidation';\n\ninterface UseBalanceUpdaterProps {\n setWalletAddress: (address: string) => void;\n setIsConnected: (connected: boolean) => void;\n setHasSnap: (hasSnap: boolean) => void;\n setPublicTokens: React.Dispatch<React.SetStateAction<Token[]>>;\n setPrivateTokens: React.Dispatch<React.SetStateAction<Token[]>>;\n checkNetwork: (provider: ethers.BrowserProvider) => Promise<void>;\n getAESKeyFromSnap: (\n accountAddress: string,\n options?: { skipCache?: boolean } & AesKeyProviderOptions,\n ) => Promise<string | null>;\n fetchPrivateBalance: (userAddress: string, aesKey: string, contractAddress: string, version: 64 | 256, decimals?: number, readChainId?: number, isPlainBalance?: boolean, decryptOptions?: PrivateBalanceDecryptOptions) => Promise<string>;\n canUseSnapOperations?: boolean;\n snapDecryptOptions?: PrivateBalanceDecryptOptions;\n sessionAesKey?: string | null;\n setSessionAesKey: (key: string | null, keyWallet?: string) => void;\n /** MetaMask-only: read-only Snap key validation on explicit unlock. */\n validateMetaMaskAesKeyOnUnlock?: (\n snapKey: string,\n accountAddress: string,\n connectedChainId?: number | null,\n ) => Promise<void>;\n}\n\n/**\n * Custom hook to handle account state updates and balance fetching.\n * Dynamically iterates over SUPPORTED_TOKENS filtered by chain — no hardcoded token lists.\n *\n * @param props - State setters and helper functions required for updating the account.\n * @returns An object containing the `updateAccountState` function.\n */\nexport const useBalanceUpdater = ({\n setWalletAddress,\n setIsConnected,\n setHasSnap,\n setPublicTokens,\n setPrivateTokens,\n checkNetwork,\n getAESKeyFromSnap,\n fetchPrivateBalance,\n canUseSnapOperations = false,\n snapDecryptOptions,\n sessionAesKey,\n setSessionAesKey,\n validateMetaMaskAesKeyOnUnlock,\n}: UseBalanceUpdaterProps) => {\n const updateGenerationRef = useRef(0);\n\n const updateAccountState = useCallback(async (\n account: string,\n checkSnap = false,\n fetchPrivate = false,\n aesKeyOverride?: string | null,\n chainOverride?: number,\n options?: UpdateAccountStateOptions & AesKeyProviderOptions,\n ) => {\n const generation = ++updateGenerationRef.current;\n const isStale = () => generation !== updateGenerationRef.current;\n const validateOnUnlock = options?.validateOnUnlock === true;\n\n try {\n setWalletAddress(account);\n setIsConnected(true);\n const allowSnapOperations =\n canUseSnapOperations\n && !options?.forceContractOnboarding\n && (!options?.restoreOnly || options?.snapSideDecrypt === true);\n const deferPublicBalances =\n options?.restoreOnly === true\n && fetchPrivate\n && !aesKeyOverride\n && !sessionAesKey;\n\n const hasChainOverride = typeof chainOverride === 'number';\n\n if (!(window.ethereum || hasChainOverride)) {\n if (fetchPrivate) {\n logger.warn('Cannot fetch private balances without wallet provider or chain override');\n return false;\n }\n return true;\n }\n\n if (window.ethereum || hasChainOverride) {\n const browserProvider = window.ethereum && !hasChainOverride\n ? new ethers.BrowserProvider(window.ethereum)\n : null;\n const forceContractOnboarding = options?.forceContractOnboarding === true;\n const effectiveSessionAesKey = forceContractOnboarding ? null : sessionAesKey;\n const needsAesKeyFetch =\n fetchPrivate\n && !aesKeyOverride\n && !effectiveSessionAesKey\n && checkSnap\n && !(allowSnapOperations && options?.snapSideDecrypt);\n let restoredAesKey: string | null = aesKeyOverride ?? effectiveSessionAesKey ?? null;\n\n if (deferPublicBalances && needsAesKeyFetch) {\n logger.log('⚡ Restore-only unlock: fetching AES key before balance RPCs');\n const { validateOnUnlock: _validateOnUnlock, ...aesKeyOptions } = options ?? {};\n restoredAesKey = validateOnUnlock\n ? await getAESKeyFromSnap(account, { skipCache: true, ...aesKeyOptions })\n : await getAESKeyFromSnap(account, aesKeyOptions);\n if (isStale()) return false;\n if (!restoredAesKey) {\n return false;\n }\n }\n\n if (browserProvider && !deferPublicBalances) {\n await checkNetwork(browserProvider);\n if (isStale()) return false;\n }\n\n const currentChainId = hasChainOverride\n ? chainOverride\n : Number((await browserProvider!.getNetwork()).chainId);\n if (isStale()) return false;\n\n const addresses = CONTRACT_ADDRESSES[currentChainId];\n if (fetchPrivate && !addresses) {\n logger.warn(`No contract addresses configured for chain ${currentChainId}`);\n return false;\n }\n const readProvider = hasChainOverride\n ? await createResilientJsonRpcProvider(currentChainId)\n : browserProvider!;\n\n // ─── Public Balances (dynamic) ──────────────────────────────────\n if (!deferPublicBalances) {\n const publicTokenConfigs = getPublicTokensForChain(currentChainId);\n\n // Fetch native balance (used for tokens without addressKey, e.g. COTI)\n const nativeBalanceWei = await readProvider.getBalance(account);\n const nativeBalance = ethers.formatEther(nativeBalanceWei);\n\n // Fetch all ERC20 public balances in parallel\n const publicBalances = await Promise.all(publicTokenConfigs.map(async token => {\n // Native token — show chain coin balance (wrapped address is only for the portal contract).\n if (!token.addressKey || token.isNative) {\n return nativeBalance;\n }\n const tokenAddress = addresses?.[token.addressKey];\n if (!tokenAddress) return '0';\n try {\n const contract = new ethers.Contract(tokenAddress, ERC20_ABI, readProvider);\n const bal = await contract.balanceOf(account);\n return ethers.formatUnits(bal, token.decimals);\n } catch {\n return '0';\n }\n }));\n\n if (isStale()) return false;\n\n logger.log('✅ Updating public tokens list');\n setPublicTokens(publicTokenConfigs.map((token, index) => ({\n symbol: token.symbol,\n name: token.name,\n balance: formatTokenBalanceDisplay(token.symbol, publicBalances[index]),\n isPrivate: false,\n icon: token.icon,\n addressKey: token.addressKey,\n bridgeAddressKey: token.bridgeAddressKey,\n decimals: token.decimals,\n isNative: token.isNative,\n supportedChainIds: token.supportedChainIds,\n })));\n }\n // ─── Private Balances (dynamic) ─────────────────────────────────\n if (addresses && fetchPrivate) {\n try {\n let aesKey: string | null = restoredAesKey;\n let markValidatedAfterSuccess = false;\n\n if (needsAesKeyFetch && !aesKey) {\n const { validateOnUnlock: _validateOnUnlock, ...aesKeyOptions } = options ?? {};\n if (validateOnUnlock) {\n aesKey = Object.keys(aesKeyOptions).length === 0\n ? await getAESKeyFromSnap(account, { skipCache: true })\n : await getAESKeyFromSnap(account, { skipCache: true, ...aesKeyOptions });\n } else {\n aesKey = options === undefined\n ? await getAESKeyFromSnap(account)\n : await getAESKeyFromSnap(account, aesKeyOptions);\n }\n if (isStale()) return false;\n if (!aesKey) {\n logger.log('ℹ️ AES key required for unlock but unavailable (cancelled or failed).');\n return false;\n }\n }\n\n if (\n aesKey\n && validateOnUnlock\n && validateMetaMaskAesKeyOnUnlock\n && !options?.forceContractOnboarding\n && !isAesKeyValidatedForUnlock(account, aesKey)\n ) {\n await validateMetaMaskAesKeyOnUnlock(aesKey, account, currentChainId);\n if (isStale()) return false;\n markValidatedAfterSuccess = true;\n }\n\n if (aesKey && options?.forceContractOnboarding) {\n markValidatedAfterSuccess = true;\n }\n\n if (allowSnapOperations) {\n if (isStale()) return false;\n setHasSnap(true);\n }\n\n const privateTokenConfigs = getPrivateTokensForChain(currentChainId);\n const publicTokenConfigs = getPublicTokensForChain(currentChainId);\n // Private tokens backed by a native public asset (p.ETH, p.AVAX, p.COTI)\n // store a plain uint256 balance; ERC-20-style pTokens use flat ctUint256.\n const hasPlainPrivateTokens = privateTokenConfigs.some(token => {\n const publicSymbol = token.symbol.replace(/^p\\./, '');\n return !!publicTokenConfigs.find(t => t.symbol === publicSymbol)?.isNative;\n });\n\n if (!aesKey && !allowSnapOperations && !hasPlainPrivateTokens) {\n logger.log('ℹ️ Snap available but keys missing/rejected.');\n return false;\n }\n\n if (aesKey || allowSnapOperations || hasPlainPrivateTokens) {\n logger.log('🔄 Fetching private balances...');\n\n const privateFetches = await Promise.all(privateTokenConfigs.map(async token => {\n const tokenAddress = token.addressKey ? addresses[token.addressKey] : undefined;\n if (!tokenAddress) {\n return { symbol: token.symbol, value: '0', isMismatch: false };\n }\n const publicSymbol = token.symbol.replace(/^p\\./, '');\n const pubCfg = publicTokenConfigs.find(t => t.symbol === publicSymbol);\n const isPlainBalance = !!pubCfg?.isNative;\n logger.log(`[BalanceUpdater] ${token.symbol} balance route`, {\n tokenAddress,\n decimals: token.decimals,\n publicSymbol,\n publicIsNative: pubCfg?.isNative ?? false,\n isPlainBalance,\n chainId: currentChainId,\n });\n if (!aesKey && !allowSnapOperations && !isPlainBalance) {\n return { symbol: token.symbol, value: '0', isMismatch: false };\n }\n try {\n const value = await fetchPrivateBalance(\n account,\n aesKey ?? '',\n tokenAddress,\n 256,\n token.decimals,\n currentChainId,\n isPlainBalance,\n allowSnapOperations ? snapDecryptOptions : undefined,\n );\n return { symbol: token.symbol, value, isMismatch: false };\n } catch (e: any) {\n const msg = e?.message || '';\n const isMismatch =\n msg.includes('AES key mismatch') ||\n msg.includes('onboarding') ||\n msg.includes('ACCOUNT_NOT_ONBOARDED') ||\n msg.includes('implausible decrypted balance');\n if (isMismatch) {\n logger.warn(`⚠️ Private token decrypt mismatch for ${tokenAddress}. Falling back to 0.`);\n return { symbol: token.symbol, value: '0', isMismatch: true };\n }\n throw e;\n }\n }));\n\n if (isStale()) return false;\n\n const mismatchCount = privateFetches.filter(r => r.isMismatch).length;\n\n if (mismatchCount > 0) {\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n `AES key mismatch for ${mismatchCount} private token(s). Re-onboarding required.`,\n );\n }\n\n logger.log('🔐 Updating private tokens list');\n setPrivateTokens(privateTokenConfigs.map(token => {\n const result = privateFetches.find(r => r.symbol === token.symbol);\n return {\n symbol: token.symbol,\n name: token.name,\n balance: formatTokenBalanceDisplay(token.symbol, result?.value ?? '0'),\n isPrivate: true,\n icon: token.icon,\n addressKey: token.addressKey,\n bridgeAddressKey: token.bridgeAddressKey,\n decimals: token.decimals,\n supportedChainIds: token.supportedChainIds,\n };\n }));\n if (aesKey) {\n if (isStale()) return false;\n if (markValidatedAfterSuccess) {\n markAesKeyValidatedForUnlock(account, aesKey);\n }\n setSessionAesKey(aesKey, account);\n }\n return true;\n }\n } catch (privateError: any) {\n if (isStale()) return false;\n logger.warn('⚠️ Could not fetch/decrypt private balance on load:', privateError);\n if (privateError instanceof CotiPluginError) {\n throw privateError;\n }\n return false;\n }\n }\n }\n return true;\n } catch (error: any) {\n if (isStale()) return false;\n logger.error('Error updating account state:', error);\n if (error instanceof CotiPluginError) {\n throw error;\n }\n return false;\n }\n }, [setWalletAddress, setHasSnap, setIsConnected, setPublicTokens, checkNetwork, getAESKeyFromSnap, fetchPrivateBalance, canUseSnapOperations, setPrivateTokens, sessionAesKey, setSessionAesKey, validateMetaMaskAesKeyOnUnlock]);\n\n return { updateAccountState };\n};\n","export const TOKEN_BALANCE_DISPLAY_DECIMALS: Record<string, number> = {\n COTI: 4,\n \"p.COTI\": 4,\n WETH: 6,\n \"p.WETH\": 6,\n USDC: 4,\n \"p.USDC\": 4,\n USDT: 4,\n \"p.USDT\": 4,\n WBTC: 6,\n \"p.WBTC\": 6,\n WADA: 6,\n \"p.WADA\": 6,\n};\n\nexport function expandExponentialNumber(numStr: string): string {\n const eString = numStr.toLowerCase();\n if (!eString.includes('e')) return numStr;\n\n const [base, exp] = eString.split('e');\n const expNum = parseInt(exp, 10);\n\n let [intPart, decPart = ''] = base.split('.');\n if (expNum === 0) return `${intPart}.${decPart}`;\n\n if (expNum > 0) {\n decPart = decPart.padEnd(expNum, '0');\n return `${intPart}${decPart.slice(0, expNum)}.${decPart.slice(expNum)}`;\n } else {\n const absExp = Math.abs(expNum);\n intPart = intPart.padStart(absExp + 1, '0');\n return `${intPart.slice(0, -absExp)}.${intPart.slice(-absExp)}${decPart}`;\n }\n}\n\nexport function truncateDecimalValue(value: string | number, decimals: number): string {\n let numStr = String(value);\n if (numStr === '' || numStr === 'NaN') return '0';\n\n numStr = expandExponentialNumber(numStr);\n\n const [integerPart, decimalPart] = numStr.split('.');\n if (!decimalPart || decimals === 0) {\n return integerPart;\n }\n\n let truncatedDecimal = decimalPart.slice(0, decimals);\n\n // Remove trailing zeros\n truncatedDecimal = truncatedDecimal.replace(/0+$/, '');\n\n return truncatedDecimal ? `${integerPart}.${truncatedDecimal}` : integerPart;\n}\n\nexport function formatTokenBalanceDisplay(symbol: string, balance: string | number): string {\n const decimals = TOKEN_BALANCE_DISPLAY_DECIMALS[symbol] ?? 4;\n return truncateDecimalValue(balance, decimals);\n}\n\nexport function addThousandsSeparators(value: string | number): string {\n const [rawIntegerPart, decimalPart] = String(value).split('.');\n let integerPart = rawIntegerPart;\n integerPart = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n return decimalPart !== undefined ? `${integerPart}.${decimalPart}` : integerPart;\n}\n\nexport function formatBalanceWithNotation(value: string | number): string {\n const numValue = parseFloat(String(value));\n\n if (numValue === 0 || Math.abs(numValue) < 1) {\n return addThousandsSeparators(value);\n }\n\n const hasDecimals = String(value).includes('.') && parseFloat(String(value)) % 1 !== 0;\n\n if (hasDecimals) {\n return addThousandsSeparators(value);\n }\n\n const absValue = Math.abs(numValue);\n const sign = numValue < 0 ? '-' : '';\n\n if (absValue >= 1_000_000_000_000) {\n const exactValue = absValue / 1_000_000_000_000;\n const truncated = Math.floor(exactValue * 100) / 100;\n const formatted = truncated.toString().replace(/\\.0+$/, '');\n return `${sign}${formatted}T`;\n } else if (absValue >= 1_000_000_000) {\n const exactValue = absValue / 1_000_000_000;\n const truncated = Math.floor(exactValue * 100) / 100;\n const formatted = truncated.toString().replace(/\\.0+$/, '');\n return `${sign}${formatted}B`;\n } else if (absValue >= 1_000_000) {\n const exactValue = absValue / 1_000_000;\n const truncated = Math.floor(exactValue * 100) / 100;\n const formatted = truncated.toString().replace(/\\.0+$/, '');\n return `${sign}${formatted}M`;\n }\n\n return addThousandsSeparators(value);\n}\n","import { encodeKey, encodeUint, encrypt, decryptUint, decodeUint } from '@coti-io/coti-sdk-typescript';\nimport { ethers } from 'ethers';\nimport { normalizeAesKey } from './aesKey';\nimport { decryptCtUint256 } from './decryption';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { guardedEthAccounts } from '../lib/metaMaskMobile';\nimport { logger } from '../lib/logger';\nimport type { EIP1193Provider } from '../lib/ethereum';\nimport { CONTRACT_ADDRESSES, getPrivateTokensForChain, getPublicTokensForChain } from '../contracts/config';\nimport { withRpcFallback } from '../lib/rpcProvider';\n\n/** Fixed plaintext used for local encrypt/decrypt round-trip validation. */\nconst ROUND_TRIP_TEST_VALUE = 0x0123456789abcdefn;\n\nconst FLAT_BALANCE_ABI = [\n 'function balanceOf(address) view returns (tuple(uint256 ciphertextHigh, uint256 ciphertextLow))',\n];\n\n/** Returns the 128-bit SDK key material (Snap may store 256-bit hex). */\nexport function getSdkAesKeyHex(aesKey: string): string {\n const trimmed = aesKey.startsWith('0x') ? aesKey.slice(2) : aesKey;\n const lowered = trimmed.toLowerCase();\n if (/^[0-9a-f]{64}$/.test(lowered)) {\n return lowered.slice(0, 32);\n }\n return normalizeAesKey(aesKey);\n}\n\n/**\n * Encrypts and decrypts a fixed test value with the given AES key.\n * Returns true when the round-trip succeeds.\n */\nexport function validateAesKeyRoundTrip(aesKey: string): boolean {\n try {\n const sdkKey = getSdkAesKeyHex(aesKey);\n const keyBytes = encodeKey(sdkKey);\n const plainBytes = encodeUint(ROUND_TRIP_TEST_VALUE);\n const { ciphertext, r } = encrypt(keyBytes, plainBytes);\n const ct = new Uint8Array(ciphertext.length + r.length);\n ct.set(ciphertext, 0);\n ct.set(r, ciphertext.length);\n const decrypted = decryptUint(decodeUint(ct), sdkKey);\n const decryptedBigInt = typeof decrypted === 'bigint' ? decrypted : BigInt(decrypted);\n return decryptedBigInt === ROUND_TRIP_TEST_VALUE;\n } catch (error) {\n logger.warn(\n '[validateAesKeyRoundTrip] failed:',\n error instanceof Error ? error.message : error,\n );\n return false;\n }\n}\n\n/**\n * Compares two AES keys that may differ in length (32 vs 64 hex chars).\n */\nexport function aesKeysEquivalent(a: string, b: string): boolean {\n return getSdkAesKeyHex(a) === getSdkAesKeyHex(b);\n}\n\n/**\n * Ensures MetaMask's active account matches the connected dApp address.\n */\nexport async function assertMetaMaskActiveAccount(\n provider: EIP1193Provider,\n expectedAddress: string,\n): Promise<void> {\n const accounts = await guardedEthAccounts(provider);\n const active = accounts[0]?.toLowerCase();\n const expected = expectedAddress.toLowerCase();\n if (!active || active !== expected) {\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n 'MetaMask active account does not match the connected wallet. Switch accounts in MetaMask and try again.',\n );\n }\n}\n\nasync function readEncryptedBalance(\n provider: ethers.JsonRpcProvider,\n tokenAddress: string,\n account: string,\n): Promise<unknown | null> {\n try {\n const flatContract = new ethers.Contract(tokenAddress, FLAT_BALANCE_ABI, provider);\n return await flatContract.balanceOf(account);\n } catch (error) {\n logger.warn('[validateAesKeyAgainstOnChainCiphertext] balanceOf read failed:', error);\n return null;\n }\n}\n\nfunction tryDecryptEncryptedBalance(\n encrypted: unknown,\n aesKey: string,\n decimals: number,\n): boolean | null {\n const record = encrypted as Record<string, unknown>;\n const arrayValue = encrypted as ArrayLike<unknown>;\n const high = (record.ciphertextHigh ?? arrayValue[0] ?? 0n) as bigint;\n const low = (record.ciphertextLow ?? arrayValue[1] ?? 0n) as bigint;\n if (high === 0n && low === 0n) return null;\n\n const decrypted = decryptCtUint256({ ciphertextHigh: high, ciphertextLow: low }, aesKey, { decimals });\n return decrypted !== null;\n}\n\n/**\n * Read-only validation: decrypts existing on-chain ciphertext via RPC (no wallet transactions).\n * When every non-zero ciphertext fails to decrypt, the AES key is treated as invalid.\n */\nexport async function validateAesKeyAgainstOnChainCiphertext(\n aesKey: string,\n account: string,\n chainId: number,\n): Promise<void> {\n const addresses = CONTRACT_ADDRESSES[chainId];\n if (!addresses) return;\n\n const privateTokenConfigs = getPrivateTokensForChain(chainId);\n const publicTokenConfigs = getPublicTokensForChain(chainId);\n\n let sawNonZeroCiphertext = false;\n let validated = false;\n\n await withRpcFallback(chainId, async provider => {\n for (const token of privateTokenConfigs) {\n if (!token.addressKey) continue;\n const tokenAddress = addresses[token.addressKey];\n if (!tokenAddress) continue;\n\n const publicSymbol = token.symbol.replace(/^p\\./, '');\n const pubCfg = publicTokenConfigs.find(t => t.symbol === publicSymbol);\n if (pubCfg?.isNative) continue;\n\n const encrypted = await readEncryptedBalance(provider, tokenAddress, account);\n if (!encrypted) continue;\n\n const decryptResult = tryDecryptEncryptedBalance(encrypted, aesKey, token.decimals ?? 18);\n if (decryptResult === null) continue;\n\n sawNonZeroCiphertext = true;\n if (decryptResult) {\n logger.log(`[validateAesKeyAgainstOnChainCiphertext] key validated via ${token.symbol}`);\n validated = true;\n return;\n }\n }\n });\n\n if (validated) return;\n\n if (sawNonZeroCiphertext) {\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n 'AES key cannot decrypt on-chain private balances for this account. Re-onboarding required.',\n );\n }\n}\n\n/**\n * Validates a MetaMask Snap AES key on unlock without wallet transactions:\n * 1. Local encrypt/decrypt round-trip\n * 2. Active account matches connected address\n * 3. Read-only decrypt probe against on-chain ciphertext (when present)\n */\nexport async function validateMetaMaskAesKeyOnUnlock(\n snapKey: string,\n address: string,\n walletProvider: EIP1193Provider,\n chainId?: number | null,\n): Promise<void> {\n if (!validateAesKeyRoundTrip(snapKey)) {\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n 'AES key failed encrypt/decrypt validation. Re-onboarding required.',\n );\n }\n\n await assertMetaMaskActiveAccount(walletProvider, address);\n\n if (typeof chainId === 'number') {\n await validateAesKeyAgainstOnChainCiphertext(snapKey, address, chainId);\n }\n}\n\n/** Session-scoped registry of AES keys that passed unlock validation for a wallet. */\nconst validatedUnlockKeys = new Map<string, string>();\n\nexport function markAesKeyValidatedForUnlock(address: string, aesKey: string): void {\n validatedUnlockKeys.set(\n address.toLowerCase(),\n getSdkAesKeyHex(aesKey).toLowerCase(),\n );\n}\n\nexport function clearAesKeyValidatedForUnlock(address?: string): void {\n if (address) {\n validatedUnlockKeys.delete(address.toLowerCase());\n } else {\n validatedUnlockKeys.clear();\n }\n}\n\nexport function isAesKeyValidatedForUnlock(address: string, aesKey: string): boolean {\n const stored = validatedUnlockKeys.get(address.toLowerCase());\n if (!stored) return false;\n return stored === getSdkAesKeyHex(aesKey).toLowerCase();\n}\n\nexport function getValidatedAesKeyForUnlock(address: string): string | null {\n return validatedUnlockKeys.get(address.toLowerCase()) ?? null;\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES, BRIDGE_ABI, BRIDGE_ERC20_ABI, ERC20_ABI, SUPPORTED_TOKENS } from '../contracts/config';\nimport { fetchBridgeFees, BridgeFees } from './useBridgeFees';\nimport { getRpcUrlForChainId } from '../config/chains';\nimport { getChainConfig } from '../chains';\nimport { fetchPodBridgeData } from '../chains/portal/podPortalAdminData';\nimport { logger } from '../lib/logger';\n\nexport interface BridgeData extends BridgeFees {\n bridgeName: string;\n bridgeAddress: string;\n publicToken: string;\n publicTokenIcon: string;\n privateToken: string;\n privateTokenIcon: string;\n minDepositAmount: string;\n maxDepositAmount: string;\n minWithdrawAmount: string;\n maxWithdrawAmount: string;\n accumulatedFees: string;\n accumulatedCotiFees: string;\n nativeCotiFee: string;\n bridgeBalance: string;\n isPaused: boolean;\n tokenDecimals: number;\n /** Symbol the fee values are denominated in (native coin on PoD chains; COTI otherwise). */\n feeTokenSymbol?: string;\n isLoading: boolean;\n error: string | null;\n}\n\nexport const useBridgeData = (chainId: number) => {\n const [bridgesData, setBridgesData] = useState<BridgeData[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [refreshTrigger, setRefreshTrigger] = useState(0);\n\n const refresh = useCallback(() => {\n setRefreshTrigger(prev => prev + 1);\n }, []);\n\n useEffect(() => {\n const fetchBridgeData = async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n // PoD chains (Sepolia/Fuji): portals expose a different interface —\n // read fee configs live instead of calling COTI bridge getters.\n if (getChainConfig(chainId)?.portalStrategy === 'pod-privacy-portal') {\n setBridgesData(await fetchPodBridgeData(chainId));\n return;\n }\n\n const addresses = CONTRACT_ADDRESSES[chainId as keyof typeof CONTRACT_ADDRESSES];\n\n if (!addresses) {\n // Chain has no bridge contracts (e.g. Sepolia) — return empty data\n setBridgesData([]);\n return;\n }\n\n const rpcUrl = getRpcUrlForChainId(chainId);\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const bridges: BridgeData[] = [];\n\n const bridgeTokens = SUPPORTED_TOKENS.filter(\n token => !token.isPrivate\n && token.bridgeAddressKey\n && (!token.supportedChainIds || token.supportedChainIds.includes(chainId))\n );\n\n for (const token of bridgeTokens) {\n /* v8 ignore next -- unreachable: bridgeTokens filter requires bridgeAddressKey */\n if (!token.bridgeAddressKey) continue;\n\n const bridgeAddress = addresses[token.bridgeAddressKey as keyof typeof addresses] as string;\n\n if (!bridgeAddress || bridgeAddress === '') {\n logger.warn(`Bridge address not found for ${token.symbol}`);\n continue;\n }\n\n try {\n // Native token: no addressKey (e.g. COTI on COTI chain, ETH on Sepolia)\n const isNative = !token.addressKey;\n const abi = isNative ? BRIDGE_ABI : BRIDGE_ERC20_ABI;\n const contract = new ethers.Contract(bridgeAddress, abi, provider);\n\n const tokenAddress = token.addressKey\n ? addresses[token.addressKey as keyof typeof addresses] as string\n : null;\n\n const balancePromise = isNative\n ? contract.getBridgeBalance().catch(() => '0')\n : tokenAddress\n ? new ethers.Contract(tokenAddress, ERC20_ABI, provider)\n .balanceOf(bridgeAddress).catch(() => '0')\n : Promise.resolve('0');\n\n const [fees, accCotiFees, paused, balance, minDeposit, maxDeposit, minWithdraw, maxWithdraw] = await Promise.all([\n fetchBridgeFees(bridgeAddress, isNative, provider),\n contract.accumulatedCotiFees().catch(() => '0'),\n contract.paused().catch(() => false),\n balancePromise,\n contract.minDepositAmount().catch(() => '0'),\n contract.maxDepositAmount().catch(() => '0'),\n contract.minWithdrawAmount().catch(() => '0'),\n contract.maxWithdrawAmount().catch(() => '0'),\n ]);\n\n const privateToken = SUPPORTED_TOKENS.find(\n t => t.isPrivate && t.bridgeAddressKey === token.bridgeAddressKey\n );\n\n bridges.push({\n bridgeName: `${token.symbol} Bridge`,\n bridgeAddress,\n publicToken: token.symbol,\n publicTokenIcon: token.icon,\n privateToken: privateToken?.symbol || 'N/A', /* v8 ignore branch */\n privateTokenIcon: privateToken?.icon || '', /* v8 ignore branch */\n ...fees,\n minDepositAmount: ethers.formatUnits(minDeposit, token.decimals),\n maxDepositAmount: ethers.formatUnits(maxDeposit, token.decimals),\n minWithdrawAmount: ethers.formatUnits(minWithdraw, token.decimals),\n maxWithdrawAmount: ethers.formatUnits(maxWithdraw, token.decimals),\n accumulatedFees: '0',\n accumulatedCotiFees: ethers.formatEther(accCotiFees),\n nativeCotiFee: '0',\n bridgeBalance: ethers.formatUnits(balance, token.decimals),\n isPaused: paused,\n tokenDecimals: token.decimals,\n isLoading: false,\n error: null,\n });\n } catch (err) {\n logger.error(`Error fetching data for ${token.symbol} bridge:`, err);\n bridges.push({\n bridgeName: `${token.symbol} Bridge`,\n bridgeAddress,\n publicToken: token.symbol,\n publicTokenIcon: token.icon,\n privateToken: 'N/A',\n privateTokenIcon: '',\n depositFixedFee: 'Error',\n depositPercentageBps: 'Error',\n depositMaxFee: 'Error',\n withdrawFixedFee: 'Error',\n withdrawPercentageBps: 'Error',\n withdrawMaxFee: 'Error',\n minDepositAmount: 'Error',\n maxDepositAmount: 'Error',\n minWithdrawAmount: 'Error',\n maxWithdrawAmount: 'Error',\n accumulatedFees: 'Error',\n accumulatedCotiFees: 'Error',\n nativeCotiFee: 'Error',\n bridgeBalance: 'Error',\n isPaused: false,\n tokenDecimals: token.decimals,\n isLoading: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n }\n\n setBridgesData(bridges);\n } catch (err) {\n logger.error('Error fetching bridge data:', err);\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setIsLoading(false);\n }\n };\n\n if (chainId) {\n fetchBridgeData();\n }\n }, [chainId, refreshTrigger]);\n\n return { bridgesData, isLoading, error, refresh };\n};\n","import { ethers } from 'ethers';\nimport { BRIDGE_ABI, BRIDGE_ERC20_ABI, COTI_PRICE_CONSUMER_ABI, CONTRACT_ADDRESSES } from '../contracts/config';\nimport { getRpcUrlForChainId } from '../config/chains';\nimport { logger } from '../lib/logger';\n\n/**\n * Maps bridge token symbols to the `_base` argument of the COTI price consumer's\n * `getPrice(string)` view function. Mirrors what the on-chain bridge passes when\n * resolving prices.\n */\nconst SYMBOL_TO_ORACLE_BASE: Record<string, string> = {\n COTI: 'COTI',\n WETH: 'ETH',\n WBTC: 'WBTC',\n USDT: 'USDT',\n USDC: 'USDC',\n 'USDC.e': 'USDC',\n WADA: 'ADA',\n // gCOTI is not in the on-chain price consumer\n};\n\n/**\n * Resolves the COTI price-consumer address for the given chain id.\n * Falls back to the testnet oracle when the chain id is unknown.\n */\nfunction getPriceConsumerAddress(chainId: number = 7082400): string {\n const addresses = (CONTRACT_ADDRESSES as Record<number, Record<string, string>>)[chainId];\n return addresses?.CotiPriceConsumer || (CONTRACT_ADDRESSES as any)[7082400].CotiPriceConsumer;\n}\n\n/**\n * Fetches the current USD price for a token symbol via the on-chain\n * COTI price consumer (replaces the previous Band Protocol RPC call).\n *\n * The consumer returns a fixed-point uint256 with 18 decimals.\n *\n * @param symbol - Token symbol (e.g. \"WETH\", \"WBTC\", \"USDT\", \"COTI\")\n * @param provider - Optional ethers provider; defaults to COTI testnet RPC\n * @param chainId - Optional chain id; controls which oracle address is used\n * @returns USD price as a number, or null if unavailable\n */\nexport async function fetchTokenUsdPrice(\n symbol: string,\n provider?: ethers.JsonRpcProvider | ethers.BrowserProvider,\n chainId: number = 7082400,\n): Promise<number | null> {\n const base = SYMBOL_TO_ORACLE_BASE[symbol];\n if (!base) {\n logger.warn(`No on-chain price mapping for symbol: ${symbol}`);\n return null;\n }\n\n try {\n const rpcProvider = provider || new ethers.JsonRpcProvider(getRpcUrlForChainId(chainId));\n const oracleAddress = getPriceConsumerAddress(chainId);\n const contract = new ethers.Contract(oracleAddress, COTI_PRICE_CONSUMER_ABI, rpcProvider);\n const raw: bigint = await contract.getPrice(base);\n // Price is returned as 18-decimal fixed point (same scale as parseEther)\n return Number(ethers.formatEther(raw));\n } catch (err: any) {\n // The consumer can revert with StaleOracleData(uint256, uint256) when the\n // underlying IStdReference data is older than `maxStaleness`.\n const decoded = err?.revert?.name === 'StaleOracleData'\n ? `oracle data stale (lastUpdated=${err.revert.args?.[0]}, threshold=${err.revert.args?.[1]})`\n : err?.shortMessage || err?.message || 'unknown error';\n logger.error(`Error fetching on-chain USD price for ${symbol}: ${decoded}`);\n return null;\n }\n}\n\nexport interface BridgeFees {\n depositFixedFee: string;\n depositPercentageBps: string;\n depositMaxFee: string;\n withdrawFixedFee: string;\n withdrawPercentageBps: string;\n withdrawMaxFee: string;\n}\n\nconst ERROR_FEES: BridgeFees = {\n depositFixedFee: 'Error',\n depositPercentageBps: 'Error',\n depositMaxFee: 'Error',\n withdrawFixedFee: 'Error',\n withdrawPercentageBps: 'Error',\n withdrawMaxFee: 'Error',\n};\n\n/**\n * Fetches the dynamic fee parameters (fixedFee, percentageBps, maxFee) for\n * both deposit and withdraw from a bridge contract.\n *\n * @param bridgeAddress - On-chain address of the bridge contract\n * @param isNativeBridge - true for the native COTI bridge, false for ERC-20 bridges\n * @param provider - An ethers JsonRpcProvider (or compatible)\n * @returns Formatted BridgeFees with COTI values in ether and bps as raw string\n */\nexport async function fetchBridgeFees(\n bridgeAddress: string,\n isNativeBridge: boolean,\n provider: ethers.JsonRpcProvider\n): Promise<BridgeFees> {\n try {\n const abi = isNativeBridge ? BRIDGE_ABI : BRIDGE_ERC20_ABI;\n const contract = new ethers.Contract(bridgeAddress, abi, provider);\n\n const [\n depositFixedFee,\n depositPercentageBps,\n depositMaxFee,\n withdrawFixedFee,\n withdrawPercentageBps,\n withdrawMaxFee,\n ] = await Promise.all([\n contract.depositFixedFee().catch(() => '0'),\n contract.depositPercentageBps().catch(() => '0'),\n contract.depositMaxFee().catch(() => '0'),\n contract.withdrawFixedFee().catch(() => '0'),\n contract.withdrawPercentageBps().catch(() => '0'),\n contract.withdrawMaxFee().catch(() => '0'),\n ]);\n\n return {\n depositFixedFee: ethers.formatEther(depositFixedFee),\n depositPercentageBps: depositPercentageBps.toString(),\n depositMaxFee: ethers.formatEther(depositMaxFee),\n withdrawFixedFee: ethers.formatEther(withdrawFixedFee),\n withdrawPercentageBps: withdrawPercentageBps.toString(),\n withdrawMaxFee: ethers.formatEther(withdrawMaxFee),\n };\n } catch (err) {\n logger.error(`Error fetching fees for bridge ${bridgeAddress}:`, err);\n return ERROR_FEES;\n }\n}\n\n// ─── Fee Computation (mirrors Solidity logic) ────────────────────────────────\n\nconst FEE_DIVISOR = 1_000_000n;\n\n/**\n * Dynamic fee: take the greater of percentageFee and fixedFee, then cap at maxFee.\n * All values in wei (bigint).\n */\nfunction calculateDynamicFee(percentageFee: bigint, fixedFee: bigint, maxFee: bigint): bigint {\n const fee = percentageFee > fixedFee ? percentageFee : fixedFee;\n return maxFee > 0n && fee > maxFee ? maxFee : fee;\n}\n\n/**\n * Compute the bridge fee for a native COTI deposit/withdraw.\n * Mirrors the Solidity `_computeCotiFee` function.\n *\n * @param cotiAmount - Amount in COTI (human-readable, e.g. \"10.5\")\n * @param fixedFee - Floor fee in COTI (human-readable)\n * @param percentageBps - Basis points relative to FEE_DIVISOR (raw number string)\n * @param maxFee - Cap fee in COTI (human-readable)\n * @param cotiUsdPrice - Current COTI price in USD (from Band Protocol)\n * @returns Fee in COTI as a human-readable string\n */\nexport function computeCotiFee(\n cotiAmount: string,\n fixedFee: string,\n percentageBps: string,\n maxFee: string,\n cotiUsdPrice: number\n): string {\n const amountWei = ethers.parseEther(cotiAmount);\n const fixedFeeWei = ethers.parseEther(fixedFee);\n const maxFeeWei = ethers.parseEther(maxFee);\n const bps = BigInt(percentageBps);\n\n // cotiUsdRate as 18-decimal fixed point (same scale as Solidity oracle)\n const cotiUsdRate = ethers.parseEther(cotiUsdPrice.toString());\n\n // txValueUsd = (cotiAmount * cotiUsdRate) / 1e18\n const txValueUsd = (amountWei * cotiUsdRate) / ethers.WeiPerEther;\n\n // percentageFeeUsd = (txValueUsd * percentageBps) / FEE_DIVISOR\n const percentageFeeUsd = (txValueUsd * bps) / FEE_DIVISOR;\n\n // percentageFeeCoti = (percentageFeeUsd * 1e18) / cotiUsdRate\n const percentageFeeCoti = cotiUsdRate > 0n\n ? (percentageFeeUsd * ethers.WeiPerEther) / cotiUsdRate\n : 0n;\n\n const fee = calculateDynamicFee(percentageFeeCoti, fixedFeeWei, maxFeeWei);\n return ethers.formatEther(fee);\n}\n\n/**\n * Compute the bridge fee for an ERC-20 token deposit/withdraw.\n * Mirrors the Solidity `_computeErc20Fee` function.\n * The fee is denominated in COTI.\n *\n * @param tokenAmount - Amount in token units (human-readable, e.g. \"1.5\")\n * @param tokenDecimals - Decimals of the ERC-20 token (e.g. 18, 8, 6)\n * @param fixedFee - Floor fee in COTI (human-readable)\n * @param percentageBps - Basis points relative to FEE_DIVISOR (raw number string)\n * @param maxFee - Cap fee in COTI (human-readable)\n * @param tokenUsdPrice - Current token price in USD (from Band Protocol)\n * @param cotiUsdPrice - Current COTI price in USD (from Band Protocol)\n * @returns Fee in COTI as a human-readable string\n */\nexport function computeErc20Fee(\n tokenAmount: string,\n tokenDecimals: number,\n fixedFee: string,\n percentageBps: string,\n maxFee: string,\n tokenUsdPrice: number,\n cotiUsdPrice: number\n): string {\n const amountWei = ethers.parseUnits(tokenAmount, tokenDecimals);\n const fixedFeeWei = ethers.parseEther(fixedFee);\n const maxFeeWei = ethers.parseEther(maxFee);\n const bps = BigInt(percentageBps);\n\n // tokenUsdRate as 18-decimal fixed point\n const tokenUsdRate = ethers.parseEther(tokenUsdPrice.toString());\n const cotiUsdRate = ethers.parseEther(cotiUsdPrice.toString());\n\n // txValueUsd = (tokenAmount * tokenUsdRate) / 10^tokenDecimals\n const tokenUnit = 10n ** BigInt(tokenDecimals);\n const txValueUsd = (amountWei * tokenUsdRate) / tokenUnit;\n\n // percentageFeeUsd = (txValueUsd * percentageBps) / FEE_DIVISOR\n const percentageFeeUsd = (txValueUsd * bps) / FEE_DIVISOR;\n\n // percentageFeeCoti = (percentageFeeUsd * 1e18) / cotiUsdRate\n const percentageFeeCoti = cotiUsdRate > 0n\n ? (percentageFeeUsd * ethers.WeiPerEther) / cotiUsdRate\n : 0n;\n\n const fee = calculateDynamicFee(percentageFeeCoti, fixedFeeWei, maxFeeWei);\n return ethers.formatEther(fee);\n}\n\n// ─── Unified Fee Simulation (on-chain call to bridge.computeCotiFee / computeErc20Fee) ─────────────\n\n/** ABI fragments for the on-chain fee simulation view functions */\nconst SIMULATE_FEE_NATIVE_ABI = [\n 'function computeCotiFee(uint256 amount, uint256 fixedFee, uint256 percentageBps, uint256 maxFee) view returns (uint256 fee)',\n] as const;\n\nconst SIMULATE_FEE_ERC20_ABI = [\n 'function computeErc20Fee(uint256 amount, uint256 fixedFee, uint256 percentageBps, uint256 maxFee, string tokenSymbol, uint8 tokenDecimals) view returns (uint256 fee)',\n] as const;\n\n/** Maps bridge token symbols to their Band oracle symbol */\nconst TOKEN_TO_ORACLE_SYMBOL: Record<string, string> = {\n COTI: 'COTI',\n WETH: 'ETH',\n WBTC: 'WBTC',\n USDT: 'USDT',\n 'USDC.e': 'USDC',\n WADA: 'ADA',\n gCOTI: 'GCOTI',\n};\n\n/** Maps bridge token symbols to their decimals */\nconst TOKEN_DECIMALS: Record<string, number> = {\n COTI: 18,\n WETH: 18,\n WBTC: 8,\n USDT: 6,\n 'USDC.e': 6,\n WADA: 6,\n gCOTI: 18,\n};\n\nexport interface SimulationResult {\n fee: string;\n explanation: string;\n}\n\n/**\n * Call the on-chain fee simulation view function on a bridge contract.\n * - Native COTI bridge: calls computeCotiFee(amount, fixedFee, percentageBps, maxFee)\n * - ERC-20 bridges: calls computeErc20Fee(amount, fixedFee, percentageBps, maxFee, tokenSymbol, tokenDecimals)\n *\n * @param bridgeAddress - Address of the bridge contract\n * @param amount - Token amount (human-readable, e.g. \"1.5\")\n * @param fixedFee - Floor fee in COTI (human-readable, e.g. \"10\")\n * @param percentageBps - Basis points relative to FEE_DIVISOR (raw number string, e.g. \"500\")\n * @param maxFee - Cap fee in COTI (human-readable, e.g. \"3000\")\n * @param oracleSymbol - Oracle symbol: \"COTI\" for native, \"ETH\"/\"WBTC\"/\"USDT\"/\"USDC\"/\"ADA\" for ERC-20\n * @param tokenDecimals - Token decimals (18, 8, or 6)\n * @param provider - An ethers provider\n * @returns SimulationResult with fee in COTI and explanation\n */\nexport async function simulateFeeOnChain(\n bridgeAddress: string,\n amount: string,\n fixedFee: string,\n percentageBps: string,\n maxFee: string,\n oracleSymbol: string,\n tokenDecimals: number,\n provider: ethers.JsonRpcProvider | ethers.BrowserProvider\n): Promise<SimulationResult> {\n try {\n const amountWei = ethers.parseUnits(amount, tokenDecimals);\n const fixedFeeWei = ethers.parseEther(fixedFee || '0');\n const bpsNum = parseInt(percentageBps || '0');\n const maxFeeWei = ethers.parseEther(maxFee || '0');\n\n const isNative = oracleSymbol === 'COTI';\n let fee: bigint;\n\n if (isNative) {\n const contract = new ethers.Contract(bridgeAddress, SIMULATE_FEE_NATIVE_ABI, provider);\n fee = await contract.computeCotiFee(amountWei, fixedFeeWei, bpsNum, maxFeeWei);\n } else {\n const contract = new ethers.Contract(bridgeAddress, SIMULATE_FEE_ERC20_ABI, provider);\n fee = await contract.computeErc20Fee(amountWei, fixedFeeWei, bpsNum, maxFeeWei, oracleSymbol, tokenDecimals);\n }\n\n const feeFormatted = parseFloat(ethers.formatEther(fee)).toFixed(4);\n\n // Determine which rule was applied\n let explanation: string;\n if (fee === maxFeeWei && maxFeeWei > 0n) {\n explanation = 'Max fee cap applied';\n } else if (fee === fixedFeeWei) {\n explanation = 'Fixed fee floor applied';\n } else {\n explanation = 'Percentage fee applied';\n }\n\n return { fee: feeFormatted, explanation };\n } catch (err) {\n logger.error('simulateFeeOnChain error:', err);\n return { fee: '—', explanation: 'Contract call failed' };\n }\n}\n\n/**\n * Helper to get oracle symbol and decimals for a bridge token symbol.\n */\nexport function getTokenSimulationMeta(tokenSymbol: string): { oracleSymbol: string; decimals: number } {\n return {\n oracleSymbol: TOKEN_TO_ORACLE_SYMBOL[tokenSymbol] || tokenSymbol,\n decimals: TOKEN_DECIMALS[tokenSymbol] || 18,\n };\n}\n","/**\n * @deprecated Import viem chains and RPC helpers from `../chains` or `../chains/viemChains` instead.\n * Re-exported for backward compatibility with existing `config/chains` import paths.\n */\nexport {\n cotiMainnet,\n cotiTestnet,\n sepolia,\n avalancheFuji,\n ethereumMainnet,\n ETHEREUM_MAINNET_CHAIN_ID,\n ETHEREUM_MAINNET_RPC,\n COTI_MAINNET_RPC,\n COTI_TESTNET_RPC,\n SEPOLIA_RPC,\n SEPOLIA_RPC_FALLBACK,\n AVALANCHE_FUJI_RPC,\n AVALANCHE_FUJI_RPC_FALLBACK,\n getRpcUrlForChainId,\n chainConfigToViemChain,\n} from '../chains/viemChains';\n\nexport { getRpcUrlsForChain } from '../chains';\n\nexport {\n COTI_MAINNET_CHAIN_ID,\n COTI_TESTNET_CHAIN_ID,\n SEPOLIA_CHAIN_ID,\n} from '../chains';\n","import { useMemo } from 'react';\nimport { BridgeData } from './useBridgeData';\n\nexport type BridgeStatus = 'active' | 'paused';\n\nexport function useBridgeStatus(bridge: BridgeData) {\n return useMemo<BridgeStatus>(\n () => (bridge.isPaused ? 'paused' : 'active'),\n [bridge.isPaused]\n );\n}\n","import { getPrivateTokensForChain, getPublicTokensForChain } from '../../chains';\nimport type { Token } from './types';\n\nexport type { Token };\n\nexport const getInitialPublicTokens = (chainId?: number): Token[] =>\n getPublicTokensForChain(chainId).map(t => ({\n symbol: t.symbol,\n name: t.name,\n balance: '0.00',\n isPrivate: false,\n icon: t.icon,\n addressKey: t.addressKey,\n bridgeAddressKey: t.bridgeAddressKey,\n decimals: t.decimals,\n isNative: t.isNative,\n supportedChainIds: t.supportedChainIds,\n }));\n\nexport const getInitialPrivateTokens = (chainId?: number): Token[] =>\n getPrivateTokensForChain(chainId).map(t => ({\n symbol: t.symbol,\n name: t.name,\n balance: '0.00',\n isPrivate: true,\n icon: t.icon,\n addressKey: t.addressKey,\n bridgeAddressKey: t.bridgeAddressKey,\n decimals: t.decimals,\n supportedChainIds: t.supportedChainIds,\n }));\n","import { ethers } from 'ethers';\nimport { normalizeAesKey } from '../../crypto/aesKey';\nimport { getEthereumProvider, type EIP1193Provider } from '../../lib/ethereum';\nimport { logger } from '../../lib/logger';\nimport { CONTRACT_ADDRESSES } from '../../contracts/config';\nimport { getPrivateTokensForChain } from '../../chains';\nimport { encryptValue256 } from './encryptValue256';\nimport { shortHash } from './utils';\n\n/** Matches coti-snap useTokenOperations private 256-bit transfer selector. */\nexport const PRIVATE_ERC20_TRANSFER_256_SIG =\n 'transfer(address,((uint256,uint256),bytes))';\n\nconst GAS_ESTIMATE_BUFFER_PERCENT = 105n;\nconst CONFIDENTIAL_TRANSFER_GAS_LIMIT = 2_000_000n;\n\nconst TRANSFER_INTERFACE = new ethers.Interface([\n 'function transfer(address to, tuple(tuple(uint256 ciphertextHigh, uint256 ciphertextLow) ciphertext, bytes signature) value) returns (uint256)',\n]);\n\nexport interface ExecutePrivateTokenTransferParams {\n /** Private token contract address */\n tokenAddress: string;\n /** Recipient wallet address */\n recipient: string;\n /** Human-readable amount (e.g. \"1.5\") */\n amount: string;\n /** Token decimals for amount parsing */\n decimals: number;\n /** 32-byte AES key hex (with or without 0x prefix) */\n aesKey: string;\n /** Connected wallet address (tx sender) */\n walletAddress: string;\n /** Optional EIP-1193 provider; defaults to window.ethereum */\n provider?: EIP1193Provider | null;\n}\n\nexport interface ExecutePrivateTokenTransferResult {\n txHash: string;\n}\n\ntype ItUint256TransferPayload = {\n ciphertext: { ciphertextHigh: bigint; ciphertextLow: bigint };\n signature: string;\n};\n\ninterface SendPrivateTokenTransferParams {\n chainId: number;\n symbol: string;\n recipient: string;\n amount: string;\n walletAddress: string;\n provider?: EIP1193Provider | null;\n sessionAesKey?: string | null;\n hasSnap?: boolean;\n getAESKeyFromSnap?: (accountAddress: string) => Promise<string | null>;\n}\n\nexport function normalizeAesKeyHex(aesKey: string): string {\n try {\n return normalizeAesKey(aesKey);\n } catch {\n throw new Error('AES key must be a 32-hex-character string.');\n }\n}\n\nexport function resolvePrivateTokenContractAddress(\n chainId: number,\n addressKey: string,\n): string | undefined {\n const addresses = CONTRACT_ADDRESSES[chainId];\n if (!addresses) return undefined;\n const resolved = addresses[addressKey as keyof typeof addresses];\n return resolved || undefined;\n}\n\nexport function resolvePrivateTokenTransferTarget(\n chainId: number,\n symbol: string,\n): { tokenAddress: string; decimals: number; addressKey: string } | null {\n const token = getPrivateTokensForChain(chainId).find(t => t.symbol === symbol);\n if (!token?.addressKey) return null;\n\n const tokenAddress = resolvePrivateTokenContractAddress(chainId, token.addressKey);\n if (!tokenAddress) return null;\n\n return {\n tokenAddress,\n decimals: token.decimals ?? 18,\n addressKey: token.addressKey,\n };\n}\n\nfunction validatePrivateTransferInputs(\n tokenAddress: string,\n recipient: string,\n amount: string,\n walletAddress: string,\n): void {\n if (!ethers.isAddress(tokenAddress)) {\n throw new Error('Invalid token contract address');\n }\n if (!ethers.isAddress(recipient)) {\n throw new Error('Invalid recipient address');\n }\n if (recipient.toLowerCase() === walletAddress.toLowerCase()) {\n throw new Error('Cannot send to your own address');\n }\n if (!amount?.trim() || !Number.isFinite(Number(amount)) || Number(amount) <= 0) {\n throw new Error('Amount must be greater than zero');\n }\n}\n\nfunction parseTransferAmountWei(amount: string, decimals: number): bigint {\n let amountWei: bigint;\n try {\n amountWei = ethers.parseUnits(amount, decimals);\n } catch {\n throw new Error('Invalid amount for token decimals');\n }\n if (amountWei <= 0n) {\n throw new Error('Amount must be greater than zero');\n }\n return amountWei;\n}\n\nasync function submitPrivateTokenTransferTx(params: {\n tokenAddress: string;\n recipient: string;\n amount: string;\n walletAddress: string;\n itValue: ItUint256TransferPayload;\n provider: EIP1193Provider;\n}): Promise<ExecutePrivateTokenTransferResult> {\n const { tokenAddress, recipient, amount, walletAddress, itValue, provider: eip1193 } = params;\n\n const calldata = TRANSFER_INTERFACE.encodeFunctionData('transfer', [\n recipient,\n [[itValue.ciphertext.ciphertextHigh, itValue.ciphertext.ciphertextLow], itValue.signature],\n ]);\n\n let gasLimit = CONFIDENTIAL_TRANSFER_GAS_LIMIT;\n try {\n const estimateHex = await eip1193.request({\n method: 'eth_estimateGas',\n params: [\n {\n from: walletAddress,\n to: tokenAddress,\n data: calldata,\n },\n ],\n });\n gasLimit = (BigInt(estimateHex as string) * GAS_ESTIMATE_BUFFER_PERCENT) / 100n;\n } catch (err) {\n logger.warn('Private transfer gas estimation failed, using fallback', err);\n }\n\n logger.log('Sending private token transfer', {\n token: shortHash(tokenAddress),\n recipient: shortHash(recipient),\n amount,\n });\n\n const browserProvider = new ethers.BrowserProvider(eip1193);\n const rawTxHash = (await eip1193.request({\n method: 'eth_sendTransaction',\n params: [\n {\n from: walletAddress,\n to: tokenAddress,\n data: calldata,\n gas: `0x${gasLimit.toString(16)}`,\n },\n ],\n })) as string;\n\n logger.log('Waiting for private transfer tx', { txHash: shortHash(rawTxHash) });\n const receipt = await browserProvider.waitForTransaction(rawTxHash);\n if (!receipt || receipt.status !== 1) {\n throw new Error('Private token transfer failed');\n }\n\n return { txHash: rawTxHash };\n}\n\n/**\n * Sends a private ERC-20 transfer (256-bit itUint256) to another address.\n *\n * Flow mirrors coti-snap transferERC20 (256-bit branch) and portal private approve:\n * encrypt + signMessage, encode transfer calldata, estimate gas, eth_sendTransaction.\n */\nexport async function executePrivateTokenTransfer(\n params: ExecutePrivateTokenTransferParams,\n): Promise<ExecutePrivateTokenTransferResult> {\n const {\n tokenAddress,\n recipient,\n amount,\n decimals,\n aesKey,\n walletAddress,\n provider: injectedProvider,\n } = params;\n\n validatePrivateTransferInputs(tokenAddress, recipient, amount, walletAddress);\n\n const eip1193 = injectedProvider ?? getEthereumProvider();\n if (!eip1193) {\n throw new Error('No wallet found');\n }\n\n const normalizedAesKey = normalizeAesKeyHex(aesKey);\n const provider = new ethers.BrowserProvider(eip1193);\n // Pass walletAddress so ethers targets the connected account instead of\n // calling eth_requestAccounts, which pops up unconnected wallet extensions.\n const signer = await provider.getSigner(walletAddress);\n const amountWei = parseTransferAmountWei(amount, decimals);\n const transferSig = ethers.id(PRIVATE_ERC20_TRANSFER_256_SIG).slice(0, 10);\n const itValue = await encryptValue256(\n amountWei,\n normalizedAesKey,\n tokenAddress,\n transferSig,\n walletAddress,\n signer,\n );\n\n return submitPrivateTokenTransferTx({\n tokenAddress,\n recipient,\n amount,\n walletAddress,\n itValue,\n provider: eip1193,\n });\n}\n\n/**\n * Plugin-owned private send — resolves token metadata and encrypts via session key\n * or Snap without exposing the AES key to dApp code.\n */\nexport async function sendPrivateTokenTransfer(\n params: SendPrivateTokenTransferParams,\n): Promise<ExecutePrivateTokenTransferResult> {\n const {\n chainId,\n symbol,\n recipient,\n amount,\n walletAddress,\n provider: injectedProvider,\n sessionAesKey,\n hasSnap,\n getAESKeyFromSnap,\n } = params;\n\n const target = resolvePrivateTokenTransferTarget(chainId, symbol);\n if (!target) {\n throw new Error('This token is not supported for send on this network.');\n }\n\n validatePrivateTransferInputs(target.tokenAddress, recipient, amount, walletAddress);\n\n const eip1193 = injectedProvider ?? getEthereumProvider();\n if (!eip1193) {\n throw new Error('No wallet found');\n }\n\n const browserProvider = new ethers.BrowserProvider(eip1193);\n // Pass walletAddress so ethers targets the connected account instead of\n // calling eth_requestAccounts, which pops up unconnected wallet extensions.\n const signer = await browserProvider.getSigner(walletAddress);\n const amountWei = parseTransferAmountWei(amount, target.decimals);\n const transferSig = ethers.id(PRIVATE_ERC20_TRANSFER_256_SIG).slice(0, 10);\n\n let aesKey = sessionAesKey ? normalizeAesKeyHex(sessionAesKey) : null;\n if (!aesKey && hasSnap && getAESKeyFromSnap) {\n const snapKey = await getAESKeyFromSnap(walletAddress);\n if (snapKey) {\n aesKey = normalizeAesKeyHex(snapKey);\n }\n }\n\n if (!aesKey) {\n throw new Error('Private balances are locked. Unlock to send tokens.');\n }\n\n const itValue = await encryptValue256(\n amountWei,\n aesKey,\n target.tokenAddress,\n transferSig,\n walletAddress,\n signer,\n );\n\n return submitPrivateTokenTransferTx({\n tokenAddress: target.tokenAddress,\n recipient,\n amount,\n walletAddress,\n itValue,\n provider: eip1193,\n });\n}\n","import { buildItUint256WithSigner } from '@coti-io/coti-sdk-typescript';\nimport { ethers } from 'ethers';\nimport { normalizeAesKey } from '../../crypto/aesKey';\n\n/**\n * Builds a signed 256-bit COTI input-text value for a browser wallet signer.\n * Delegates to SDK `buildItUint256WithSigner` (browser-wallet signing path).\n */\nexport async function encryptValue256(\n amountWei: bigint,\n aesKeyHex: string,\n contractAddress: string,\n functionSelector: string,\n walletAddress: string,\n signer: ethers.JsonRpcSigner,\n): Promise<{\n ciphertext: { ciphertextHigh: bigint; ciphertextLow: bigint };\n signature: string;\n}> {\n const result = await buildItUint256WithSigner({\n value: amountWei,\n aesKey: normalizeAesKey(aesKeyHex),\n signerAddress: walletAddress,\n contractAddress,\n functionSelector,\n signMessage: (message) => signer.signMessage(message),\n });\n\n return {\n ciphertext: {\n ciphertextHigh: result.ciphertext.ciphertextHigh,\n ciphertextLow: result.ciphertext.ciphertextLow,\n },\n signature: result.signature,\n };\n}\n","export const shortHash = (value: string | undefined | null) =>\n value && value.length > 12 ? `${value.slice(0, 10)}…` : value ?? 'n/a';\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { useAccount } from 'wagmi';\nimport { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES, ERC20_ABI } from '../../contracts/config';\nimport type { PodWithdrawPermit } from '../../chains/portal/executePodPortalTransaction';\nimport { signPodWithdrawPermit } from '../../chains/portal/executePodPortalTransaction';\nimport { getPrivateTokensForChain, getPublicTokensForChain } from '../../chains';\nimport {\n findPublicTokenConfig,\n isPodPortalPublicToken,\n podPortalNotConfiguredError,\n resolveConfiguredAddress,\n resolvePodPortalAddresses,\n skipsPublicDepositApproval,\n} from '../../chains/portal/helpers';\nimport { logger } from '../../lib/logger';\nimport { decryptCtUint256 } from '../../crypto/decryption';\nimport { encryptValue256 } from './encryptValue256';\nimport { shortHash } from './utils';\nimport type { Token, ToastState } from './types';\nimport { getMetaMaskProvider } from '../../lib/ethereum';\nimport { useSnap } from '../useSnap';\n\nexport interface UsePrivacyBridgeAllowanceOptions {\n isConnected: boolean;\n walletAddress: string;\n publicTokens: Token[];\n amount: string;\n direction: 'to-private' | 'to-public';\n selectedTokenIndex: number;\n hasSnap: boolean;\n setToastState: React.Dispatch<React.SetStateAction<ToastState>>;\n /** In-memory session AES key — avoids Snap/provider calls when available. */\n sessionAesKey?: string | null;\n chainId?: number;\n}\n\n/** ERC20 / encrypted private token allowance checks and approvals. */\nexport const usePrivacyBridgeAllowance = ({\n isConnected,\n walletAddress,\n publicTokens,\n amount,\n direction,\n selectedTokenIndex,\n hasSnap,\n setToastState,\n sessionAesKey,\n chainId,\n}: UsePrivacyBridgeAllowanceOptions) => {\n const [allowance, setAllowance] = useState<string>('0');\n const [isApproving, setIsApproving] = useState(false);\n const [podWithdrawPermit, setPodWithdrawPermit] = useState<PodWithdrawPermit | null>(null);\n /** Synchronous store so transfer can run in the same tick as approve (before React re-renders). */\n const podWithdrawPermitRef = useRef<PodWithdrawPermit | null>(null);\n const { decryptCtUint256ViaSnap, buildItUint256ViaSnap } = useSnap();\n\n const clearPodWithdrawPermit = useCallback(() => {\n podWithdrawPermitRef.current = null;\n setPodWithdrawPermit(null);\n }, []);\n\n useEffect(() => {\n clearPodWithdrawPermit();\n }, [walletAddress, clearPodWithdrawPermit]);\n\n const getPodWithdrawPermit = useCallback(\n (): PodWithdrawPermit | null => podWithdrawPermitRef.current ?? podWithdrawPermit,\n [podWithdrawPermit],\n );\n\n const isPodWithdrawPermitStale = useCallback((\n permit: PodWithdrawPermit | null,\n token: Token | undefined,\n activeChainId?: number,\n ): boolean => {\n if (!permit || !walletAddress || !token) return true;\n try {\n const decimals = token.decimals ?? 18;\n const amountWei = ethers.parseUnits(amount || '0', decimals).toString();\n if (permit.wallet.toLowerCase() !== walletAddress.toLowerCase()) return true;\n if (permit.amountWei !== amountWei) return true;\n\n const resolvedChainId = activeChainId ?? chainId;\n if (!resolvedChainId) return false;\n\n const addresses = CONTRACT_ADDRESSES[resolvedChainId];\n const pubCfg = getPublicTokensForChain(resolvedChainId).find(\n t => t.symbol === token.symbol && !t.isPrivate,\n );\n const privCfg = getPrivateTokensForChain(resolvedChainId).find(\n t => t.symbol === `p.${token.symbol.replace(/^p\\./, '')}`,\n );\n const resolved = pubCfg && addresses\n ? resolvePodPortalAddresses({ addresses, pubCfg, privCfg })\n : null;\n if (!resolved) return true;\n\n return (\n permit.portalAddress.toLowerCase() !== resolved.portalAddress.toLowerCase()\n || permit.pTokenAddress.toLowerCase() !== resolved.pTokenAddress.toLowerCase()\n );\n } catch {\n return true;\n }\n }, [amount, chainId, walletAddress]);\n\n // The wagmi connector for the wallet the user actually selected (Rabby, MetaMask, etc.).\n // We resolve the EIP-1193 provider from this connector instead of reading window.ethereum,\n // which is unreliable when multiple wallet extensions compete for the global.\n const { connector } = useAccount();\n\n /**\n * Resolves the EIP-1193 provider for the connected wallet.\n * Prefers the wagmi connector's provider (the exact wallet the user chose),\n * falling back to window.ethereum only if the connector can't supply one.\n */\n const resolveInjectedProvider = useCallback(async (): Promise<any> => {\n if (connector?.getProvider) {\n try {\n const connectorProvider = await connector.getProvider();\n if (connectorProvider) return connectorProvider;\n } catch (e) {\n logger.warn('[Approve] connector.getProvider() failed, falling back to window.ethereum', e);\n }\n }\n return getMetaMaskProvider() ?? window.ethereum;\n }, [connector]);\n\n const checkAllowance = useCallback(async () => {\n if (!isConnected || !walletAddress) return;\n\n const token = publicTokens[selectedTokenIndex];\n const injectedProvider = await resolveInjectedProvider();\n if (!injectedProvider) return;\n const provider = new ethers.BrowserProvider(injectedProvider);\n const network = await provider.getNetwork();\n const currentChainId = Number(network.chainId);\n const pubCfgEarly = findPublicTokenConfig(currentChainId, token?.symbol ?? \"\");\n\n // Native deposits skip ERC-20 approve; PoD withdraw uses a typed permit instead of allowance.\n if (skipsPublicDepositApproval(pubCfgEarly, direction)) {\n setAllowance('999999999999999999');\n return;\n }\n if (direction === 'to-public' && isPodPortalPublicToken(currentChainId, pubCfgEarly)) {\n setAllowance('999999999999999999');\n return;\n }\n\n // Reset to 0 to prevent stale state from previous token\n setAllowance('0');\n\n try {\n const addresses = CONTRACT_ADDRESSES[currentChainId];\n\n let tokenAddress: string | undefined;\n let bridgeAddress: string | undefined;\n let decimals = 18;\n\n const pubCfg = getPublicTokensForChain(currentChainId).find(\n t => t.symbol === token.symbol && !t.isPrivate\n );\n if (pubCfg?.bridgeAddressKey && addresses) {\n bridgeAddress = resolveConfiguredAddress(addresses, pubCfg.bridgeAddressKey);\n }\n if (pubCfg?.addressKey && addresses) {\n tokenAddress = resolveConfiguredAddress(addresses, pubCfg.addressKey);\n }\n if (pubCfg) {\n decimals = pubCfg.decimals;\n }\n\n if (!bridgeAddress) {\n if (token.symbol === 'WETH') {\n tokenAddress = addresses?.WETH;\n bridgeAddress = addresses?.PrivacyBridgeWETH;\n decimals = 18;\n } else if (token.symbol === 'WBTC') {\n tokenAddress = addresses?.WBTC;\n bridgeAddress = addresses?.PrivacyBridgeWBTC;\n decimals = 8;\n } else if (token.symbol === 'USDT') {\n tokenAddress = addresses?.USDT;\n bridgeAddress = addresses?.PrivacyBridgeUSDT;\n decimals = 6;\n } else if (token.symbol === 'USDC.e') {\n tokenAddress = addresses?.USDC_E;\n bridgeAddress = addresses?.PrivacyBridgeUSDCe;\n decimals = 6;\n } else if (token.symbol === 'WADA') {\n tokenAddress = addresses?.WADA;\n bridgeAddress = addresses?.PrivacyBridgeWADA;\n decimals = 18;\n } else if (token.symbol === 'gCOTI') {\n tokenAddress = addresses?.gCOTI;\n bridgeAddress = addresses?.PrivacyBridgegCOTI;\n decimals = 18;\n } else if (token.symbol === 'COTI') {\n // Native COTI: no public tokenAddress, but bridge address is needed for to-public allowance check\n bridgeAddress = addresses?.PrivacyBridgeCotiNative;\n }\n }\n\n // For to-private (deposit), ERC-20 needs token + bridge; native portal tokens only need bridge.\n const isNativeDeposit = !!pubCfg?.isNative;\n if (direction === 'to-private' && !isNativeDeposit && (!tokenAddress || !bridgeAddress)) return;\n if (direction === 'to-private' && isNativeDeposit && !bridgeAddress) return;\n if (!bridgeAddress) return;\n\n let currentAllowance = 0n;\n\n // Check direction to decide which token to check\n if (direction === 'to-public') {\n // For Portal Out, we need to check the allowance of the Private Token.\n // Resolving private token address and decimals\n let privateTokenKey = \"\";\n let privateDecimals = 18;\n if (token.symbol === 'COTI') {\n privateTokenKey = 'PrivateCoti';\n privateDecimals = 18;\n } else {\n privateTokenKey = 'p.' + token.symbol;\n if (token.symbol === 'WETH' || token.symbol === 'gCOTI') privateDecimals = 18;\n else if (token.symbol === 'WBTC') privateDecimals = 8;\n else privateDecimals = 6; // USDT, USDC.e, WADA\n }\n if (token.symbol === 'USDC.e') privateTokenKey = 'p.USDC_E';\n\n const privateTokenAddress = addresses[privateTokenKey];\n if (!privateTokenAddress) {\n setAllowance('0');\n return;\n }\n\n const privTokCfg = getPrivateTokensForChain(currentChainId).find(\n pt =>\n !!pt.addressKey &&\n addresses[pt.addressKey as keyof typeof addresses] === privateTokenAddress\n );\n if (privTokCfg) privateDecimals = privTokCfg.decimals;\n\n try {\n const tokenContract = new ethers.Contract(privateTokenAddress, [\n \"function allowance(address owner, address spender) view returns (tuple(tuple(uint256 ciphertextHigh, uint256 ciphertextLow) ciphertext, tuple(uint256 ciphertextHigh, uint256 ciphertextLow) ownerCiphertext, tuple(uint256 ciphertextHigh, uint256 ciphertextLow) spenderCiphertext))\"\n ], provider);\n \n const currentAllowance = await tokenContract.allowance(walletAddress, bridgeAddress);\n\n // If the allowance is clearly uninitialized or 0, return early:\n if (currentAllowance.ownerCiphertext.ciphertextHigh === 0n &&\n currentAllowance.ownerCiphertext.ciphertextLow === 0n) {\n setAllowance('0');\n return;\n }\n\n // Attempt dynamic decryption without exposing AES to the dApp.\n // Snap wallets decrypt inside Snap; non-Snap wallets use the plugin session key.\n if (hasSnap || sessionAesKey) {\n try {\n const ciphertext = {\n ciphertextHigh: currentAllowance.ownerCiphertext.ciphertextHigh,\n ciphertextLow: currentAllowance.ownerCiphertext.ciphertextLow\n };\n const decryptedVal = sessionAesKey\n ? decryptCtUint256(ciphertext, sessionAesKey, { decimals: privateDecimals })\n : await decryptCtUint256ViaSnap(ciphertext, currentChainId, walletAddress);\n\n if (decryptedVal === null) {\n setAllowance('0');\n } else {\n setAllowance(ethers.formatUnits(decryptedVal, privateDecimals));\n }\n return;\n } catch (decryptErr) {\n logger.warn(\"Could not decrypt private allowance, defaulting to 0\", decryptErr);\n }\n }\n\n // If no AES key or user rejected, fall back to 0 so they can re-approve\n setAllowance('0');\n } catch (e) {\n logger.warn(\"Could not check private allowance, defaulting to 0\", e);\n setAllowance('0');\n }\n return;\n } else {\n // Public Token Allowance Check\n /* v8 ignore next 3 -- unreachable: to-private without tokenAddress returns above */\n if (!tokenAddress) {\n setAllowance('0');\n return;\n }\n const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);\n currentAllowance = await tokenContract.allowance(walletAddress, bridgeAddress);\n }\n\n setAllowance(ethers.formatUnits(currentAllowance, decimals));\n } catch (err) {\n logger.error(\"Failed to check allowance\", err);\n setAllowance('0');\n }\n }, [isConnected, walletAddress, selectedTokenIndex, publicTokens, hasSnap, direction, sessionAesKey, resolveInjectedProvider, decryptCtUint256ViaSnap]);\n\n // Auto-check allowance on dependencies change\n useEffect(() => {\n checkAllowance();\n }, [checkAllowance]);\n\n /**\n * Initiates the token approval transaction.\n * Sets `isApproving` to true during the process and shows toast notifications.\n */\n const handleApprove = async () => {\n if (!isConnected || !walletAddress) return;\n\n const token = publicTokens[selectedTokenIndex];\n if (direction === 'to-private' && (token?.isNative || (token?.symbol === 'COTI' && !token.addressKey))) return;\n\n try {\n // Resolve the provider from the connected wallet's wagmi connector,\n // NOT window.ethereum, which is unreliable with multiple wallets installed.\n const injectedProvider = await resolveInjectedProvider();\n const provider = new ethers.BrowserProvider(injectedProvider);\n\n // Guardrail: request only the connected account from the provider.\n // Using getSigner() without an address argument can trigger popups from\n // other installed wallets (MetaMask, Rabby, Trust, etc.) when they compete\n // for window.ethereum. By passing the known walletAddress, ethers will call\n // eth_requestAccounts only if needed and validate the returned address,\n // preventing a different wallet from hijacking the signing request.\n logger.log('[Approve] Requesting signer for connected address', { walletAddress, connectorId: connector?.id });\n const signer = await provider.getSigner(walletAddress);\n const network = await provider.getNetwork();\n const currentChainId = Number(network.chainId);\n const addresses = CONTRACT_ADDRESSES[currentChainId];\n\n let tokenAddress: string | undefined;\n let bridgeAddress: string | undefined;\n let decimals = 18;\n\n const pubCfgApprove = getPublicTokensForChain(currentChainId).find(\n t => t.symbol === token.symbol && !t.isPrivate\n );\n if (pubCfgApprove?.bridgeAddressKey && addresses) {\n bridgeAddress = resolveConfiguredAddress(addresses, pubCfgApprove.bridgeAddressKey);\n }\n if (pubCfgApprove?.addressKey && addresses) {\n tokenAddress = resolveConfiguredAddress(addresses, pubCfgApprove.addressKey);\n }\n if (pubCfgApprove) {\n decimals = pubCfgApprove.decimals;\n }\n\n if (!bridgeAddress) {\n // Resolve Addresses based on Token\n if (token.symbol === 'WETH') {\n tokenAddress = addresses?.WETH;\n bridgeAddress = addresses?.PrivacyBridgeWETH;\n decimals = 18;\n } else if (token.symbol === 'WBTC') {\n tokenAddress = addresses?.WBTC;\n bridgeAddress = addresses?.PrivacyBridgeWBTC;\n decimals = 8;\n } else if (token.symbol === 'USDT') {\n tokenAddress = addresses?.USDT;\n bridgeAddress = addresses?.PrivacyBridgeUSDT;\n decimals = 6;\n } else if (token.symbol === 'USDC.e') {\n tokenAddress = addresses?.USDC_E;\n bridgeAddress = addresses?.PrivacyBridgeUSDCe;\n decimals = 6;\n } else if (token.symbol === 'WADA') {\n tokenAddress = addresses?.WADA;\n bridgeAddress = addresses?.PrivacyBridgeWADA;\n decimals = 18;\n } else if (token.symbol === 'gCOTI') {\n tokenAddress = addresses?.gCOTI;\n bridgeAddress = addresses?.PrivacyBridgegCOTI;\n decimals = 18;\n } else if (token.symbol === 'COTI') {\n // Native COTI doesn't need approval for Deposit\n /* v8 ignore next -- unreachable: native COTI deposit returns above at line 439 */\n if (direction === 'to-private') return;\n \n bridgeAddress = addresses?.PrivacyBridgeCotiNative;\n }\n }\n\n if (isPodPortalPublicToken(currentChainId, pubCfgApprove)) {\n const privTokCfgApprove = getPrivateTokensForChain(currentChainId).find(\n pt => pt.symbol === `p.${token.symbol.replace(/^p\\./, '')}`\n );\n const resolved = pubCfgApprove\n ? resolvePodPortalAddresses({ addresses, pubCfg: pubCfgApprove, privCfg: privTokCfgApprove })\n : null;\n if (!resolved) {\n throw new Error(podPortalNotConfiguredError(currentChainId, token.symbol));\n }\n\n if (direction === 'to-public') {\n const amountWei = ethers.parseUnits(amount || '0', pubCfgApprove?.decimals ?? 18); /* v8 ignore branch */\n setIsApproving(true);\n setToastState({\n visible: true,\n title: 'Approve PoD Withdraw',\n message: `Please sign the permit to allow the PoD portal to withdraw your private ${token.symbol}.`,\n });\n\n const permit = await signPodWithdrawPermit({\n signer,\n pTokenAddress: resolved.pTokenAddress,\n portalAddress: resolved.portalAddress,\n amountWei,\n chainId: currentChainId,\n tokenSymbol: token.symbol,\n });\n podWithdrawPermitRef.current = permit;\n setPodWithdrawPermit(permit);\n setIsApproving(false);\n setToastState(prev => ({ ...prev, visible: false }));\n return;\n }\n\n bridgeAddress = resolved.portalAddress;\n tokenAddress = resolved.underlyingAddress;\n } else if (direction === 'to-private' && (!tokenAddress || !bridgeAddress)) {\n return;\n }\n\n if (!bridgeAddress) return;\n\n const amountToApprove = amount ? ethers.parseUnits(amount, decimals) : ethers.MaxUint256;\n\n setIsApproving(true);\n setToastState({\n visible: true,\n title: 'Approve Allowance',\n message: `Please approve the bridge to access your ${direction === 'to-public' ? 'Private ' : ''}${token.symbol}.`\n });\n\n let tx;\n\n if (direction === 'to-public') {\n // Private Token Approval (Encrypted)\n \n // 1. Resolve private token address and decimals\n let privateTokenKey = \"\";\n let privateDecimals = 18;\n if (token.symbol === 'COTI') {\n privateTokenKey = 'PrivateCoti';\n privateDecimals = 18;\n } else {\n privateTokenKey = 'p.' + token.symbol;\n if (token.symbol === 'WETH' || token.symbol === 'gCOTI') privateDecimals = 18;\n else if (token.symbol === 'WBTC') privateDecimals = 8;\n else privateDecimals = 6; // USDT, USDC.e, WADA\n }\n if (token.symbol === 'USDC.e') privateTokenKey = 'p.USDC_E';\n\n const privateTokenAddress = addresses[privateTokenKey];\n if (!privateTokenAddress) throw new Error(\"Private token address not found\");\n\n const privTokCfgApprove = getPrivateTokensForChain(currentChainId).find(\n pt =>\n !!pt.addressKey &&\n addresses[pt.addressKey as keyof typeof addresses] === privateTokenAddress\n );\n if (privTokCfgApprove) privateDecimals = privTokCfgApprove.decimals;\n\n // 2. Create itValue. Snap wallets build it inside Snap; non-Snap\n // wallets use the plugin session key from onboarding/manual recovery.\n setIsApproving(true);\n setToastState({\n visible: true,\n title: 'Approve Private Token',\n message: `Please approve the bridge to access your Private ${token.symbol} tokens.`\n });\n\n const amountToApprove = amount ? ethers.parseUnits(amount, privateDecimals) : ethers.MaxUint256;\n\n // approve(address,itUint256) — Encrypted approval using manual 256-bit encryption.\n const approveSig = ethers.id('approve(address,((uint256,uint256),bytes))').slice(0, 10);\n const itValue = sessionAesKey\n ? await encryptValue256(\n amountToApprove,\n sessionAesKey,\n privateTokenAddress,\n approveSig,\n walletAddress,\n signer\n )\n : hasSnap\n ? await buildItUint256ViaSnap({\n value: amountToApprove,\n tokenAddress: privateTokenAddress,\n functionSelector: approveSig,\n chainId: currentChainId,\n accountAddress: walletAddress,\n })\n : null;\n if (!itValue) {\n throw new Error(\"Private approval requires unlock/onboarding first.\");\n }\n logger.log('🔐 [Approve] Encrypted approval payload ready, encoding calldata...');\n\n // Manually encode the calldata\n const approveInterface = new ethers.Interface([\n \"function approve(address spender, tuple(tuple(uint256 ciphertextHigh, uint256 ciphertextLow) ciphertext, bytes signature) value) returns (bool)\"\n ]);\n const calldata = approveInterface.encodeFunctionData(\"approve\", [\n bridgeAddress,\n [[itValue.ciphertext.ciphertextHigh, itValue.ciphertext.ciphertextLow], itValue.signature]\n ]);\n\n logger.log('🔐 [Approve] Sending approve tx (wallet confirmation expected)...');\n // Bypassing Coti provider — use the connected wallet's provider directly.\n const rawTxHash = await (injectedProvider as any).request({\n method: 'eth_sendTransaction',\n params: [{\n from: walletAddress,\n to: privateTokenAddress,\n data: calldata,\n gas: '0xB71B00' // 12,000,000 in hex\n }]\n });\n\n logger.log('🔐 [Approve] Tx submitted, waiting for confirmation', { txHash: shortHash(rawTxHash) });\n await provider.waitForTransaction(rawTxHash);\n logger.log('🔐 [Approve] Tx confirmed, refreshing allowance...');\n\n setIsApproving(false);\n setToastState(prev => ({ ...prev, visible: false }));\n await checkAllowance();\n logger.log('✅ [Approve] Complete');\n return;\n\n } else {\n // Public Token Approval (Standard)\n /* v8 ignore next -- unreachable: to-private without tokenAddress returns above at line 500 */\n if (!tokenAddress) throw new Error(\"Token address not found\");\n const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, signer);\n tx = await tokenContract.approve(bridgeAddress, amountToApprove);\n }\n\n setToastState({\n visible: true,\n title: 'Approving...',\n message: 'Waiting for allowance confirmation...'\n });\n\n await tx.wait();\n\n // Refresh allowance\n await checkAllowance();\n\n setIsApproving(false);\n setToastState(prev => ({ ...prev, visible: false }));\n\n } catch (err) {\n logger.error(\"Approval failed\", err);\n setIsApproving(false);\n setToastState(prev => ({ ...prev, visible: false }));\n throw err; // Rethrow to allow UI to handle error (e.g. show message, reset state)\n }\n };\n\n /**\n * Determines if an approval is required for the current transaction.\n * @returns `true` if approval is needed, `false` otherwise.\n */\n const isApprovalNeeded = (() => {\n const token = publicTokens[selectedTokenIndex];\n\n if (direction === 'to-private' && (token?.isNative || (token?.symbol === 'COTI' && !token.addressKey))) {\n return false;\n }\n\n if (direction === 'to-public' && token?.bridgeAddressKey?.startsWith('PrivacyPortal')) {\n return isPodWithdrawPermitStale(podWithdrawPermit, token, chainId);\n }\n\n const amountNum = parseFloat(amount || '0');\n const allowanceNum = parseFloat(allowance);\n return amountNum > allowanceNum;\n })();\n return {\n allowance,\n isApproving,\n handleApprove,\n checkAllowance,\n isApprovalNeeded,\n podWithdrawPermit,\n setPodWithdrawPermit,\n getPodWithdrawPermit,\n clearPodWithdrawPermit,\n };\n};\n","import { useCallback, useRef } from 'react';\nimport * as CotiSDK from '@coti-io/coti-sdk-typescript';\nconst { generateRSAKeyPair, decryptRSA } = CotiSDK;\nimport { MetaMaskInpageProvider } from '@metamask/providers';\nimport { useAccount } from 'wagmi';\nimport { getPluginConfig, getSnapRequestParams, isSnapInstallEnabled } from '../config/plugin';\nimport { getMetaMaskProvider } from '../lib/ethereum';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from '../lib/logger';\nimport {\n assertMetaMaskActiveAccount,\n validateAesKeyRoundTrip,\n} from '../crypto/aesKeyValidation';\nimport { guardedEthAccounts } from '../lib/metaMaskMobile';\nimport type { CtUint256 } from '../types/ciphertext';\n\nexport interface GetAESKeyFromSnapOptions {\n /** Bypass the in-memory cache and fetch a fresh key from the Snap. */\n skipCache?: boolean;\n}\n\nexport interface BuildItUint256ViaSnapParams {\n value: bigint | string;\n tokenAddress: string;\n functionSelector: string;\n chainId?: number | string;\n accountAddress?: string;\n}\n\nexport interface SnapItUint256 {\n ciphertext: {\n ciphertextHigh: bigint;\n ciphertextLow: bigint;\n };\n signature: string;\n}\n\n/**\n * Custom hook that manages the entire lifecycle of the Coti Snap integration.\n * \n * This hook serves as the central controller for all Snap-related operations, including:\n * 1. **Installation Check**: Verifying if the Coti Snap is installed in the user's MetaMask wallet.\n * 2. **Connection Management**: orchestrating the connection process and requesting necessary permissions.\n * 3. **Key Retrieval**: Securely retrieving the user's AES key from the Snap for on-chain data decryption.\n * 4. **Error Handling**: centralizing error state management and providing retry mechanisms for connection failures.\n * \n * It acts as a bridge between the DApp and the wallet's Snap capability, ensuring a smooth user experience\n * for privacy-preserving features.\n * \n * @param setSnapError - Optional state setter to update if Snap is missing or connection fails.\n * @returns {Object} An object containing:\n * - `isSnapInstalled`: Async function that returns true if the Snap is found, false otherwise.\n * - `executeSnapCheck`: Async function that checks installation, logs status, sets error if missing, or executes callback if found.\n * - `connectToSnap`: Async function that requests permissions to connect to the Snap.\n * - `getAESKeyFromSnap`: Async function that specifically retrieves the AES key, handling retries.\n * - `resetError`: Function to clear the error state (if setSnapError is provided).\n */\nconst getSnapId = () => getPluginConfig().snapId;\n\n/**\n * Module-level AES key cache — singleton shared across all `useSnap` hook instances.\n *\n * IMPORTANT: This is intentionally a module-scoped mutable variable, NOT React state.\n * It acts as a process-wide singleton cache so that multiple components mounting\n * `useSnap` share the same cached key without triggering re-renders.\n *\n * Constraints:\n * - Only safe in browser SPA environments (single JS context per tab).\n * - NOT compatible with SSR or React Server Components — the cache would leak\n * across requests on the server.\n * - Cleared explicitly via `clearSnapCache()` on disconnect or account change.\n * - Never persisted to storage — lost on page refresh by design.\n */\nlet globalAESKeyCache: Record<string, string> = {};\n\nfunction getErrorMessage(error: unknown): string {\n if (error && typeof error === 'object') {\n const err = error as {\n message?: string;\n data?: { originalError?: { message?: string } };\n };\n return err.data?.originalError?.message ?? err.message ?? '';\n }\n return '';\n}\n\nfunction isSnapAccountNotReadyError(error: unknown): boolean {\n const message = getErrorMessage(error);\n return (\n message.includes('No account connected') ||\n message.includes('Extension context invalidated')\n );\n}\n\nfunction toSnapChainId(chainId?: number | string): string | undefined {\n return chainId === undefined ? undefined : String(chainId);\n}\n\nfunction stringifyBigInts(value: unknown): unknown {\n if (typeof value === 'bigint') return value.toString();\n if (Array.isArray(value)) return value.map(stringifyBigInts);\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n stringifyBigInts(item),\n ]),\n );\n }\n return value;\n}\n\nfunction parseSnapItUint256(value: unknown): SnapItUint256 | null {\n const result = value as {\n ciphertext?: { ciphertextHigh?: string | number | bigint; ciphertextLow?: string | number | bigint };\n signature?: string;\n } | null;\n if (!result?.ciphertext || typeof result.signature !== 'string') return null;\n return {\n ciphertext: {\n ciphertextHigh: BigInt(result.ciphertext.ciphertextHigh ?? 0),\n ciphertextLow: BigInt(result.ciphertext.ciphertextLow ?? 0),\n },\n signature: result.signature,\n };\n}\n\nasync function ensureSnapWalletAccounts(provider: MetaMaskInpageProvider): Promise<void> {\n try {\n const accounts = await guardedEthAccounts(provider);\n if (accounts.length > 0) return;\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISSING,\n 'No MetaMask account is connected for Snap key access',\n );\n } catch (error) {\n logger.warn('⚠️ eth_accounts before Snap RPC failed:', getErrorMessage(error));\n throw error;\n }\n}\n\nasync function getCotiChainId(provider: MetaMaskInpageProvider): Promise<number> {\n const COTI_MAINNET_ID = 2632500;\n const COTI_TESTNET_ID = 7082400;\n const rawChainIdHex = await provider.request({ method: 'eth_chainId' }) as string;\n const rawChainId = parseInt(rawChainIdHex, 16);\n return rawChainId === COTI_MAINNET_ID ? COTI_MAINNET_ID : COTI_TESTNET_ID;\n}\n\nfunction aesKeyCacheKey(accountAddress: string, cotiChainId: number): string {\n return `${accountAddress.toLowerCase()}:${cotiChainId}`;\n}\n\nasync function prepareSnapForKeyAccess(\n provider: MetaMaskInpageProvider,\n snapIdValue: string,\n): Promise<void> {\n await ensureSnapWalletAccounts(provider);\n try {\n await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: snapIdValue,\n request: { method: 'connect-to-wallet' },\n },\n });\n } catch (error) {\n logger.warn('⚠️ Snap connect-to-wallet failed (non-fatal):', getErrorMessage(error));\n }\n}\n\nexport const useSnap = (setSnapError?: (error: string | null) => void) => {\n const isSnapRequestPending = useRef(false);\n const { address: connectedAddress, connector } = useAccount();\n\n /**\n * Resolves the MetaMask provider for Snap RPCs.\n * Prefers the wagmi connector (EIP-6963 when connected via MetaMask), then\n * EIP-6963 discovery, then window.ethereum fallbacks.\n */\n const resolveProvider = useCallback(async (): Promise<MetaMaskInpageProvider | null> => {\n if (connector) {\n try {\n const connectorProvider = await connector.getProvider();\n if (connectorProvider) {\n logger.log('🔗 Snap provider: wagmi connector');\n return connectorProvider as MetaMaskInpageProvider;\n }\n } catch (error) {\n logger.warn('⚠️ connector.getProvider() failed for Snap', error);\n }\n }\n\n const metaMaskProvider = getMetaMaskProvider();\n if (metaMaskProvider) {\n logger.log('🔗 Snap provider: EIP-6963 / MetaMask fallback');\n return metaMaskProvider as MetaMaskInpageProvider;\n }\n\n logger.log('❌ No MetaMask provider available for Snap');\n return null;\n }, [connector]);\n\n // Flag to check if environment is Flask\n const isFlask = useRef<boolean>(false);\n\n /**\n * Detects if the user is running MetaMask Flask.\n */\n const detectFlask = useCallback(async (): Promise<boolean> => {\n const provider = await resolveProvider();\n /* v8 ignore next -- unreachable: isSnapInstalled guards provider before calling detectFlask */\n if (!provider) return false;\n try {\n const clientVersion = await provider.request({ method: 'web3_clientVersion' });\n const isFlaskDetected = (clientVersion as string).includes('flask');\n logger.log(`🦊 Client Version: ${clientVersion} (Flask: ${isFlaskDetected})`);\n isFlask.current = isFlaskDetected;\n return isFlaskDetected;\n } catch (e) {\n logger.warn('⚠️ Failed to check client version', e);\n return false;\n }\n }, [resolveProvider]);\n\n /**\n * Checks if the Coti Snap is currently installed AND connected to this origin.\n * Only uses wallet_getSnaps — no dialogs, no side effects.\n * Returns false if snap is not visible (not installed OR not connected to this origin).\n * Also returns false for non-MetaMask wallets that don't support wallet_getSnaps.\n */\n const isSnapInstalled = useCallback(async (): Promise<boolean> => {\n const provider = await resolveProvider();\n if (!provider) {\n logger.log('❌ isSnapInstalled: No MetaMask provider');\n return false;\n }\n\n try {\n await detectFlask();\n\n logger.log('🕵️♀️ requesting wallet_getSnaps...');\n const snaps = (await provider.request({ method: 'wallet_getSnaps' })) as Record<string, any>;\n logger.log('🕵️♀️ wallet_getSnaps result:', JSON.stringify(snaps, null, 2));\n\n const snapInfo = Object.values(snaps).find(\n (snap: any) => snap.id === getSnapId()\n ) || (getSnapId() in snaps);\n\n if (snapInfo) {\n logger.log(`✅ Snap found and connected: ${getSnapId()}`);\n return true;\n }\n\n // Snap not visible — either not installed or installed but not connected to this origin.\n // We cannot distinguish without showing a MetaMask dialog.\n // Return false and let the UI guide the user.\n logger.log(`ℹ️ Snap ${getSnapId()} not visible via wallet_getSnaps.`);\n return false;\n } catch (error: any) {\n // -32601 means the wallet doesn't support wallet_getSnaps (Rabby, Trust, etc.)\n if (error?.code === -32601) {\n logger.log('ℹ️ Wallet does not support wallet_getSnaps (non-MetaMask wallet). Snap unavailable.');\n return false;\n }\n logger.error('❌ Error checking snap connection:', error);\n return false;\n }\n }, [detectFlask, resolveProvider]);\n\n\n /**\n * Connect to COTI Snap (request permissions).\n * Returns false immediately for wallets that don't support snaps.\n */\n const connectToSnap = useCallback(async (): Promise<boolean> => {\n if (!isSnapInstallEnabled()) {\n logger.log('ℹ️ Snap install disabled via plugin config');\n return false;\n }\n\n const provider = await resolveProvider();\n if (!provider) {\n logger.log('❌ No MetaMask provider available for Snap install');\n if (setSnapError) {\n setSnapError('No MetaMask provider found. Disable other wallet extensions and retry.');\n }\n return false;\n }\n\n try {\n logger.log('🔌 Requesting permission to connect to COTI Snap...');\n await provider.request({\n method: 'wallet_requestSnaps',\n params: getSnapRequestParams(getSnapId()),\n });\n logger.log('✅ Connected to COTI Snap');\n if (setSnapError) setSnapError(null);\n return true;\n } catch (error: any) {\n // Non-MetaMask wallets don't support wallet_requestSnaps\n if (error?.code === -32601) {\n logger.log('ℹ️ Wallet does not support wallet_requestSnaps (non-MetaMask wallet).');\n if (setSnapError) {\n setSnapError('Snap requires MetaMask. Disable other wallet extensions and retry.');\n }\n return false;\n }\n logger.error('❌ Failed to connect to snap:', error.message);\n if (setSnapError) {\n if (!isFlask.current) {\n setSnapError('MetaMask Flask is required for this Snap.');\n } else {\n setSnapError('Failed to connect to Snap');\n }\n }\n // Propagate error for context handling\n throw new CotiPluginError(CotiErrorCode.SNAP_CONNECT_FAILED, 'Failed to connect to COTI Snap');\n }\n }, [setSnapError, resolveProvider]);\n\n\n /**\n * Orchestrates the Snap connection check with logging and error handling.\n * \n * @param onSnapFound - Callback to execute if Snap is installed (e.g., updateAccountState).\n * Should return true if successful, false otherwise.\n * @returns {Promise<void>}\n */\n const executeSnapCheck = useCallback(async (\n onSnapFound: () => Promise<boolean>\n ) => {\n const installed = await isSnapInstalled();\n\n if (installed) {\n logger.log('✅ Snap is installed. Attempting to retrieve key...');\n const success = await onSnapFound();\n if (!success) {\n logger.log('⚠️ Snap installed but key retrieval failed/cancelled. Banner handles error.');\n }\n } else {\n logger.log('ℹ️ Snap NOT installed/detected.');\n if (setSnapError) setSnapError(null);\n }\n }, [isSnapInstalled, setSnapError]);\n\n /**\n * Syncs the environment (testnet/mainnet) with the Snap.\n * This ensures the Snap uses the correct config for the current network.\n */\n const syncEnvironment = useCallback(async (): Promise<void> => {\n const provider = await resolveProvider();\n if (!provider) return;\n\n try {\n await ensureSnapWalletAccounts(provider);\n\n const chainIdHex = await provider.request({ method: 'eth_chainId' }) as string;\n const chainId = parseInt(chainIdHex, 16);\n\n // Map the current chain to the correct COTI environment.\n // Non-COTI chains (e.g. Sepolia) default to testnet since that is\n // where the user's AES key is stored during testnet workflows.\n const COTI_MAINNET_ID = 2632500;\n const COTI_TESTNET_ID = 7082400;\n const environment = chainId === COTI_MAINNET_ID ? 'mainnet' : 'testnet';\n const cotiChainId = chainId === COTI_MAINNET_ID ? COTI_MAINNET_ID : COTI_TESTNET_ID;\n\n logger.log(`🌍 Syncing Snap Environment to: ${environment} (requested ChainID: ${chainId} → COTI ChainID: ${cotiChainId})`);\n\n await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method: 'set-environment',\n params: { environment }\n }\n }\n });\n logger.log('✅ Snap Environment Synced');\n } catch (error) {\n logger.warn('⚠️ Failed to sync Snap environment:', error);\n // Non-critical, but good to know\n }\n }, [resolveProvider]);\n\n const invokeSnapOperation = useCallback(async <Result,>(\n method: string,\n params?: Record<string, unknown>,\n ): Promise<Result | null> => {\n const provider = await resolveProvider();\n if (!provider) {\n logger.log('❌ No MetaMask provider available for Snap operation');\n return null;\n }\n\n const installed = await isSnapInstalled();\n if (!installed) {\n throw new CotiPluginError(\n CotiErrorCode.SNAP_CONNECT_FAILED,\n 'COTI Snap is not installed or not connected to this origin',\n );\n }\n\n await prepareSnapForKeyAccess(provider, getSnapId());\n await syncEnvironment();\n\n return provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method,\n params,\n },\n },\n }) as Promise<Result | null>;\n }, [isSnapInstalled, resolveProvider, syncEnvironment]);\n\n const decryptCtUint64ViaSnap = useCallback(async (\n value: bigint | string | number,\n chainId?: number | string,\n accountAddress?: string,\n ): Promise<bigint | null> => {\n const result = await invokeSnapOperation<string | null>('decrypt', {\n type: 'ctUint64',\n value: value.toString(),\n chainId: toSnapChainId(chainId),\n address: accountAddress ?? connectedAddress,\n });\n return result == null ? null : BigInt(result);\n }, [connectedAddress, invokeSnapOperation]);\n\n const decryptCtUint256ViaSnap = useCallback(async (\n value: CtUint256,\n chainId?: number | string,\n accountAddress?: string,\n ): Promise<bigint | null> => {\n const result = await invokeSnapOperation<string | null>('decrypt', {\n type: 'ctUint256',\n value: stringifyBigInts(value),\n chainId: toSnapChainId(chainId),\n address: accountAddress ?? connectedAddress,\n });\n return result == null ? null : BigInt(result);\n }, [connectedAddress, invokeSnapOperation]);\n\n const encryptUint256ViaSnap = useCallback(async (\n value: bigint | string,\n chainId?: number | string,\n accountAddress?: string,\n ): Promise<{ ciphertextHigh: bigint; ciphertextLow: bigint } | null> => {\n const result = await invokeSnapOperation<{\n ciphertextHigh: string | number | bigint;\n ciphertextLow: string | number | bigint;\n } | null>('encrypt', {\n type: 'uint256',\n value: value.toString(),\n chainId: toSnapChainId(chainId),\n address: accountAddress ?? connectedAddress,\n });\n if (!result) return null;\n return {\n ciphertextHigh: BigInt(result.ciphertextHigh),\n ciphertextLow: BigInt(result.ciphertextLow),\n };\n }, [connectedAddress, invokeSnapOperation]);\n\n const buildItUint256ViaSnap = useCallback(async (\n params: BuildItUint256ViaSnapParams,\n ): Promise<SnapItUint256 | null> => {\n const result = await invokeSnapOperation<{ value?: unknown } | null>('build-it-uint256', {\n value: params.value.toString(),\n tokenAddress: params.tokenAddress,\n functionSelector: params.functionSelector,\n chainId: toSnapChainId(params.chainId),\n address: params.accountAddress ?? connectedAddress,\n });\n return parseSnapItUint256(result?.value);\n }, [connectedAddress, invokeSnapOperation]);\n\n /**\n * Get AES key from COTI Snap.\n * Includes retry logic.\n */\n const getAESKeyFromSnap = useCallback(async (\n accountAddress: string,\n options?: GetAESKeyFromSnapOptions,\n ): Promise<string | null> => {\n if (setSnapError) setSnapError(null);\n\n const skipCache = options?.skipCache === true;\n\n if (isSnapRequestPending.current) {\n logger.log('⏳ Snap request already pending, skipping concurrent call.');\n return null;\n }\n\n const provider = await resolveProvider();\n if (!provider) {\n logger.log('❌ No MetaMask provider available');\n return null;\n }\n\n const cotiChainId = await getCotiChainId(provider);\n\n // Return cached key if available (unless a fresh fetch was requested)\n if (!skipCache && accountAddress) {\n const cacheKey = aesKeyCacheKey(accountAddress, cotiChainId);\n const cachedKey = globalAESKeyCache[cacheKey];\n if (cachedKey) {\n try {\n await assertMetaMaskActiveAccount(provider, accountAddress);\n logger.log('🔑 Returning globally cached AES key');\n return cachedKey;\n } catch {\n delete globalAESKeyCache[cacheKey];\n }\n }\n }\n\n const installed = await isSnapInstalled();\n if (!installed) {\n logger.log('❌ Snap not visible via wallet_getSnaps.');\n throw new CotiPluginError(\n CotiErrorCode.SNAP_CONNECT_FAILED,\n 'COTI Snap is not installed or not connected to this origin',\n );\n }\n\n await prepareSnapForKeyAccess(provider, getSnapId());\n\n // Sync Environment explicitly before requesting key\n await syncEnvironment();\n\n // Add a small delay to ensure account is fully connected\n await new Promise(resolve => setTimeout(resolve, 500));\n\n if (accountAddress) {\n await assertMetaMaskActiveAccount(provider, accountAddress);\n }\n\n try {\n isSnapRequestPending.current = true;\n logger.log('🔑 Requesting AES key from COTI Snap...');\n\n let hasKey: boolean;\n try {\n hasKey = await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method: 'has-aes-key',\n params: { chainId: cotiChainId, address: accountAddress },\n },\n },\n }) as boolean;\n } catch (error: unknown) {\n if (isSnapAccountNotReadyError(error)) {\n logger.log('ℹ️ Snap account not ready during has-aes-key — contract onboarding required');\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISSING,\n 'COTI Snap has no AES key stored for this account',\n );\n }\n throw error;\n }\n\n if (!hasKey) {\n logger.log('ℹ️ Snap installed but has no AES key — contract onboarding required');\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISSING,\n 'COTI Snap has no AES key stored for this account',\n );\n }\n\n // Retry logic for robustness\n let retries = 3;\n let lastError;\n\n while (retries > 0) {\n try {\n logger.log(`🔑 Requesting AES key for COTI chainId: ${cotiChainId}`);\n\n // Directly request the key (User preference to force fetch)\n // Explicitly passing chainId to bypass sync state issues\n const key = await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method: 'get-aes-key',\n params: { chainId: cotiChainId, address: accountAddress }\n }\n }\n });\n\n logger.log('🔍 wallet_invokeSnap: key received, length:', (key as string)?.length);\n\n if (!key) {\n logger.warn('⚠️ Snap returned null (User likely rejected).');\n // Throw specific error so we don't trigger \"Missing Key\" onboarding flow\n throw new CotiPluginError(CotiErrorCode.SNAP_DIALOG_REJECTED, 'User rejected Snap dialog');\n }\n\n const snapKey = key as string;\n\n if (!validateAesKeyRoundTrip(snapKey)) {\n logger.error('❌ Snap AES key failed encrypt/decrypt round-trip validation');\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n 'AES key failed encrypt/decrypt validation. Re-onboarding required.',\n );\n }\n\n if (accountAddress) {\n await assertMetaMaskActiveAccount(provider, accountAddress);\n }\n\n logger.log('✅ AES key received from snap and passed round-trip validation');\n\n globalAESKeyCache[aesKeyCacheKey(accountAddress, cotiChainId)] = snapKey;\n return snapKey;\n\n } catch (error: any) {\n lastError = error;\n\n if (error.message?.includes('No account connected') && retries > 1) {\n logger.log(`⏳ Account not ready, retrying... (${retries - 1} attempts left)`);\n await new Promise(resolve => setTimeout(resolve, 1000));\n retries--;\n } else {\n logger.error('❌ Error during Snap interaction:', error);\n throw error;\n }\n }\n }\n\n /* v8 ignore next -- unreachable: retry loop throws or returns before exiting while */\n throw lastError;\n } catch (error: any) {\n logger.error('❌ Failed to get AES key from snap:', error.message);\n\n if (error instanceof CotiPluginError) {\n throw error;\n }\n\n if (isSnapAccountNotReadyError(error)) {\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISSING,\n 'COTI Snap has no AES key stored for this account',\n );\n }\n\n if (setSnapError) setSnapError(error.message || 'Failed to connect to Snap');\n return null;\n } finally {\n isSnapRequestPending.current = false;\n }\n }, [isSnapInstalled, setSnapError, resolveProvider, syncEnvironment]);\n\n /**\n * Read-only check: whether the Snap has an AES key stored for the active account.\n * Does not prompt the user. Returns null when the Snap is unavailable.\n */\n const hasAesKeyInSnap = useCallback(async (accountAddress?: string): Promise<boolean | null> => {\n const provider = await resolveProvider();\n if (!provider) return null;\n\n const installed = await isSnapInstalled();\n if (!installed) return null;\n\n await prepareSnapForKeyAccess(provider, getSnapId());\n await syncEnvironment();\n\n if (accountAddress) {\n try {\n await assertMetaMaskActiveAccount(provider, accountAddress);\n } catch {\n return false;\n }\n }\n\n const cotiChainId = await getCotiChainId(provider);\n\n try {\n return await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method: 'has-aes-key',\n params: { chainId: cotiChainId, address: accountAddress },\n },\n },\n }) as boolean;\n } catch (error: unknown) {\n if (isSnapAccountNotReadyError(error)) return false;\n logger.warn('has-aes-key check failed:', getErrorMessage(error));\n return null;\n }\n }, [isSnapInstalled, resolveProvider, syncEnvironment]);\n\n /**\n * Save AES key to Snap (persist it for future sessions)\n */\n const saveAESKeyToSnap = useCallback(async (key: string, accountAddress: string = ''): Promise<boolean> => {\n const provider = await resolveProvider();\n if (!provider) return false;\n try {\n const installed = await isSnapInstalled();\n if (!installed) {\n logger.log(`ℹ️ Skipping AES key save — Snap ${getSnapId()} is not visible to this origin.`);\n return false;\n }\n\n await prepareSnapForKeyAccess(provider, getSnapId());\n await syncEnvironment();\n\n if (accountAddress) {\n await assertMetaMaskActiveAccount(provider, accountAddress);\n }\n\n const cotiChainId = await getCotiChainId(provider);\n\n logger.log('💾 Saving AES key to Snap...');\n await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: getSnapId(),\n request: {\n method: 'set-aes-key',\n params: { newUserAesKey: key, chainId: cotiChainId, address: accountAddress },\n },\n },\n });\n logger.log('✅ AES key saved to Snap successfully');\n if (accountAddress) {\n globalAESKeyCache[aesKeyCacheKey(accountAddress, cotiChainId)] = key;\n }\n if (setSnapError) setSnapError(null);\n return true;\n } catch (err: any) {\n logger.error('❌ Failed to save AES key to Snap:', err);\n return false;\n }\n }, [setSnapError, resolveProvider, isSnapInstalled, syncEnvironment]);\n\n const resetError = useCallback(() => {\n if (setSnapError) setSnapError(null);\n }, [setSnapError]);\n\n /**\n * Clears the globally cached AES key.\n * This forces the next unlock request to go back to the Snap or Onboarding flow.\n */\n const clearSnapCache = useCallback(() => {\n logger.log('🧹 Clearing global AES key cache');\n globalAESKeyCache = {};\n }, []);\n\n // Helper to expose sync\n const connectAndSync = useCallback(async () => {\n const connected = await connectToSnap();\n if (connected) {\n await syncEnvironment();\n }\n return connected;\n }, [connectToSnap, syncEnvironment]);\n\n /**\n * Manually triggers the onboarding flow (Generate/Recover AES key via SDK).\n * Used when Snap is missing or user forces a key regeneration.\n * \n * @returns {Promise<string | null>} The generated AES key if successful.\n */\n const handleManualOnboarding = useCallback(async (): Promise<string | null> => {\n try {\n logger.log(\"🚀 Starting manual onboarding flow...\");\n const key = await onboardUser();\n\n /* v8 ignore next 9 -- onboardUser is a same-module stub that always throws in unit tests */\n if (key && key !== \"PENDING\") {\n logger.log(\"🔑 Key recovered from SDK:\", key);\n await saveAESKeyToSnap(key);\n logger.log(\"✅ Onboarding flow finished.\");\n return key;\n }\n /* v8 ignore next */\n return null;\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : 'Unknown error';\n logger.error('Manual onboarding failed:', e);\n if (setSnapError) setSnapError(`Onboarding failed: ${message}`);\n return null;\n }\n }, [saveAESKeyToSnap, setSnapError]);\n\n /**\n * Verifies that the key in the Snap matches the key generated by the SDK (Network).\n * Useful for debugging stale states.\n */\n const handleKeyVerification = useCallback(async (): Promise<void> => {\n try {\n logger.log(\"🔍 STARTING KEY VERIFICATION...\");\n logger.log(\"1️⃣ Fetching AES Key from Snap Storage...\");\n const snapKey = await getAESKeyFromSnap('');\n logger.log(\" -> Snap Key length:\", snapKey?.length);\n\n logger.log(\"2️⃣ Computing AES Key from Network (generateOrRecoverAes)...\");\n logger.log(\" (Please sign the message in MetaMask)\");\n\n /* v8 ignore start -- onboardUser is a same-module stub; comparison UI requires live onboarding */\n const netKey = await onboardUser();\n logger.log(\" -> Network Key length:\", (netKey as string)?.length);\n\n logger.log(\"3️⃣ COMPARISON RESULT:\");\n const match = snapKey === netKey;\n logger.log(` MATCH: ${match ? \"✅ YES\" : \"❌ NO\"}`);\n\n if (!match) {\n logger.error('CRITICAL MISMATCH DETECTED!');\n logger.error('Snap key and Network key do NOT match. You MUST Force Onboard to fix this.');\n if (setSnapError) {\n setSnapError('AES key mismatch: Snap and network keys do not match. Force onboard to fix.');\n }\n } else {\n logger.log('Keys match. Issues are likely elsewhere.');\n if (setSnapError) setSnapError(null);\n }\n /* v8 ignore stop */\n\n } catch (e: unknown) {\n logger.error('Key verification failed:', e);\n const message = e instanceof Error ? e.message : 'Key verification failed';\n if (setSnapError) setSnapError(`Verification failed: ${message}`);\n if (e instanceof CotiPluginError) throw e;\n }\n }, [getAESKeyFromSnap, setSnapError]);\n\n return {\n isSnapInstalled,\n executeSnapCheck,\n connectToSnap: connectAndSync,\n requestSnapConnection: connectToSnap, // explicit wallet_requestSnaps for \"Connect Snap\" button\n getAESKeyFromSnap,\n hasAesKeyInSnap,\n saveAESKeyToSnap,\n decryptCtUint64ViaSnap,\n decryptCtUint256ViaSnap,\n encryptUint256ViaSnap,\n buildItUint256ViaSnap,\n resetError,\n handleManualOnboarding,\n handleKeyVerification,\n clearSnapCache\n };\n};\n\n/**\n * Signs a 256-bit IT hash using the snap's raw ECDSA signing capability.\n * The snap derives the private key and signs without the Ethereum prefix,\n * which is required by the COTI MPC 256-bit precompile.\n *\n * @param msgHash - 32-byte hex hash to sign (keccak256 of packed message)\n * @returns 65-byte signature as Uint8Array, or null if user rejected\n */\nexport const signIT256ViaSnap = async (msgHash: string): Promise<Uint8Array | null> => {\n const currentSnapId = getPluginConfig().snapId;\n const provider = getMetaMaskProvider();\n if (!provider) throw new CotiPluginError(CotiErrorCode.NO_PROVIDER, 'No wallet provider found');\n\n const result = await provider.request({\n method: 'wallet_invokeSnap',\n params: {\n snapId: currentSnapId,\n request: {\n method: 'sign-it256',\n params: { msgHash }\n }\n }\n });\n\n if (!result) return null; // user rejected\n\n // Result is an array of numbers (from snap's Array.from(sigBytes))\n return new Uint8Array(result as number[]);\n};\n\n/**\n * Onboard user to Coti Network (generate/recover AES key via SDK)\n * This is required if the user has never onboarded or the network was reset.\n */\n/**\n * Placeholder onboardUser function - directs users to the MetaMask onboarding page.\n * Actual onboarding happens at https://dev.metamask.coti.io/wallet\n */\nexport const onboardUser = async () => {\n throw new Error(\"Please visit https://dev.metamask.coti.io/wallet to complete onboarding\");\n};\n","import { useState, useCallback } from 'react';\nimport { useAccount } from 'wagmi';\nimport { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES, BRIDGE_ABI, BRIDGE_ERC20_ABI, ERC20_ABI } from '../../contracts/config';\nimport type { PodPortalRequest } from '../../contracts/pod';\nimport type { PodWithdrawPermit } from '../../chains/portal/executePodPortalTransaction';\nimport { executePodPortalTransaction } from '../../chains/portal/executePodPortalTransaction';\nimport { formatTokenBalanceDisplay } from '../../lib/utils';\nimport { estimateBridgeFee } from '../useEstimateBridgeFees';\nimport { getChainConfig, getExplorerBaseUrlForChain, getPrivateTokensForChain, getPublicTokensForChain, getRpcUrlForChain } from '../../chains';\nimport { isPodPortalPublicToken, podPortalNotConfiguredError, resolveConfiguredAddress, resolvePodPortalAddresses } from '../../chains/portal/helpers';\nimport { logger } from '../../lib/logger';\nimport { truncateAddress } from '../../lib/format';\nimport { shortHash } from './utils';\nimport type { SwapProgressStage, Token, ToastState } from './types';\n\nexport interface UsePrivacyBridgeExecutorOptions {\n walletAddress: string;\n publicTokens: Token[];\n setPublicTokens: React.Dispatch<React.SetStateAction<Token[]>>;\n setPrivateTokens: React.Dispatch<React.SetStateAction<Token[]>>;\n setToastState: React.Dispatch<React.SetStateAction<ToastState>>;\n refreshPrivateBalances?: () => Promise<boolean>;\n refreshPublicBalances?: () => Promise<boolean>;\n upsertPodRequest?: (request: PodPortalRequest) => void;\n getPodWithdrawPermit: () => PodWithdrawPermit | null;\n clearPodWithdrawPermit: () => void;\n}\n\n/** Deposit/withdraw and PoD portal transaction execution. */\nexport const usePrivacyBridgeExecutor = ({\n walletAddress,\n publicTokens,\n setPublicTokens,\n setPrivateTokens,\n setToastState,\n refreshPrivateBalances,\n refreshPublicBalances,\n upsertPodRequest,\n getPodWithdrawPermit,\n clearPodWithdrawPermit,\n}: UsePrivacyBridgeExecutorOptions) => {\n const [isBridgingLoading, setIsBridgingLoading] = useState(false);\n\n // Connector for the wallet the user selected via RainbowKit/wagmi.\n // We resolve the EIP-1193 provider from it rather than window.ethereum,\n // which is unreliable when multiple wallet extensions are installed.\n const { connector, chainId: connectedChainId } = useAccount();\n\n const resolveInjectedProvider = useCallback(async (): Promise<any> => {\n if (connector?.getProvider) {\n try {\n const connectorProvider = await connector.getProvider();\n if (connectorProvider) return connectorProvider;\n } catch (e) {\n logger.warn('[Executor] connector.getProvider() failed, falling back to window.ethereum', e);\n }\n }\n return window.ethereum;\n }, [connector]);\n\n const calculateGasMargin = async (\n contract: ethers.Contract,\n methodName: string,\n args: any[],\n fallbackGasLimit: bigint,\n overrides: any = {}\n ): Promise<bigint> => {\n try {\n logger.log(`Estimating gas for ${methodName}...`);\n const estimatedGas = await contract[methodName].estimateGas(...args, overrides);\n // removing 20% buffer as requested\n // const safeGas = (estimatedGas * 120n) / 100n;\n const safeGas = estimatedGas;\n logger.log(`Gas estimation successful: ${estimatedGas.toString()} -> Safe limit: ${safeGas.toString()}`);\n return safeGas;\n } catch (error: any) {\n logger.warn(`Gas estimation failed for ${methodName}`, error);\n // Log specific error reason if available\n if (error.reason) logger.warn(` Reason: ${error.reason}`);\n if (error.data) logger.warn(` Data: ${error.data}`);\n\n return fallbackGasLimit;\n }\n };\n\n const executeTransaction = useCallback(async (\n txAmount: string,\n txDirection: 'to-private' | 'to-public',\n txTokenIndex: number,\n onProgress?: (stage: SwapProgressStage, txHash?: string) => void\n ) => {\n logger.log(`🚀 Initiating swap transaction: ${txAmount} (Direction: ${txDirection}, Token Index: ${txTokenIndex})`);\n setIsBridgingLoading(true);\n // Captured outside the try block's scope so the catch handler below can still\n // report the broadcast tx hash even when the thrown error doesn't carry one.\n let capturedTxHash: string | undefined;\n try {\n if (!window.ethereum) throw new Error(\"No wallet found\");\n\n // Initialize Ethers using the connected wallet's provider (via wagmi connector),\n // NOT window.ethereum which is unreliable with multiple wallets installed.\n const injectedProvider = await resolveInjectedProvider();\n const provider = new ethers.BrowserProvider(injectedProvider);\n // Pass walletAddress to getSigner so ethers targets the connected account\n // instead of triggering popups from competing wallet extensions.\n const signer = await provider.getSigner(walletAddress);\n\n const network = await provider.getNetwork();\n const currentChainId = Number(network.chainId);\n const addresses = CONTRACT_ADDRESSES[currentChainId];\n\n if (!addresses) throw new Error(\"Unsupported network\");\n\n const txPublicToken = publicTokens[txTokenIndex];\n const chainCfgExec = getChainConfig(currentChainId);\n\n const pubTokExec = getPublicTokensForChain(currentChainId).find(\n t => t.symbol === txPublicToken.symbol && !t.isPrivate\n );\n const privTokExec = getPrivateTokensForChain(currentChainId).find(\n t => t.symbol === `p.${txPublicToken.symbol.replace(/^p\\./, '')}`\n );\n let publicDecimals = pubTokExec?.decimals ?? 18;\n let privateDecimals = privTokExec?.decimals ?? pubTokExec?.decimals ?? 18;\n const decimals = txDirection === 'to-private' ? publicDecimals : privateDecimals;\n\n if (chainCfgExec?.portalStrategy === 'pod-privacy-portal' && isPodPortalPublicToken(currentChainId, pubTokExec)) {\n const resolved = pubTokExec\n ? resolvePodPortalAddresses({ addresses, pubCfg: pubTokExec, privCfg: privTokExec })\n : null;\n if (!resolved) {\n throw new Error(podPortalNotConfiguredError(currentChainId, txPublicToken.symbol));\n }\n\n setToastState({\n visible: true,\n title: txDirection === 'to-private' ? 'Submit PoD Deposit' : 'Submit PoD Withdraw',\n message: `Please confirm the ${chainCfgExec.name} transaction in your wallet.`,\n });\n\n const withdrawPermit = txDirection === 'to-public' ? getPodWithdrawPermit() ?? undefined : undefined;\n const result = await executePodPortalTransaction({\n txAmount,\n txDirection,\n signer,\n provider,\n portalAddress: resolved.portalAddress,\n underlyingAddress: resolved.underlyingAddress,\n pTokenAddress: resolved.pTokenAddress,\n tokenSymbol: txPublicToken.symbol,\n decimals,\n chainId: currentChainId,\n isNativeDeposit: !!pubTokExec?.isNative,\n withdrawPermit,\n onProgress,\n });\n\n upsertPodRequest?.(result.request);\n if (txDirection === 'to-public') {\n clearPodWithdrawPermit();\n }\n onProgress?.('transfer-complete', result.txHash);\n\n if (refreshPublicBalances) {\n logger.log('🔄 Refreshing public balances after PoD source tx...');\n refreshPublicBalances().catch(err =>\n logger.warn('Public balance refresh after PoD source tx failed', err),\n );\n }\n\n setToastState({\n visible: true,\n title: 'PoD Request Submitted',\n message: txDirection === 'to-private'\n ? `Deposit submitted on ${chainCfgExec.name}. Private balance will update after the PoD callback succeeds.`\n : `Withdraw submitted on ${chainCfgExec.name}. Funds are released after the PoD callback succeeds.`,\n });\n logger.log('PoD portal request submitted', { txHash: shortHash(result.txHash) });\n return;\n }\n\n let bridgeAddress: string | undefined = resolveConfiguredAddress(\n addresses,\n pubTokExec?.bridgeAddressKey,\n );\n let tokenAddress: string | undefined = resolveConfiguredAddress(\n addresses,\n pubTokExec?.addressKey,\n );\n\n const isWeth = txPublicToken.symbol === 'WETH';\n const isWbtc = txPublicToken.symbol === 'WBTC';\n const isUsdt = txPublicToken.symbol === 'USDT';\n const isUsdcE = txPublicToken.symbol === 'USDC.e';\n const isWada = txPublicToken.symbol === 'WADA';\n const isGCoti = txPublicToken.symbol === 'gCOTI';\n\n if (!bridgeAddress) {\n if (isWeth) {\n bridgeAddress = addresses.PrivacyBridgeWETH;\n tokenAddress = addresses.WETH;\n publicDecimals = 18;\n privateDecimals = 18;\n } else if (isWbtc) {\n bridgeAddress = addresses.PrivacyBridgeWBTC;\n tokenAddress = addresses.WBTC;\n publicDecimals = 8;\n privateDecimals = 8;\n } else if (isUsdt) {\n bridgeAddress = addresses.PrivacyBridgeUSDT;\n tokenAddress = addresses.USDT;\n publicDecimals = 6;\n privateDecimals = 6;\n } else if (isUsdcE) {\n bridgeAddress = addresses.PrivacyBridgeUSDCe;\n tokenAddress = addresses.USDC_E;\n publicDecimals = 6;\n privateDecimals = 6;\n } else if (isWada) {\n bridgeAddress = addresses.PrivacyBridgeWADA;\n tokenAddress = addresses.WADA;\n publicDecimals = 6;\n privateDecimals = 6;\n } else if (isGCoti) {\n bridgeAddress = addresses.PrivacyBridgegCOTI;\n tokenAddress = addresses.gCOTI;\n publicDecimals = 18;\n privateDecimals = 18;\n } else {\n bridgeAddress = addresses.PrivacyBridgeCotiNative;\n publicDecimals = 18;\n privateDecimals = 18;\n }\n }\n\n if (!bridgeAddress) throw new Error(\"Bridge address not found for this token\");\n\n const isErc20 = !!tokenAddress;\n\n const bridgeAbi = isErc20 ? BRIDGE_ERC20_ABI : BRIDGE_ABI;\n\n const bridge = new ethers.Contract(bridgeAddress, bridgeAbi, signer);\n\n const amountWei = ethers.parseUnits(txAmount, decimals);\n\n let tx;\n\n if (txDirection === 'to-private') {\n // Deposit\n logger.log('Depositing to bridge', {\n token: txPublicToken.symbol,\n bridge: truncateAddress(bridgeAddress),\n });\n\n setToastState({\n visible: true,\n title: 'Confirm Transaction',\n message: 'Please confirm the transaction in your wallet to deposit to your private balance.'\n });\n\n try {\n if (isErc20 && tokenAddress) {\n // ERC20 Deposit: requires allowance\n const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, signer);\n const userBalance = await tokenContract.balanceOf(walletAddress);\n\n const amountWeiPublic = ethers.parseUnits(txAmount, publicDecimals); // Allowance/Balance always unchecked against public amount\n\n // Re-check allowance using Public Decimals\n const userAllowance = await tokenContract.allowance(walletAddress, bridgeAddress);\n\n if (userBalance < amountWeiPublic) {\n logger.log('Insufficient balance for deposit', {\n token: txPublicToken.symbol,\n decimals: publicDecimals,\n });\n throw new Error(`Insufficient ${txPublicToken.symbol} balance. You have ${ethers.formatUnits(userBalance, publicDecimals)} ${txPublicToken.symbol}, trying to bridge ${txAmount}.`);\n }\n if (userAllowance < amountWeiPublic) {\n throw new Error(`Insufficient Allowance. Approved: ${ethers.formatUnits(userAllowance, publicDecimals)}, Required: ${txAmount}. Please Approve again.`);\n }\n\n logger.log(\"🔄 Executing ERC20 Deposit...\");\n\n // Get fee from on-chain estimateDepositFee\n let nativeFee = 0n;\n let cotiOracleTimestamp = 0n;\n let tokenOracleTimestamp = 0n;\n try {\n const rpcUrl = getRpcUrlForChain(Number((await provider.getNetwork()).chainId));\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const feeEstimate = await estimateBridgeFee(txPublicToken.symbol, txAmount, rpcProvider);\n if (feeEstimate.depositFee !== 'Error') {\n nativeFee = ethers.parseEther(feeEstimate.depositFee);\n }\n cotiOracleTimestamp = BigInt(feeEstimate.cotiLastUpdated || '0');\n tokenOracleTimestamp = BigInt(feeEstimate.tokenLastUpdated || '0');\n logger.log('Computed COTI fee for ERC20 deposit');\n logger.log('Oracle timestamps loaded for ERC20 deposit', {\n coti: cotiOracleTimestamp.toString(),\n token: tokenOracleTimestamp.toString(),\n });\n } catch (e) {\n logger.warn(\"⚠️ Could not compute dynamic fee, defaulting to 0:\", e);\n }\n\n // The bridge enforces strict equality between these timestamps and the\n // on-chain oracle rows — submitting 0,0 always reverts (OracleTimestampMismatch).\n if (cotiOracleTimestamp === 0n || tokenOracleTimestamp === 0n) {\n throw new Error(`Could not load oracle price data for the ${txPublicToken.symbol} portal fee. Please try again.`);\n }\n\n logger.log('ERC20 deposit prepared', { token: txPublicToken.symbol });\n\n // CRITICAL: Bypass the Coti provider — it strips the data field from\n // non-encrypted transactions, causing msg.data to land as \"\" and revert.\n const depositBridge = new ethers.Contract(bridgeAddress, BRIDGE_ERC20_ABI, signer);\n const depositCalldata = depositBridge.interface.encodeFunctionData('deposit(uint256,uint256,uint256)', [amountWeiPublic, cotiOracleTimestamp, tokenOracleTimestamp]);\n\n let depositGasLimit = 12000000n;\n try {\n const depositGasHex = await (injectedProvider as any).request({\n method: 'eth_estimateGas',\n params: [{\n from: walletAddress,\n to: bridgeAddress,\n data: depositCalldata,\n value: '0x' + nativeFee.toString(16),\n }]\n });\n depositGasLimit = (BigInt(depositGasHex) * 130n) / 100n;\n logger.log(`🔍 ERC20 deposit gas: estimated=${BigInt(depositGasHex)}, buffered=${depositGasLimit}`);\n } catch (estErr: any) {\n logger.warn(\"⚠️ ERC20 deposit gas estimation failed, falling back to 12M:\", estErr?.message);\n }\n\n const rawDepositTxHash = await (injectedProvider as any).request({\n method: 'eth_sendTransaction',\n params: [{\n from: walletAddress,\n to: bridgeAddress,\n data: depositCalldata,\n value: '0x' + nativeFee.toString(16),\n gas: '0x' + depositGasLimit.toString(16),\n }]\n });\n\n logger.log('ERC20 deposit tx sent', { txHash: shortHash(rawDepositTxHash) });\n tx = {\n hash: rawDepositTxHash,\n wait: async () => await provider.waitForTransaction(rawDepositTxHash)\n } as any;\n\n } else {\n // Native COTI Deposit\n logger.log(\"🔄 Executing Native COTI Deposit...\");\n\n // Get dual oracle timestamps from fee estimation\n let cotiOracleTimestamp = 0n;\n let tokenOracleTimestamp = 0n;\n try {\n const rpcUrl = getRpcUrlForChain(Number((await provider.getNetwork()).chainId));\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const feeEstimate = await estimateBridgeFee('COTI', txAmount, rpcProvider);\n cotiOracleTimestamp = BigInt(feeEstimate.cotiLastUpdated || '0');\n tokenOracleTimestamp = cotiOracleTimestamp;\n logger.log('Oracle timestamps loaded for native COTI deposit', {\n coti: cotiOracleTimestamp.toString(),\n token: tokenOracleTimestamp.toString(),\n });\n } catch (e) {\n logger.warn(\"⚠️ Could not fetch oracle timestamp:\", e);\n }\n\n // The bridge enforces strict equality between these timestamps and the\n // on-chain oracle rows — submitting 0,0 always reverts (OracleTimestampMismatch).\n if (cotiOracleTimestamp === 0n) {\n throw new Error('Could not load oracle price data for the COTI portal fee. Please try again.');\n }\n\n // Default fallback 12M — native COTI bridge.deposit() triggers MPC operations.\n let safeGasLimit = 12000000n;\n\n logger.log('Native COTI deposit prepared', { token: txPublicToken.symbol, gasLimit: safeGasLimit.toString() });\n\n try {\n logger.log(\"🔍 Attempting calculateGasMargin for native COTI deposit...\");\n const estimatedGas = await calculateGasMargin(\n bridge,\n 'deposit(uint256,uint256)',\n [cotiOracleTimestamp, tokenOracleTimestamp],\n 12000000n,\n { value: amountWei }\n );\n const buffered = (estimatedGas * 130n) / 100n;\n safeGasLimit = buffered > 900000n ? buffered : 900000n;\n logger.log(`🔍 Native COTI deposit gas: estimated=${estimatedGas}, buffered=${buffered}, final=${safeGasLimit}`);\n /* v8 ignore start -- calculateGasMargin never throws; it returns fallbackGasLimit internally */\n } catch (e) {\n logger.warn(\"⚠️ Native COTI deposit gas estimation failed, falling back to 12M:\", e);\n }\n /* v8 ignore stop */\n\n tx = await bridge['deposit(uint256,uint256)'](cotiOracleTimestamp, tokenOracleTimestamp, { value: amountWei, gasLimit: safeGasLimit });\n }\n } catch (e) {\n setIsBridgingLoading(false);\n setToastState(prev => ({ ...prev, visible: false }));\n throw e;\n }\n } else {\n // Withdraw (Portal Out) — Uses bridge.withdraw()\n logger.log(`Withdrawing ${txAmount} p.${txPublicToken.symbol}`);\n\n try {\n // Check Allowance first (similar to Deposit)\n const parsedAmount = ethers.parseUnits(txAmount, privateDecimals);\n \n // We don't have an easy way to check encrypted allowance here, \n // but we rely on the component gating the transition to Withdraw.\n // However, let's at least ensure we have the correct signer.\n\n const walletAddress = await signer.getAddress();\n \n // 5. Call bridge.withdraw(amount)\n setToastState({\n visible: true,\n title: 'Confirm Withdrawal',\n message: 'Please confirm the withdrawal transaction in your wallet.'\n });\n\n const bridgeAbi = isErc20 ? BRIDGE_ERC20_ABI : BRIDGE_ABI;\n const bridgeContract = new ethers.Contract(bridgeAddress, bridgeAbi, signer);\n\n // Fetch the native COTI fee for the bridge withdrawal\n // Compute the dynamic fee from on-chain estimateWithdrawFee\n let nativeFee = 0n;\n let cotiOracleTimestamp = 0n;\n let tokenOracleTimestamp = 0n;\n if (isErc20) {\n try {\n const rpcUrl = getRpcUrlForChain(Number((await provider.getNetwork()).chainId));\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const feeEstimate = await estimateBridgeFee(txPublicToken.symbol, txAmount, rpcProvider);\n if (feeEstimate.withdrawFee !== 'Error') {\n nativeFee = ethers.parseEther(feeEstimate.withdrawFee);\n }\n cotiOracleTimestamp = BigInt(feeEstimate.cotiLastUpdated || '0');\n tokenOracleTimestamp = BigInt(feeEstimate.tokenLastUpdated || '0');\n logger.log('Computed COTI fee for withdraw');\n logger.log('Oracle timestamps loaded for withdraw', {\n coti: cotiOracleTimestamp.toString(),\n token: tokenOracleTimestamp.toString(),\n });\n } catch (e) {\n logger.warn(\"⚠️ Could not compute dynamic fee for withdraw, defaulting to 0:\", e);\n }\n } else {\n // Native COTI withdrawal — get dual oracle timestamps\n try {\n const rpcUrl = getRpcUrlForChain(Number((await provider.getNetwork()).chainId));\n const rpcProvider = new ethers.JsonRpcProvider(rpcUrl);\n const feeEstimate = await estimateBridgeFee('COTI', txAmount, rpcProvider);\n cotiOracleTimestamp = BigInt(feeEstimate.cotiLastUpdated || '0');\n tokenOracleTimestamp = cotiOracleTimestamp;\n logger.log('Oracle timestamps loaded for native withdraw', {\n coti: cotiOracleTimestamp.toString(),\n token: tokenOracleTimestamp.toString(),\n });\n } catch (e) {\n logger.warn(\"⚠️ Could not fetch oracle timestamps for withdraw:\", e);\n }\n }\n\n // The bridge enforces strict equality between these timestamps and the\n // on-chain oracle rows — submitting 0,0 always reverts (OracleTimestampMismatch).\n if (cotiOracleTimestamp === 0n || tokenOracleTimestamp === 0n) {\n throw new Error(`Could not load oracle price data for the ${txPublicToken.symbol} portal fee. Please try again.`);\n }\n\n logger.log(\"🔄 Executing Withdraw via bridge.withdraw()...\");\n // Default fallback gas limit for MPC operations.\n // COTI node's estimateGas can under-count, but we will try to calculate dynamically.\n let safeGasLimit = 12000000n;\n\n logger.log('Withdraw prepared', { token: txPublicToken.symbol, gasLimit: safeGasLimit.toString() });\n\n // CRITICAL: We also bypass the Coti provider here because it strips the data field\n // from normal (non-encrypted) transactions. Without this, msg.data lands as \"\" and reverts.\n const withdrawCalldata = bridgeContract.interface.encodeFunctionData('withdraw(uint256,uint256,uint256)', [amountWei, cotiOracleTimestamp, tokenOracleTimestamp]);\n\n try {\n logger.log(\"🔍 Attempting eth_estimateGas for withdraw...\");\n // Use direct COTI RPC for the estimate — wallet providers (Rabby/MetaMask)\n // strip revert data from -32603 errors, making it impossible to decode\n // custom errors like InsufficientBridgeLiquidity. The direct RPC returns\n // the full revert data in the error response.\n const network = await provider.getNetwork();\n const estimateProvider = new ethers.JsonRpcProvider(\n getRpcUrlForChain(Number(network.chainId))\n );\n const gasEstimate = await estimateProvider.estimateGas({\n from: walletAddress,\n to: bridgeAddress,\n data: withdrawCalldata,\n value: nativeFee,\n });\n // Add 30% buffer — MPC operations have significant gas variance between\n // estimation and execution, 10% is not enough and causes silent reverts.\n safeGasLimit = (gasEstimate * 130n) / 100n;\n logger.log(`🔍 Withdraw gas estimation successful: ${gasEstimate.toString()} → with 30% buffer: ${safeGasLimit.toString()}`);\n } catch (estimateErr: any) {\n // The estimate reverted — decode the error and abort rather than\n // submitting a tx that will certainly fail on-chain.\n logger.warn(\"⚠️ Withdraw gas estimation failed:\", estimateErr?.shortMessage || estimateErr?.message);\n\n const knownSelectors: Record<string, string> = {\n '0xaae25839': 'Insufficient bridge liquidity. Please try a smaller amount.',\n '0x83b5f08b': 'Not enough COTI to pay the portal fee.',\n '0xb6d6e7d6': 'Not enough COTI balance to pay gas fees.',\n '0x0fdbcf37': 'Withdrawal amount is below the minimum allowed.',\n '0x9aae5367': 'Withdrawal amount exceeds the maximum allowed.',\n '0xfb291504': 'Deposits are currently disabled for this bridge.',\n '0xcbca5aa2': 'Amount cannot be zero.',\n '0x045c4b02': 'Token transfer failed. Please check your balance and approval.',\n '0x997c558e': 'The price quote expired before the transaction was confirmed.',\n };\n\n // ethers v6 JsonRpcProvider puts revert data in error.data or error.info.error.data\n const errData = estimateErr?.data\n || estimateErr?.info?.error?.data\n || estimateErr?.error?.data\n || '';\n const selector = typeof errData === 'string' && errData.length >= 10\n ? errData.slice(0, 10)\n : '';\n\n if (selector && knownSelectors[selector]) {\n throw Object.assign(new Error(knownSelectors[selector]), {\n cause: estimateErr,\n });\n }\n\n // Check if the error message contains \"execution reverted\"\n const msg = estimateErr?.message || estimateErr?.shortMessage || '';\n if (msg.includes('execution reverted') || msg.includes('revert')) {\n throw Object.assign(\n new Error('Transaction would fail on-chain. The bridge may have insufficient liquidity or your balance is too low.'),\n { cause: estimateErr },\n );\n }\n\n // For non-revert errors (network timeout, etc.), fall back to 12M and try anyway\n logger.warn(\" Non-revert estimation error, proceeding with 12M gas limit\");\n }\n\n const rawWithdrawTxHash = await (injectedProvider as any).request({\n method: 'eth_sendTransaction',\n params: [{\n from: walletAddress,\n to: bridgeAddress,\n data: withdrawCalldata,\n value: '0x' + nativeFee.toString(16),\n gas: '0x' + safeGasLimit.toString(16)\n }]\n });\n\n logger.log('Withdraw tx sent', { txHash: shortHash(rawWithdrawTxHash) });\n\n // We mock a transaction response shape for the shared logic below\n tx = {\n hash: rawWithdrawTxHash,\n wait: async () => await provider.waitForTransaction(rawWithdrawTxHash)\n } as any;\n\n } catch (e) {\n setIsBridgingLoading(false);\n setToastState(prev => ({ ...prev, visible: false }));\n throw e;\n }\n }\n\n // ... (Rest of function)\n\n // Gas Estimation Logic (Updated also)\n // ... (Wait, I need to update Gas Estimation separately below)\n\n\n logger.log('Transaction sent', { txHash: shortHash(tx.hash) });\n capturedTxHash = tx.hash;\n onProgress?.('transfer-start', tx.hash);\n\n // Show processing toast now that we have the tx\n setToastState({\n visible: true,\n title: 'Processing Transaction',\n message: 'Transaction sent to network. Waiting for confirmation...'\n });\n\n const receipt = await tx.wait();\n logger.log('Transaction confirmed', {\n status: receipt.status,\n blockNumber: receipt.blockNumber,\n gasUsed: receipt.gasUsed?.toString(),\n gasLimit: receipt.gasLimit?.toString() ?? 'n/a',\n });\n\n // Validate transaction succeeded on-chain\n if (receipt.status !== 1) {\n const gasUsed = receipt.gasUsed ? Number(receipt.gasUsed) : 0;\n const txHashStr = tx.hash || receipt.hash || '';\n logger.warn('Transaction reverted on-chain', {\n gasUsed,\n txHash: shortHash(txHashStr),\n });\n\n // Try to extract revert reason by replaying the tx via eth_call\n let revertReason = '';\n try {\n // Use direct COTI RPC (not MetaMask) for the replay.\n // Use \"latest\" block — COTI testnet doesn't support historical eth_call.\n // The revert reason should be the same at current state for most errors\n // (InsufficientBridgeLiquidity, BridgePaused, etc.)\n const network = await provider.getNetwork();\n const replayProvider = new ethers.JsonRpcProvider(\n getRpcUrlForChain(Number(network.chainId))\n );\n await replayProvider.call({\n to: receipt.to,\n from: receipt.from,\n data: receipt.data || undefined,\n value: receipt.value || undefined,\n });\n } catch (replayErr: any) {\n // The replay should fail with the revert reason\n const errorName = replayErr.errorName || replayErr.revert?.name;\n const revertData = replayErr.data || replayErr.error?.data;\n\n // Check known error names\n const knownErrors: Record<string, string> = {\n 'InsufficientCotiFee': 'Not enough COTI to pay the portal fee.',\n 'InsufficientEthBalance': 'Not enough COTI balance to pay gas fees.',\n 'DepositBelowMinimum': 'Deposit amount is below the minimum allowed.',\n 'DepositExceedsMaximum': 'Deposit amount exceeds the maximum allowed.',\n 'WithdrawBelowMinimum': 'Withdrawal amount is below the minimum allowed.',\n 'WithdrawExceedsMaximum': 'Withdrawal amount exceeds the maximum allowed.',\n 'DepositDisabled': 'Deposits are currently disabled for this bridge.',\n 'BridgePaused': 'Bridge is currently paused.',\n 'AmountZero': 'Amount cannot be zero.',\n 'InsufficientBridgeLiquidity': 'Insufficient bridge liquidity.',\n 'TokenTransferFailed': 'Token transfer failed. Check balance and approval.',\n 'OracleTimestampMismatch': 'The price quote expired before the transaction was confirmed.',\n };\n\n if (errorName && knownErrors[errorName]) {\n revertReason = knownErrors[errorName];\n } else if (replayErr.reason) {\n revertReason = replayErr.reason;\n } else if (replayErr.shortMessage) {\n revertReason = replayErr.shortMessage;\n } else if (revertData && typeof revertData === 'string' && revertData.length >= 10) {\n revertReason = `Revert data: ${revertData.slice(0, 10)}`;\n }\n }\n\n const baseMsg = 'Transaction failed on-chain.';\n const detail = revertReason ? ` Reason: ${revertReason}` : '';\n const txLink = txHashStr ? ` TX: ${txHashStr}` : '';\n throw new Error(`${baseMsg}${detail}${txLink}`);\n }\n\n onProgress?.('transfer-complete', tx.hash);\n\n // Update balances (simple mock update for UI responsiveness, real fetch should happen too)\n if (txPublicToken && txAmount) {\n const amountNum = parseFloat(txAmount);\n\n if (txDirection === 'to-private') {\n setPublicTokens(prev => prev.map(t =>\n t.symbol === txPublicToken.symbol\n ? { ...t, balance: formatTokenBalanceDisplay(t.symbol, parseFloat(t.balance) - amountNum) }\n : t\n ));\n setPrivateTokens(prev => prev.map(t =>\n t.symbol === 'p.' + txPublicToken.symbol\n ? { ...t, balance: formatTokenBalanceDisplay(t.symbol, parseFloat(t.balance) + amountNum) }\n : t\n ));\n } else {\n setPublicTokens(prev => prev.map(t =>\n t.symbol === txPublicToken.symbol\n ? { ...t, balance: formatTokenBalanceDisplay(t.symbol, parseFloat(t.balance) + amountNum) }\n : t\n ));\n setPrivateTokens(prev => prev.map(t =>\n t.symbol === 'p.' + txPublicToken.symbol\n ? { ...t, balance: formatTokenBalanceDisplay(t.symbol, parseFloat(t.balance) - amountNum) }\n : t\n ));\n }\n }\n\n if (refreshPrivateBalances) {\n logger.log(\"🔄 Triggering immediate balance refresh...\");\n refreshPrivateBalances().catch(err =>\n logger.error('Immediate balance refresh failed', err),\n );\n }\n\n setToastState({\n visible: true,\n title: 'Transaction Successful',\n message: txDirection === 'to-private'\n ? `Successfully deposited ${txAmount} ${txPublicToken.symbol} to your private balance.`\n : `Successfully withdrew ${txAmount} ${txPublicToken.symbol} to your public balance.`\n });\n\n } catch (error: any) {\n logger.error(\"Transaction failed:\", error);\n\n // In ethers v6, tx.wait() throws CALL_EXCEPTION with receipt attached when tx reverts.\n // Try to decode the custom revert error from the contract ABI.\n if (error.code === 'CALL_EXCEPTION') {\n const revertData = error.data || error.error?.data;\n const errorName = error.errorName || error.revert?.name;\n const gasUsed = error.receipt?.gasUsed ? Number(error.receipt.gasUsed) : 0;\n const failedTxHash = error.receipt?.hash || error.transaction?.hash || capturedTxHash || '';\n logger.warn(`⚠️ CALL_EXCEPTION on-chain revert. Error: ${errorName || 'unknown'}, Gas used: ${gasUsed}`);\n\n const throwRevertError = (message: string): never => {\n const revertError = new Error(message) as Error & { txHash?: string };\n if (failedTxHash) revertError.txHash = failedTxHash;\n throw revertError;\n };\n\n // Map known contract custom errors to user-friendly messages\n const knownErrors: Record<string, string> = {\n 'InsufficientCotiFee': 'Not enough COTI to pay the portal fee. Please add COTI to your wallet.',\n 'InsufficientEthBalance': 'Not enough COTI balance to pay gas fees. Please add COTI to your wallet.',\n 'DepositBelowMinimum': 'Deposit amount is below the minimum allowed.',\n 'DepositExceedsMaximum': 'Deposit amount exceeds the maximum allowed.',\n 'WithdrawBelowMinimum': 'Withdrawal amount is below the minimum allowed.',\n 'WithdrawExceedsMaximum': 'Withdrawal amount exceeds the maximum allowed.',\n 'DepositDisabled': 'Deposits are currently disabled for this bridge.',\n 'AmountZero': 'Amount cannot be zero.',\n 'InsufficientBridgeLiquidity': 'Insufficient bridge liquidity. Please try a smaller amount.',\n 'TokenTransferFailed': 'Token transfer failed. Please check your token balance and approval.',\n 'InsufficientAccumulatedFees': 'Insufficient accumulated fees.',\n 'OracleTimestampMismatch': 'The price quote expired before the transaction was confirmed.',\n };\n\n if (errorName && knownErrors[errorName]) {\n throwRevertError(knownErrors[errorName]);\n }\n\n // Try to match revert data against known error selectors if errorName wasn't decoded\n if (revertData && typeof revertData === 'string' && revertData.length >= 10) {\n const selector = revertData.slice(0, 10);\n const selectorMap: Record<string, string> = {\n '0x83b5f08b': 'Not enough COTI to pay the portal fee. Please add COTI to your wallet.',\n '0xb6d6e7d6': 'Not enough COTI balance to pay gas fees. Please add COTI to your wallet.',\n '0xc24b1b61': 'Deposit amount is below the minimum allowed.',\n '0xd630062d': 'Deposit amount exceeds the maximum allowed.',\n '0x0fdbcf37': 'Withdrawal amount is below the minimum allowed.',\n '0x9aae5367': 'Withdrawal amount exceeds the maximum allowed.',\n '0xfb291504': 'Deposits are currently disabled for this bridge.',\n '0xcbca5aa2': 'Amount cannot be zero.',\n '0xaae25839': 'Insufficient bridge liquidity. Please try a smaller amount.',\n '0x045c4b02': 'Token transfer failed. Please check your token balance and approval.',\n '0x997c558e': 'The price quote expired before the transaction was confirmed.',\n };\n if (selectorMap[selector]) {\n throwRevertError(selectorMap[selector]);\n }\n }\n\n // Generic revert — show a user-friendly message with a transaction link when available\n const explorerBase = getExplorerBaseUrlForChain(connectedChainId).replace(/\\/$/, '');\n const txLink = failedTxHash ? ` ${explorerBase}/tx/${failedTxHash}` : '';\n throwRevertError(`The transaction couldn't be completed. Please try again or contact support if the problem persists.${txLink}`);\n }\n\n let errorMessage = error.reason || error.message || \"Unknown error occurred\";\n\n if (errorMessage.includes(\"user rejected\")) {\n errorMessage = \"Transaction rejected by user.\";\n }\n\n setToastState({\n visible: true,\n title: 'Transaction Failed',\n message: errorMessage\n });\n // Re-throw so the caller (handleSwap) knows it failed\n throw error;\n } finally {\n setIsBridgingLoading(false);\n }\n }, [\n publicTokens,\n walletAddress,\n setPublicTokens,\n setPrivateTokens,\n setToastState,\n refreshPrivateBalances,\n refreshPublicBalances,\n upsertPodRequest,\n getPodWithdrawPermit,\n clearPodWithdrawPermit,\n resolveInjectedProvider,\n ]);\n return { executeTransaction, isBridgingLoading };\n};\n","import { useMemo } from 'react';\nimport { getChainConfig } from '../../chains';\nimport { useCotiBridgeFees } from './useCotiBridgeFees';\nimport { usePodPortalFees } from './usePodPortalFees';\nimport type { UsePrivacyBridgeGasOptions } from './usePrivacyBridgeGas.types';\n\nexport type { UsePrivacyBridgeGasOptions } from './usePrivacyBridgeGas.types';\n\n/** Routes fee estimation to COTI bridge or PoD portal hooks by chain strategy. */\nexport const usePrivacyBridgeGas = (options: UsePrivacyBridgeGasOptions) => {\n const isPodChain = getChainConfig(options.chainId)?.portalStrategy === 'pod-privacy-portal';\n const podFees = usePodPortalFees(options);\n const cotiFees = useCotiBridgeFees(options);\n\n return useMemo(\n () => (isPodChain ? podFees : cotiFees),\n [isPodChain, podFees, cotiFees],\n );\n};\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { getChainConfig } from '../../chains';\nimport { quoteCotiBridgeFees } from '../../chains/coti-bridge/fees';\nimport { logger } from '../../lib/logger';\nimport type { Token } from './types';\n\nexport interface UseCotiBridgeFeesOptions {\n isConnected: boolean;\n walletAddress?: string;\n chainId?: number;\n publicTokens: Token[];\n selectedTokenIndex: number;\n direction: 'to-private' | 'to-public';\n amount: string;\n}\n\n/** COTI bridge portal + gas fee quotes (isolated from PoD). */\nexport const useCotiBridgeFees = ({\n isConnected,\n walletAddress,\n chainId,\n publicTokens,\n selectedTokenIndex,\n direction,\n amount,\n}: UseCotiBridgeFeesOptions) => {\n const [portalFeeCoti, setPortalFeeCoti] = useState<string | null>(null);\n const [estimatedGasFee, setEstimatedGasFee] = useState<string | null>(null);\n const [feeDebugInfo, setFeeDebugInfo] = useState<{\n cotiLastUpdated: string;\n tokenLastUpdated: string;\n blockTimestamp: string;\n } | null>(null);\n const [isGasEstimating, setIsGasEstimating] = useState(false);\n const requestId = useRef(0);\n\n const refreshFees = useCallback(async () => {\n const id = ++requestId.current;\n\n if (!isConnected || !chainId) {\n setPortalFeeCoti(null);\n setEstimatedGasFee(null);\n setFeeDebugInfo(null);\n return;\n }\n\n const chainConfig = getChainConfig(chainId);\n if (chainConfig?.portalStrategy !== 'coti-bridge') {\n return;\n }\n\n const symbol = publicTokens[selectedTokenIndex]?.symbol?.replace('p.', '') || '';\n const currentAmount = amount && parseFloat(amount) > 0 ? amount : '0';\n\n if (currentAmount === '0') {\n if (id === requestId.current) {\n setPortalFeeCoti(null);\n setEstimatedGasFee(null);\n setFeeDebugInfo(null);\n }\n return;\n }\n\n setIsGasEstimating(true);\n try {\n const quote = await quoteCotiBridgeFees({\n chainId,\n symbol,\n direction,\n amount: currentAmount,\n walletAddress,\n });\n\n if (id === requestId.current) {\n setPortalFeeCoti(quote.portalFeeCoti);\n setEstimatedGasFee(quote.estimatedGasFee);\n setFeeDebugInfo(quote.feeDebugInfo);\n }\n } catch (error) {\n logger.error('Error estimating COTI bridge fees:', error);\n if (id === requestId.current) {\n setPortalFeeCoti(null);\n setEstimatedGasFee(null);\n setFeeDebugInfo(null);\n }\n } finally {\n if (id === requestId.current) {\n setIsGasEstimating(false);\n }\n }\n }, [direction, isConnected, chainId, walletAddress, selectedTokenIndex, publicTokens, amount]);\n\n useEffect(() => {\n const timeoutId = setTimeout(() => {\n void refreshFees();\n }, 400);\n return () => clearTimeout(timeoutId);\n }, [refreshFees]);\n\n return {\n portalFeeCoti,\n estimatedGasFee,\n feeDebugInfo,\n isGasEstimating,\n updateGasFee: refreshFees,\n portalFee: null,\n portalFeeSymbol: 'COTI',\n podInboxFee: null,\n l1GasFee: null,\n isPodChain: false,\n };\n};\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { useAccount } from 'wagmi';\nimport { ethers } from 'ethers';\nimport { CONTRACT_ADDRESSES } from '../../contracts/config';\nimport { getChainConfig, getPublicTokensForChain, getPrivateTokensForChain } from '../../chains';\nimport { resolvePodPortalAddresses } from '../../chains/portal/helpers';\nimport { quotePodPortalTransactionFees } from '../../chains/portal/fees';\nimport { logger } from '../../lib/logger';\nimport type { EIP1193Provider } from '../../lib/ethereum';\nimport type { Token } from './types';\n\nexport interface UsePodPortalFeesOptions {\n isConnected: boolean;\n walletAddress?: string;\n chainId?: number;\n publicTokens: Token[];\n selectedTokenIndex: number;\n direction: 'to-private' | 'to-public';\n amount: string;\n}\n\n/** PoD Privacy Portal fee quotes — portal, inbox, and L1 gas in native token. */\nexport const usePodPortalFees = ({\n isConnected,\n walletAddress,\n chainId,\n publicTokens,\n selectedTokenIndex,\n direction,\n amount,\n}: UsePodPortalFeesOptions) => {\n const { connector } = useAccount();\n const [portalFee, setPortalFee] = useState<string | null>(null);\n const [portalFeeSymbol, setPortalFeeSymbol] = useState('ETH');\n const [podInboxFee, setPodInboxFee] = useState<string | null>(null);\n const [l1GasFee, setL1GasFee] = useState<string | null>(null);\n const [isGasEstimating, setIsGasEstimating] = useState(false);\n const requestId = useRef(0);\n\n const refreshFees = useCallback(async () => {\n const id = ++requestId.current;\n\n if (!isConnected || !chainId || !walletAddress) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n return;\n }\n\n const chainConfig = getChainConfig(chainId);\n if (chainConfig?.portalStrategy !== 'pod-privacy-portal') {\n return;\n }\n\n const tokenSymbol = publicTokens[selectedTokenIndex]?.symbol || '';\n const symbol = tokenSymbol.replace('p.', '');\n const currentAmount = amount && parseFloat(amount) > 0 ? amount : '0';\n\n if (currentAmount === '0') {\n if (id === requestId.current) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n }\n return;\n }\n\n setIsGasEstimating(true);\n try {\n if (!connector?.getProvider) {\n if (id === requestId.current) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n }\n return;\n }\n\n const injected = await connector.getProvider() as EIP1193Provider | undefined;\n if (!injected?.request) {\n if (id === requestId.current) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n }\n return;\n }\n\n const podProvider = new ethers.BrowserProvider(injected);\n const addresses = CONTRACT_ADDRESSES[chainId];\n const pubTok = getPublicTokensForChain(chainId).find(\n t => t.symbol === symbol && !t.isPrivate,\n );\n const privTok = getPrivateTokensForChain(chainId).find(\n t => t.symbol === `p.${symbol}`,\n );\n const resolved = pubTok && addresses\n ? resolvePodPortalAddresses({ addresses, pubCfg: pubTok, privCfg: privTok })\n : null;\n\n if (!resolved) {\n if (id === requestId.current) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n }\n return;\n }\n\n const signer = await podProvider.getSigner();\n const quote = await quotePodPortalTransactionFees({\n runner: signer,\n chainId,\n portalAddress: resolved.portalAddress,\n pubTok,\n amount: currentAmount,\n direction,\n });\n\n logger.debug('[usePodPortalFees] fees quoted', {\n chainId,\n symbol,\n direction,\n amount: currentAmount,\n portalFee: quote.display.portalFee,\n podInboxFee: quote.display.podInboxFee,\n l1Gas: quote.display.l1Gas,\n });\n\n if (id === requestId.current) {\n setPortalFeeSymbol(quote.display.portalFeeSymbol);\n setPortalFee(quote.display.portalFee === '0' ? null : quote.display.portalFee);\n setPodInboxFee(quote.display.podInboxFee === '0' ? null : quote.display.podInboxFee);\n setL1GasFee(quote.display.l1Gas === '0' ? null : quote.display.l1Gas);\n }\n } catch (error) {\n logger.error('Error estimating PoD portal fees:', error);\n if (id === requestId.current) {\n setPortalFee(null);\n setPodInboxFee(null);\n setL1GasFee(null);\n }\n } finally {\n if (id === requestId.current) {\n setIsGasEstimating(false);\n }\n }\n }, [direction, isConnected, chainId, walletAddress, selectedTokenIndex, publicTokens, connector, amount]);\n\n useEffect(() => {\n const timeoutId = setTimeout(() => {\n void refreshFees();\n }, 400);\n return () => clearTimeout(timeoutId);\n }, [refreshFees]);\n\n return {\n portalFee,\n portalFeeSymbol,\n podInboxFee,\n l1GasFee,\n isGasEstimating,\n refreshFees,\n portalFeeCoti: null,\n estimatedGasFee: l1GasFee,\n updateGasFee: refreshFees,\n feeDebugInfo: null,\n isPodChain: true,\n };\n};\n","import { useEffect, useCallback, useState } from 'react';\nimport { logger } from '../lib/logger';\nimport { useAccount } from 'wagmi';\nimport { getPluginConfig } from '../config/plugin';\nimport { DEFAULT_CHAIN_ID, isSupportedChain } from '../chains';\nimport { useWalletType } from './useWalletType';\n\nexport interface NetworkEnforcerResult {\n /** Wallet is on a chain outside {@link CHAIN_CONFIGS} */\n isUnsupportedNetwork: boolean;\n /** Wallet is on a supported chain but not the configured enforcement target */\n isOffTargetNetwork: boolean;\n /**\n * @deprecated Use {@link isUnsupportedNetwork}. Kept for backward compatibility.\n */\n isWrongNetwork: boolean;\n /** Error/warning message when network switch is rejected or fails */\n networkMismatchWarning: string | null;\n /** Manually trigger network enforcement (switches to configured target) */\n enforceNetwork: () => Promise<void>;\n}\n\n/**\n * Network enforcement hook that supports both MetaMask (direct RPC) and\n * non-MetaMask wallets.\n *\n * - Both paths use the provided `switchNetwork` callback (the unified router),\n * which handles WalletConnect sessions (namespace check, wallet_addEthereumChain\n * push, deep-link foregrounding) as well as injected providers\n * - {@link isUnsupportedNetwork}: chain ∉ {@link CHAIN_CONFIGS}\n * - {@link isOffTargetNetwork}: supported chain ≠ configured target ({@link getTargetChainId})\n * - {@link enforceNetwork} switches to the configured target when current chain ≠ target\n *\n * @param chainId - Current chain ID as a string (decimal or hex), used for MetaMask path\n * @param switchNetwork - Network switch function (wallet_switchEthereumChain or unified router)\n */\nexport const useNetworkEnforcer = (\n chainId: string | null,\n switchNetwork: (chainId: string) => Promise<boolean>\n): NetworkEnforcerResult => {\n const { chain } = useAccount();\n const { isMetaMaskWithSnap, walletType } = useWalletType();\n const [networkMismatchWarning, setNetworkMismatchWarning] = useState<string | null>(null);\n\n const envDefaultNetwork = getPluginConfig().defaultNetworkId;\n\n /**\n * Determines the target chain ID to enforce.\n * Uses the plugin config's defaultNetworkId if set, otherwise {@link DEFAULT_CHAIN_ID} (COTI Testnet).\n */\n const getTargetChainId = useCallback((): number => {\n if (envDefaultNetwork) {\n try {\n const parsed = envDefaultNetwork.startsWith('0x')\n ? parseInt(envDefaultNetwork, 16)\n : Number(envDefaultNetwork);\n if (isSupportedChain(parsed)) return parsed;\n } catch {\n // Fall through to default\n }\n }\n return DEFAULT_CHAIN_ID;\n }, [envDefaultNetwork]);\n\n const getCurrentChainNum = useCallback((): number | null => {\n if (walletType === 'metamask' || isMetaMaskWithSnap) {\n if (!chainId) return null;\n try {\n return chainId.startsWith('0x')\n ? parseInt(chainId, 16)\n : Number(chainId);\n } catch {\n return null;\n }\n }\n return chain?.id ?? null;\n }, [chainId, chain, walletType, isMetaMaskWithSnap]);\n\n const isUnsupportedNetwork = useCallback((): boolean => {\n const current = getCurrentChainNum();\n if (current == null) return false;\n return !isSupportedChain(current);\n }, [getCurrentChainNum]);\n\n const isOffTargetNetwork = useCallback((): boolean => {\n const current = getCurrentChainNum();\n if (current == null || !isSupportedChain(current)) return false;\n return current !== getTargetChainId();\n }, [getCurrentChainNum, getTargetChainId]);\n\n /**\n * Enforce network switch.\n * Both MetaMask and non-MetaMask wallets use the provided `switchNetwork`\n * router, which picks the right transport (direct RPC, injected provider,\n * or WalletConnect add-chain + deep-link flow) for the active connection.\n */\n const enforceNetwork = useCallback(async () => {\n const targetChainId = getTargetChainId();\n\n if (walletType === 'metamask' || isMetaMaskWithSnap) {\n if (!chainId) return;\n\n const currentChainIdHex = (() => {\n try {\n return '0x' + BigInt(chainId).toString(16);\n } catch {\n return chainId.startsWith('0x')\n ? chainId\n : '0x' + Number(chainId).toString(16);\n }\n })();\n\n const targetHex = '0x' + targetChainId.toString(16);\n\n if (currentChainIdHex.toLowerCase() !== targetHex.toLowerCase()) {\n logger.warn(\n `[NetworkEnforcer] MetaMask on wrong network: ${currentChainIdHex}. Enforcing: ${targetHex}`\n );\n try {\n const success = await switchNetwork(targetHex);\n if (!success) {\n setNetworkMismatchWarning(\n 'Network switch was rejected. Please switch to a supported network to continue.'\n );\n } else {\n setNetworkMismatchWarning(null);\n }\n } catch (err) {\n logger.error('[NetworkEnforcer] MetaMask switch error:', err);\n setNetworkMismatchWarning(\n 'Failed to switch network. Please switch to a supported network manually.'\n );\n }\n }\n } else {\n if (!chain) return;\n\n if (chain.id !== targetChainId) {\n logger.warn(\n `[NetworkEnforcer] Non-MetaMask wallet on chain ${chain.id}. Enforcing: ${targetChainId}`\n );\n const targetHex = '0x' + targetChainId.toString(16);\n try {\n // Route through the unified switchNetwork router rather than wagmi's\n // switchChainAsync: for WalletConnect sessions it pre-checks the\n // approved namespace, pushes the chain with wallet_addEthereumChain\n // and deep-links the wallet app to the foreground so the user\n // actually sees the approval prompt.\n const success = await switchNetwork(targetHex);\n if (!success) {\n setNetworkMismatchWarning(\n 'Network switch was rejected. Please switch to a supported network to continue.'\n );\n } else {\n setNetworkMismatchWarning(null);\n }\n } catch (err) {\n logger.error('[NetworkEnforcer] switchNetwork error:', err);\n setNetworkMismatchWarning(\n 'Network switch was rejected. Please switch to a supported network to continue.'\n );\n }\n }\n }\n }, [\n chainId,\n chain,\n walletType,\n isMetaMaskWithSnap,\n switchNetwork,\n getTargetChainId,\n ]);\n\n const unsupported = isUnsupportedNetwork();\n const offTarget = isOffTargetNetwork();\n\n // Auto-enforce on chain changes (disabled in favor of NetworkGuard UI, but available)\n useEffect(() => {\n // Automatic enforcement is disabled in favor of NetworkGuard UI\n // enforceNetwork();\n }, [enforceNetwork]);\n\n // Clear warning when on the configured target (supported and not off-target)\n useEffect(() => {\n if (!unsupported && !offTarget) {\n setNetworkMismatchWarning(null);\n }\n }, [unsupported, offTarget]);\n\n return {\n isUnsupportedNetwork: unsupported,\n isOffTargetNetwork: offTarget,\n isWrongNetwork: unsupported,\n networkMismatchWarning,\n enforceNetwork,\n };\n};\n","import { useState, useEffect, useMemo } from 'react';\nimport { useAccount } from 'wagmi';\nimport { getPluginConfig } from '../config/plugin';\nimport { isMetaMaskMobileBrowser } from '../lib/metaMaskMobile';\n\n/**\n * Normalized wallet type derived from wagmi's stable `connector.id`.\n * Uses connector.id (wagmi-controlled) — NOT window.ethereum.isMetaMask.\n */\nexport type WalletType = 'metamask' | 'coinbase' | 'walletconnect' | 'rainbow' | 'phantom' | 'trust' | 'rabby' | 'zerion' | 'ledger' | 'unknown';\n\n/**\n * Information about the connected wallet type and its capabilities.\n */\nexport interface WalletTypeInfo {\n /** True only when connector is MetaMask AND COTI Snap is installed */\n isMetaMaskWithSnap: boolean;\n /** Normalized wallet identifier derived from connector.id */\n walletType: WalletType;\n /** Raw wagmi connector.id value */\n connectorId: string | undefined;\n}\n\n/**\n * Static mapping from wagmi connector.id to normalized WalletType.\n * This mapping is deterministic and does not rely on self-reported provider properties.\n * Includes both standard wagmi connector IDs and EIP-6963 rdns-based IDs.\n */\nconst CONNECTOR_ID_TO_WALLET_TYPE: Record<string, WalletType> = {\n // Standard wagmi connector IDs\n metaMask: 'metamask',\n coinbaseWalletSDK: 'coinbase',\n walletConnect: 'walletconnect',\n rainbow: 'rainbow',\n // EIP-6963 rdns-based connector IDs\n 'io.metamask': 'metamask',\n 'io.metamask.flask': 'metamask',\n metamask: 'metamask',\n phantom: 'phantom',\n 'trust-extension': 'trust',\n trustWallet: 'trust',\n rabby: 'rabby',\n zerion: 'zerion',\n ledger: 'ledger',\n};\n\n/**\n * Maps a wagmi connector.id to a normalized WalletType.\n * Performs exact match first, then case-insensitive partial match for MetaMask variants.\n * Falls back to 'unknown' for unrecognized connector IDs.\n */\nexport function mapConnectorIdToWalletType(connectorId: string | undefined): WalletType {\n if (!connectorId) return 'unknown';\n // Exact match\n if (CONNECTOR_ID_TO_WALLET_TYPE[connectorId]) {\n return CONNECTOR_ID_TO_WALLET_TYPE[connectorId];\n }\n // Case-insensitive partial match for MetaMask variants (e.g. \"io.metamask.flask\")\n const lower = connectorId.toLowerCase();\n if (lower.includes('metamask')) return 'metamask';\n if (lower.includes('coinbase')) return 'coinbase';\n if (lower.includes('walletconnect')) return 'walletconnect';\n if (lower.includes('phantom')) return 'phantom';\n if (lower.includes('trust')) return 'trust';\n if (lower.includes('rabby')) return 'rabby';\n if (lower.includes('zerion')) return 'zerion';\n if (lower.includes('rainbow')) return 'rainbow';\n if (lower.includes('ledger')) return 'ledger';\n return 'unknown';\n}\n\n/** Default state when no connector is available */\nconst DISCONNECTED_STATE: WalletTypeInfo = {\n isMetaMaskWithSnap: false,\n walletType: 'unknown',\n connectorId: undefined,\n};\n\n/**\n * Detects the connected wallet type using wagmi's stable `connector.id`.\n * Returns routing information for AES key retrieval.\n *\n * Security: Uses `connector.id` (wagmi-controlled, stable) rather than\n * `window.ethereum.isMetaMask` (self-reported, spoofable by any wallet).\n *\n * When the wallet type is 'metamask', performs an async Snap installation check\n * via `wallet_getSnaps` to determine if the COTI Snap is available.\n *\n * @returns WalletTypeInfo with wallet type, snap capability, and raw connector ID\n */\nexport function useWalletType(): WalletTypeInfo {\n const { connector } = useAccount();\n const [isMetaMaskWithSnap, setIsMetaMaskWithSnap] = useState(false);\n\n const connectorId = connector?.id;\n const walletType = mapConnectorIdToWalletType(connectorId);\n\n // Perform async Snap installation check when wallet type is 'metamask'\n useEffect(() => {\n let cancelled = false;\n\n if (walletType !== 'metamask' || !connector) {\n setIsMetaMaskWithSnap(false);\n return;\n }\n\n if (isMetaMaskMobileBrowser()) {\n setIsMetaMaskWithSnap(false);\n return;\n }\n\n const checkSnapInstalled = async () => {\n try {\n const provider = await connector.getProvider();\n if (!provider || cancelled) return;\n\n const snapId = getPluginConfig().snapId;\n const snaps = (await (provider as any).request({\n method: 'wallet_getSnaps',\n })) as Record<string, any>;\n\n if (cancelled) return;\n\n // wallet_getSnaps returns { [snapId]: { version, ... } }\n const snapFound = snapId in snaps ||\n Object.values(snaps).some((snap: any) => snap.id === snapId);\n\n setIsMetaMaskWithSnap(snapFound);\n } catch {\n if (!cancelled) {\n setIsMetaMaskWithSnap(false);\n }\n }\n };\n\n checkSnapInstalled();\n\n return () => {\n cancelled = true;\n };\n }, [walletType, connector]);\n\n // Memoize result to avoid re-render loops\n return useMemo<WalletTypeInfo>(() => {\n if (!connectorId) {\n return DISCONNECTED_STATE;\n }\n\n return {\n isMetaMaskWithSnap,\n walletType,\n connectorId,\n };\n }, [isMetaMaskWithSnap, walletType, connectorId]);\n}\n","import React, { useMemo, useState } from 'react';\nimport { usePrivacyBridge } from '../../hooks/usePrivacyBridge';\nimport { usePrivacyBridgeModalsState } from './usePrivacyBridgeModalsState';\nimport { usePrivacyBridgeSession } from './usePrivacyBridgeSession';\nimport { usePrivacyBridgePodState } from './usePrivacyBridgePodState';\nimport {\n PrivacyBridgeContext,\n PrivacyBridgeModalsContext,\n PrivacyBridgeNetworkContext,\n PrivacyBridgePodContext,\n PrivacyBridgeSwapContext,\n PrivacyBridgeTokensContext,\n PrivacyBridgeUnlockContext,\n PrivacyBridgeWalletContext,\n} from './contexts';\nimport { mergePrivacyBridgeSlices, type PrivacyBridgeContextSlices } from './types';\nimport {\n PrivateUnlockProvider,\n type PrivateUnlockProviderOptions,\n} from '../privateUnlock';\n\nexport interface PrivacyBridgeProviderProps {\n children: React.ReactNode;\n privateUnlock?: PrivateUnlockProviderOptions;\n}\n\nexport const PrivacyBridgeProvider: React.FC<PrivacyBridgeProviderProps> = ({\n children,\n privateUnlock,\n}) => {\n const modals = usePrivacyBridgeModalsState();\n const session = usePrivacyBridgeSession({ modals });\n\n const podState = usePrivacyBridgePodState({\n walletAddress: session.walletAddress,\n refreshPrivateBalances: session.refreshPrivateBalances,\n });\n\n const [amount, setAmount] = useState('');\n const [direction, setDirection] = useState<'to-private' | 'to-public'>('to-private');\n const [selectedTokenIndex, setSelectedTokenIndex] = useState(0);\n const [toastState, setToastState] = useState({\n visible: false,\n title: '',\n message: '' as React.ReactNode,\n });\n const [error, setError] = useState<{ title: string; message: string } | null>(null);\n\n const {\n handleSwap,\n isBridgingLoading,\n isApprovalNeeded,\n isApproving,\n handleApprove,\n estimatedGasFee,\n updateGasFee,\n isGasEstimating,\n portalFeeCoti,\n portalFee,\n portalFeeSymbol,\n podInboxFee,\n l1GasFee,\n isPodChain,\n feeDebugInfo,\n } = usePrivacyBridge({\n isConnected: session.isConnected,\n walletAddress: session.walletAddress,\n publicTokens: session.publicTokens,\n setPublicTokens: session.setPublicTokens,\n setPrivateTokens: session.setPrivateTokens,\n setToastState,\n amount,\n setAmount,\n direction,\n setDirection,\n selectedTokenIndex,\n setSelectedTokenIndex,\n error,\n hasSnap: session.hasSnap,\n setHasSnap: session.setHasSnap,\n handleOnboard: session.handleOnboard,\n refreshPublicBalances: session.refreshPublicBalances,\n refreshPrivateBalances: session.refreshPrivateBalances,\n upsertPodRequest: podState.upsertPodRequest,\n sessionAesKey: session.sessionAesKey,\n chainId: session.chainId ? Number(session.chainId) : undefined,\n });\n\n const slices = useMemo((): PrivacyBridgeContextSlices => {\n const wallet = {\n isConnected: session.isConnected,\n walletAddress: session.walletAddress,\n handleConnect: session.handleConnect,\n handleDisconnect: session.handleDisconnect,\n metamaskDetected: session.metamaskDetected,\n };\n\n const network = {\n chainId: session.chainId,\n switchNetwork: session.switchNetwork,\n networkName: session.networkName,\n isUnsupportedNetwork: session.isUnsupportedNetwork,\n isOffTargetNetwork: session.isOffTargetNetwork,\n isWrongNetwork: session.isWrongNetwork,\n networkMismatchWarning: session.networkMismatchWarning,\n enforceNetwork: session.enforceNetwork,\n COTI_MAINNET_ID: session.COTI_MAINNET_ID,\n COTI_TESTNET_ID: session.COTI_TESTNET_ID,\n SEPOLIA_ID: session.SEPOLIA_ID,\n };\n\n const unlock = {\n hasSnap: session.hasSnap,\n snapError: session.snapError,\n hasAesKeyInSnap: session.hasAesKeyInSnap,\n connectToSnap: session.connectToSnap,\n requestSnapConnection: session.requestSnapConnection,\n checkSnapStatus: session.checkSnapStatus,\n sessionAesKey: session.sessionAesKey,\n aesKeyChainId: session.aesKeyChainId,\n setAesKeyChainId: session.setAesKeyChainId,\n isPrivateUnlocked: session.isPrivateUnlocked,\n sendPrivateToken: session.sendPrivateToken,\n encryptPrivateValue: session.encryptPrivateValue,\n decryptPrivateValue: session.decryptPrivateValue,\n refreshPrivateBalances: session.refreshPrivateBalances,\n onboardingError: session.onboardingError,\n onboardingWarning: session.onboardingWarning,\n lockPrivateBalances: session.lockPrivateBalances,\n handleOnboard: session.handleOnboard,\n saveManualAesKey: session.saveManualAesKey,\n handleVerifyKeys: session.handleVerifyKeys,\n showSnapMissingModal: session.showSnapMissingModal,\n setShowSnapMissingModal: session.setShowSnapMissingModal,\n showCotiWalletAesKeyModal: session.showCotiWalletAesKeyModal,\n setShowCotiWalletAesKeyModal: session.setShowCotiWalletAesKeyModal,\n };\n\n const tokens = {\n publicTokens: session.publicTokens,\n privateTokens: session.privateTokens,\n };\n\n const swap = {\n amount,\n direction,\n selectedTokenIndex,\n setAmount,\n setDirection,\n setSelectedTokenIndex,\n handleSwap,\n isBridgingLoading,\n isApprovalNeeded,\n isApproving,\n handleApprove,\n estimatedGasFee,\n updateGasFee,\n isGasEstimating,\n portalFeeCoti,\n portalFee,\n portalFeeSymbol,\n podInboxFee,\n l1GasFee,\n isPodChain,\n feeDebugInfo,\n };\n\n const pod = {\n podRequests: podState.podRequests,\n refreshPodRequest: podState.refreshPodRequest,\n };\n\n return { wallet, network, unlock, tokens, swap, pod, modals };\n }, [\n session,\n modals,\n amount,\n direction,\n selectedTokenIndex,\n handleSwap,\n isBridgingLoading,\n isApprovalNeeded,\n isApproving,\n handleApprove,\n estimatedGasFee,\n updateGasFee,\n isGasEstimating,\n portalFeeCoti,\n portalFee,\n portalFeeSymbol,\n podInboxFee,\n l1GasFee,\n isPodChain,\n feeDebugInfo,\n podState.podRequests,\n podState.refreshPodRequest,\n ]);\n\n const legacyValue = useMemo(() => mergePrivacyBridgeSlices(slices), [slices]);\n\n return (\n <PrivacyBridgeWalletContext.Provider value={slices.wallet}>\n <PrivacyBridgeNetworkContext.Provider value={slices.network}>\n <PrivacyBridgeUnlockContext.Provider value={slices.unlock}>\n <PrivacyBridgeTokensContext.Provider value={slices.tokens}>\n <PrivacyBridgeSwapContext.Provider value={slices.swap}>\n <PrivacyBridgePodContext.Provider value={slices.pod}>\n <PrivacyBridgeModalsContext.Provider value={slices.modals}>\n <PrivacyBridgeContext.Provider value={legacyValue}>\n <PrivateUnlockProvider options={privateUnlock}>\n {children}\n </PrivateUnlockProvider>\n </PrivacyBridgeContext.Provider>\n </PrivacyBridgeModalsContext.Provider>\n </PrivacyBridgePodContext.Provider>\n </PrivacyBridgeSwapContext.Provider>\n </PrivacyBridgeTokensContext.Provider>\n </PrivacyBridgeUnlockContext.Provider>\n </PrivacyBridgeNetworkContext.Provider>\n </PrivacyBridgeWalletContext.Provider>\n );\n};\n","import { useCallback } from 'react';\nimport { logger } from '../lib/logger';\nimport { usePrivacyBridgeAllowance } from './privacyBridge/usePrivacyBridgeAllowance';\nimport { usePrivacyBridgeExecutor } from './privacyBridge/usePrivacyBridgeExecutor';\nimport { usePrivacyBridgeGas } from './privacyBridge/usePrivacyBridgeGas';\nimport type { SwapProgressStage, UsePrivacyBridgeProps } from './privacyBridge/types';\n\nexport type { Token } from './privacyBridge/tokens';\nexport type { SwapProgressStage } from './privacyBridge/types';\nexport { getInitialPublicTokens, getInitialPrivateTokens } from './privacyBridge/tokens';\n\n/**\n * Coordinates allowance, execution, gas estimation, and swap entry flow.\n * Sub-hooks mirror the {@link PrivacyBridgeProvider} facade pattern.\n */\nexport const usePrivacyBridge = ({\n isConnected,\n walletAddress,\n publicTokens,\n setPublicTokens,\n setPrivateTokens,\n setToastState,\n amount,\n setAmount,\n direction,\n setDirection,\n selectedTokenIndex,\n setSelectedTokenIndex,\n error,\n hasSnap,\n setHasSnap,\n handleOnboard,\n refreshPrivateBalances,\n refreshPublicBalances,\n upsertPodRequest,\n sessionAesKey,\n chainId,\n}: UsePrivacyBridgeProps) => {\n const allowance = usePrivacyBridgeAllowance({\n isConnected,\n walletAddress,\n publicTokens,\n amount,\n direction,\n selectedTokenIndex,\n hasSnap,\n setToastState,\n sessionAesKey,\n chainId,\n });\n\n const { executeTransaction, isBridgingLoading } = usePrivacyBridgeExecutor({\n walletAddress,\n publicTokens,\n setPublicTokens,\n setPrivateTokens,\n setToastState,\n refreshPrivateBalances,\n refreshPublicBalances,\n upsertPodRequest,\n getPodWithdrawPermit: allowance.getPodWithdrawPermit,\n clearPodWithdrawPermit: allowance.clearPodWithdrawPermit,\n });\n\n const gas = usePrivacyBridgeGas({\n isConnected,\n walletAddress,\n chainId,\n publicTokens,\n selectedTokenIndex,\n direction,\n amount,\n });\n\n const handleSwap = useCallback(\n async (\n overrideAmount?: string,\n overrideDirection?: 'to-private' | 'to-public',\n overrideTokenIndex?: number,\n onProgress?: (stage: SwapProgressStage, txHash?: string) => void,\n ) => {\n const currentAmount = overrideAmount !== undefined ? overrideAmount : amount;\n const currentDirection = overrideDirection !== undefined ? overrideDirection : direction;\n const currentIndex = overrideTokenIndex !== undefined ? overrideTokenIndex : selectedTokenIndex;\n\n const currentAmountNum = parseFloat(currentAmount);\n\n logger.log('🚀 [handleSwap] Entry:', {\n currentAmount,\n currentDirection,\n currentIndex,\n hasSnap,\n sessionAesKeyAvailable: !!sessionAesKey,\n isBridgingLoading,\n error: !!error,\n });\n\n if (!currentAmount || !!error || currentAmountNum <= 0) return;\n\n if (isBridgingLoading) {\n logger.warn('Transaction already in progress, ignoring duplicate submission.');\n return;\n }\n\n const currentPub = publicTokens[currentIndex];\n const isErc20Token =\n ['WETH', 'WBTC', 'USDT', 'USDC.e', 'WADA', 'gCOTI'].includes(currentPub?.symbol ?? '') ||\n !!currentPub?.addressKey;\n const isPodPortalToken = currentPub?.symbol === 'MTT';\n const aesKeyRequired = !isPodPortalToken && (currentDirection === 'to-public' || !isErc20Token);\n\n logger.log('🔑 [handleSwap] AES key gate check:', {\n tokenSymbol: currentPub?.symbol,\n isErc20Token,\n isPodPortalToken,\n aesKeyRequired,\n hasSnap,\n sessionAesKeyAvailable: !!sessionAesKey,\n });\n\n if (aesKeyRequired && !hasSnap) {\n // If session AES key is already available (manual entry or contract onboarding),\n // bypass any interactive flow entirely.\n if (sessionAesKey) {\n logger.log('🔑 [handleSwap] Session AES key available — bypassing key gate');\n setHasSnap(true);\n } else {\n // No session key available. The user must unlock via the appropriate modal.\n // Do NOT call getAESKeyFromSnap here — it only works for MetaMask wallets\n // and will fail with \"COTI Snap is not installed\" for Rabby/Phantom/Trust.\n logger.log('⚠️ [handleSwap] No AES key in session — requesting unlock');\n throw new Error('AES key not available. Please unlock your private tokens first.');\n }\n }\n\n logger.log('✅ [handleSwap] Gate passed, executing transaction...');\n\n if (overrideAmount !== undefined) setAmount(overrideAmount);\n if (overrideDirection !== undefined) setDirection(overrideDirection);\n if (overrideTokenIndex !== undefined) setSelectedTokenIndex(overrideTokenIndex);\n\n await executeTransaction(currentAmount, currentDirection, currentIndex, onProgress);\n },\n [\n amount,\n direction,\n selectedTokenIndex,\n error,\n hasSnap,\n isBridgingLoading,\n setAmount,\n setDirection,\n setSelectedTokenIndex,\n setHasSnap,\n executeTransaction,\n publicTokens,\n sessionAesKey,\n ],\n );\n\n return {\n executeTransaction,\n handleSwap,\n isBridgingLoading,\n allowance: allowance.allowance,\n isApproving: allowance.isApproving,\n handleApprove: allowance.handleApprove,\n checkAllowance: allowance.checkAllowance,\n isApprovalNeeded: allowance.isApprovalNeeded,\n estimatedGasFee: gas.estimatedGasFee,\n updateGasFee: gas.updateGasFee,\n isGasEstimating: gas.isGasEstimating,\n portalFeeCoti: gas.portalFeeCoti,\n portalFee: gas.portalFee,\n portalFeeSymbol: gas.portalFeeSymbol,\n podInboxFee: gas.podInboxFee,\n l1GasFee: gas.l1GasFee,\n isPodChain: gas.isPodChain,\n feeDebugInfo: gas.feeDebugInfo,\n };\n};\n","import { useEffect, useState } from 'react';\nimport { isMultipleWalletsError } from '../../utils/walletErrors';\nimport type { PrivacyBridgeModalsContextValue } from './types';\n\n/** Install and multi-wallet modal visibility (shared across connection flows). */\nexport const usePrivacyBridgeModalsState = (): PrivacyBridgeModalsContextValue => {\n const [showInstallModal, setShowInstallModal] = useState(false);\n const [showMultipleWalletsModal, setShowMultipleWalletsModal] = useState(false);\n\n useEffect(() => {\n const handler = (event: PromiseRejectionEvent) => {\n const message =\n event.reason?.message ?? (typeof event.reason === 'string' ? event.reason : '');\n if (isMultipleWalletsError(message)) {\n event.preventDefault();\n setShowMultipleWalletsModal(true);\n }\n };\n\n window.addEventListener('unhandledrejection', handler);\n return () => window.removeEventListener('unhandledrejection', handler);\n }, []);\n\n return {\n showInstallModal,\n setShowInstallModal,\n showMultipleWalletsModal,\n setShowMultipleWalletsModal,\n };\n};\n","/**\n * Substring present in the Chrome runtime error that occurs when multiple\n * browser wallet extensions conflict during message passing.\n */\nexport const MULTIPLE_WALLETS_ERROR_SUBSTRING =\n \"chrome.runtime.sendMessage() called from a webpage must specify an Extension ID\";\n\n/**\n * Determines if an error message indicates a multiple browser wallet\n * extensions conflict.\n */\nexport function isMultipleWalletsError(message: string | undefined | null): boolean {\n if (!message) return false;\n return message.includes(MULTIPLE_WALLETS_ERROR_SUBSTRING);\n}\n","import { useRef } from 'react';\nimport type { PrivacyBridgeModalsContextValue } from './types';\nimport type { UpdateAccountStateFn } from './sessionShared';\nimport { usePrivacyBridgeSessionCore } from './usePrivacyBridgeSessionCore';\nimport { usePrivacyBridgeNetworkSession } from './usePrivacyBridgeNetworkSession';\nimport { usePrivacyBridgeAccountSync } from './usePrivacyBridgeAccountSync';\nimport { usePrivacyBridgeWagmiSync } from './usePrivacyBridgeWagmiSync';\nimport { usePrivacyBridgeWalletConnection } from './usePrivacyBridgeWalletConnection';\nimport { usePrivacyBridgeUnlockSession } from './usePrivacyBridgeUnlockSession';\n\ninterface UsePrivacyBridgeSessionOptions {\n modals: PrivacyBridgeModalsContextValue;\n}\n\n/**\n * Composes wallet, network, balance sync, wagmi sync, connection, and unlock sub-hooks.\n * Return shape is unchanged for {@link PrivacyBridgeProvider} and existing API clients.\n */\nexport const usePrivacyBridgeSession = ({ modals }: UsePrivacyBridgeSessionOptions) => {\n const core = usePrivacyBridgeSessionCore({ modals });\n const updateAccountStateRef = useRef<UpdateAccountStateFn | null>(null);\n\n const network = usePrivacyBridgeNetworkSession({ core, updateAccountStateRef });\n const accountSync = usePrivacyBridgeAccountSync({ core, network, updateAccountStateRef });\n\n usePrivacyBridgeWagmiSync({ core, network, accountSync });\n\n const { handleConnect, handleDisconnect } = usePrivacyBridgeWalletConnection({\n core,\n network,\n accountSync,\n });\n\n const unlock = usePrivacyBridgeUnlockSession({ core, network, accountSync });\n\n return {\n isConnected: core.isConnected,\n walletAddress: core.walletAddress,\n hasSnap: core.hasSnap,\n setHasSnap: core.setHasSnap,\n snapError: core.snapError,\n publicTokens: core.publicTokens,\n privateTokens: core.privateTokens,\n setPublicTokens: core.setPublicTokens,\n setPrivateTokens: core.setPrivateTokens,\n metamaskDetected: core.metamaskDetected,\n setMetamaskDetected: core.setMetamaskDetected,\n connectToSnap: core.connectToSnap,\n requestSnapConnection: core.requestSnapConnection,\n checkSnapStatus: core.checkSnapStatus,\n getAESKeyFromSnap: core.getAESKeyFromSnap,\n hasAesKeyInSnap: core.hasAesKeyInSnap,\n handleOnboard: unlock.handleOnboard,\n handleVerifyKeys: unlock.handleVerifyKeys,\n aesKeyChainId: core.aesKeyChainId,\n setAesKeyChainId: core.setAesKeyChainId,\n handleConnect,\n handleDisconnect,\n refreshPublicBalances: unlock.refreshPublicBalances,\n refreshPrivateBalances: unlock.refreshPrivateBalances,\n onboardingError: core.onboardingError,\n onboardingWarning: core.onboardingWarning,\n lockPrivateBalances: unlock.lockPrivateBalances,\n saveManualAesKey: unlock.saveManualAesKey,\n sendPrivateToken: unlock.sendPrivateToken,\n encryptPrivateValue: unlock.encryptPrivateValue,\n decryptPrivateValue: unlock.decryptPrivateValue,\n sessionAesKey: core.sessionAesKey,\n isPrivateUnlocked: unlock.isPrivateUnlocked,\n showSnapMissingModal: core.showSnapMissingModal,\n setShowSnapMissingModal: core.setShowSnapMissingModal,\n showCotiWalletAesKeyModal: core.showCotiWalletAesKeyModal,\n setShowCotiWalletAesKeyModal: core.setShowCotiWalletAesKeyModal,\n chainId: network.chainId,\n currentChainId: network.currentChainId,\n switchNetwork: network.switchNetwork,\n networkName: network.networkName,\n isUnsupportedNetwork: network.isUnsupportedNetwork,\n isOffTargetNetwork: network.isOffTargetNetwork,\n isWrongNetwork: network.isWrongNetwork,\n networkMismatchWarning: network.networkMismatchWarning,\n enforceNetwork: network.enforceNetwork,\n COTI_MAINNET_ID: network.COTI_MAINNET_ID,\n COTI_TESTNET_ID: network.COTI_TESTNET_ID,\n SEPOLIA_ID: network.SEPOLIA_ID,\n wagmiChainId: network.wagmiChainId,\n wagmiSyncRef: core.wagmiSyncRef,\n };\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useSnap } from '../../hooks/useSnap';\nimport { usePrivateTokenBalance } from '../../hooks/usePrivateTokenBalance';\nimport { useWalletType } from '../../hooks/useWalletType';\nimport { useAesKeyProvider } from '../../hooks/useAesKeyProvider';\nimport { assertAesKeyChainId } from '../../config/plugin';\nimport {\n getInitialPublicTokens,\n getInitialPrivateTokens,\n type Token,\n} from '../../hooks/usePrivacyBridge';\nimport type { PrivacyBridgeModalsContextValue } from './types';\nimport { usePrivacyBridgeSessionKey } from './usePrivacyBridgeSessionKey';\nimport type { PrivacyBridgeSessionCore } from './sessionShared';\n\ninterface UsePrivacyBridgeSessionCoreOptions {\n modals: PrivacyBridgeModalsContextValue;\n}\n\n/** Shared wallet, token, snap, and session-key state for the bridge provider. */\nexport const usePrivacyBridgeSessionCore = ({\n modals,\n}: UsePrivacyBridgeSessionCoreOptions): PrivacyBridgeSessionCore => {\n const [isConnected, setIsConnected] = useState(false);\n const [walletAddress, setWalletAddress] = useState('');\n const [hasSnap, setHasSnap] = useState(false);\n const [snapError, setSnapError] = useState<string | null>(null);\n const [publicTokens, setPublicTokens] = useState<Token[]>(getInitialPublicTokens());\n const [privateTokens, setPrivateTokens] = useState<Token[]>(getInitialPrivateTokens());\n const [showSnapMissingModal, setShowSnapMissingModal] = useState(false);\n const [showCotiWalletAesKeyModal, setShowCotiWalletAesKeyModal] = useState(false);\n const [metamaskDetected, setMetamaskDetected] = useState(false);\n const [aesKeyChainId, setAesKeyChainIdState] = useState<number | undefined>(undefined);\n const ethereumListenerRegistered = useRef(false);\n const wagmiSyncRef = useRef(false);\n const disconnectingRef = useRef(false);\n const metamaskExplicitConnect = useRef(false);\n const snapCheckInFlightRef = useRef<Promise<boolean> | null>(null);\n\n const {\n sessionAesKey,\n setSessionAesKey,\n arePrivateBalancesHidden,\n setArePrivateBalancesHidden,\n } = usePrivacyBridgeSessionKey(walletAddress);\n\n const {\n isSnapInstalled,\n executeSnapCheck,\n getAESKeyFromSnap,\n hasAesKeyInSnap,\n connectToSnap,\n requestSnapConnection,\n decryptCtUint64ViaSnap,\n decryptCtUint256ViaSnap,\n encryptUint256ViaSnap,\n buildItUint256ViaSnap,\n handleManualOnboarding,\n handleKeyVerification,\n clearSnapCache,\n } = useSnap(setSnapError);\n\n const checkSnapStatus = useCallback(async (): Promise<boolean> => {\n if (snapCheckInFlightRef.current) {\n return snapCheckInFlightRef.current;\n }\n\n const promise = isSnapInstalled().then(installed => {\n setHasSnap(installed);\n return installed;\n });\n\n snapCheckInFlightRef.current = promise;\n\n try {\n return await promise;\n } finally {\n if (snapCheckInFlightRef.current === promise) {\n snapCheckInFlightRef.current = null;\n }\n }\n }, [isSnapInstalled, setHasSnap]);\n\n const walletTypeInfo = useWalletType();\n const {\n getAesKey: getAesKeyFromProvider,\n isOnboarding,\n onboardingError,\n onboardingWarning,\n } = useAesKeyProvider(walletTypeInfo);\n const { fetchPrivateBalance } = usePrivateTokenBalance();\n\n useEffect(() => {\n if (snapError && !isOnboarding) setShowSnapMissingModal(true);\n }, [snapError, isOnboarding]);\n\n const setAesKeyChainId = useCallback((chainId: number | undefined) => {\n assertAesKeyChainId(chainId);\n setAesKeyChainIdState(chainId);\n }, []);\n\n return {\n modals,\n isConnected,\n setIsConnected,\n walletAddress,\n setWalletAddress,\n hasSnap,\n setHasSnap,\n snapError,\n setSnapError,\n publicTokens,\n setPublicTokens,\n privateTokens,\n setPrivateTokens,\n showSnapMissingModal,\n setShowSnapMissingModal,\n showCotiWalletAesKeyModal,\n setShowCotiWalletAesKeyModal,\n metamaskDetected,\n setMetamaskDetected,\n ethereumListenerRegistered,\n wagmiSyncRef,\n disconnectingRef,\n metamaskExplicitConnect,\n sessionAesKey,\n setSessionAesKey,\n aesKeyChainId,\n setAesKeyChainId,\n arePrivateBalancesHidden,\n setArePrivateBalancesHidden,\n executeSnapCheck,\n checkSnapStatus,\n getAESKeyFromSnap,\n hasAesKeyInSnap,\n connectToSnap,\n requestSnapConnection,\n decryptCtUint64ViaSnap,\n decryptCtUint256ViaSnap,\n encryptUint256ViaSnap,\n buildItUint256ViaSnap,\n handleManualOnboarding,\n handleKeyVerification,\n clearSnapCache,\n fetchPrivateBalance,\n getAesKeyFromProvider,\n onboardingError,\n onboardingWarning,\n };\n};\n","import { useState, useCallback, useRef } from 'react';\nimport { useAccount } from 'wagmi';\nimport { BrowserProvider, JsonRpcSigner } from '@coti-io/coti-ethers';\nimport { getBigInt, type BigNumberish } from 'ethers';\nimport { useSnap } from './useSnap';\nimport type { WalletTypeInfo } from './useWalletType';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from '../lib/logger';\nimport { COTI_MAINNET_CHAIN_ID, COTI_TESTNET_CHAIN_ID, getRpcUrlForChainId } from '../config/chains';\nimport { getPluginConfig, type EncryptedAesBackup } from '../config/plugin';\nimport { decryptAesKeyBackup } from '../crypto/aesKeyBackupVault';\nimport { normalizeAesKey } from '../crypto/aesKey';\nimport { muteChainUpdates, unmuteChainUpdates, isChainUpdatesMuted } from '../lib/chainMute';\nimport { canPersistAesKeyToSnap } from '../lib/snapOrigins';\nimport { resolveAesKeyChainId } from '../lib/aesAccessStrategy';\nimport { isOnboardingServicesEnabled } from '../lib/onboardingServices';\nimport { persistEncryptedAesBackup } from '../lib/persistEncryptedAesBackup';\nimport { isInsufficientFundsError, isUserRejection } from '../lib/walletErrors';\nimport {\n clearMetaMaskMobileRpcCache,\n formatOnboardingError,\n guardedEthChainId,\n guardedMobileReadOnlyRpc,\n guardedMobileWalletRpc,\n isMetaMaskMobileBrowser,\n mobileHttpJsonRpc,\n MOBILE_READ_ONLY_RPC_METHODS,\n OnboardingDebugTrace,\n resolveMetaMaskMobileWalletProvider,\n} from '../lib/metaMaskMobile';\n\n/**\n * Onboarding step identifiers matching the contract onboarding flow (steps 3-9).\n */\nexport type OnboardingStep =\n | 'idle'\n | 'switching-network'\n | 'creating-provider'\n | 'preparing-onboard'\n | 'signing-transaction'\n | 'retrieving-key'\n | 'validating-key'\n | 'restoring-network'\n | 'persisting-key'\n | 'restoring-backup'\n | 'signing-backup'\n | 'granting-funds'\n | 'waiting-for-funds'\n | 'saving-backup'\n | 'complete'\n | 'error';\n\n/**\n * Metadata for each onboarding step (for progress display).\n */\nexport interface OnboardingStepInfo {\n id: OnboardingStep;\n label: string;\n description: string;\n}\n\n/**\n * Ordered list of steps shown in the progress UI (steps 3–9 from the onboarding flow doc).\n */\nexport const ONBOARDING_STEPS: OnboardingStepInfo[] = [\n { id: 'preparing-onboard', label: 'Preparing', description: 'Checking wallet and preparing onboarding' },\n { id: 'signing-transaction', label: 'Sign Transaction', description: 'Please sign the transaction in your wallet' },\n { id: 'retrieving-key', label: 'Execute Transaction', description: 'Please execute the next transaction in your wallet to generate or retrieve your AES Key' },\n { id: 'persisting-key', label: 'Persisting Key', description: 'Persisting your AES encryption key' },\n];\n\nexport interface OnboardingProgressDetails {\n /** True when the step transition was caused by explicit user cancellation. */\n cancelled?: boolean;\n /** Human-facing failure message for error transitions. */\n error?: string;\n}\n\n/**\n * Callback type for receiving onboarding step progress updates.\n */\nexport type OnboardingProgressCallback = (\n step: OnboardingStep,\n details?: OnboardingProgressDetails,\n) => void;\n\nexport interface AesKeyProviderOptions {\n /**\n * Skip Snap retrieval and use the AccountOnboard contract path.\n * Required when Snap holds a key for the wrong MetaMask profile.\n */\n forceContractOnboarding?: boolean;\n /** Whether contract-onboarding should save a client-encrypted AES backup. */\n saveBackup?: boolean;\n /** Only restore via Snap-side decrypt / backup; never export raw key or run contract onboarding. */\n restoreOnly?: boolean;\n /** Unlock via Snap typed decrypt RPC (no raw AES export). Used when AES is already stored in Snap. */\n snapSideDecrypt?: boolean;\n /** COTI Testnet/Mainnet chain that owns the AES key for this flow. */\n aesKeyChainId?: number;\n /** Decrypt encrypted backup blob, persist AES to Snap, return null (no raw key to dapp). */\n hydrateSnapFromBackup?: boolean;\n /** Receives contract-onboarding step updates for modal progress UI. */\n onProgress?: OnboardingProgressCallback;\n /** Called when backup restore is cancelled by the user. */\n onRestoreCancelled?: () => void;\n /** Encrypted backup blob from an earlier access probe — avoids a second fetch before sign. */\n prefetchedEncryptedBackup?: EncryptedAesBackup | null;\n}\n\n/** @deprecated Use {@link AesKeyProviderOptions} instead. */\nexport type GetAesKeyOptions = Pick<AesKeyProviderOptions, 'forceContractOnboarding'>;\n\n/**\n * Result interface for the useAesKeyProvider hook.\n */\nexport interface AesKeyProviderResult {\n /** Retrieves AES key — routes to Snap or onboard contract based on wallet type */\n getAesKey: (\n address: string,\n onProgress?: OnboardingProgressCallback,\n options?: AesKeyProviderOptions,\n ) => Promise<string | null>;\n /** True during the async generateOrRecoverAes() call */\n isOnboarding: boolean;\n /** Error message from failed onboarding attempts; cleared on next call */\n onboardingError: string | null;\n /** Non-blocking warning from restore/backup flows; cleared on next call */\n onboardingWarning: string | null;\n /** True when the user cancelled the latest backup restore signature. */\n wasRestoreCancelled: boolean;\n /** Current onboarding step (for progress UI) */\n currentStep: OnboardingStep;\n}\n\n/** Validates that a string is a valid 32-character hex AES key. */\nexport function isValidAesKey(key: string): boolean {\n try {\n normalizeAesKey(key);\n return true;\n } catch {\n return false;\n }\n}\n\nconst SIGN_RPC_METHODS = new Set([\n 'personal_sign',\n 'eth_sign',\n 'eth_signTypedData',\n 'eth_signTypedData_v3',\n 'eth_signTypedData_v4',\n]);\n\ntype Eip1193RequestPayload = { method: string; params?: unknown[] };\ntype Eip1193ProviderLike = { request: (args: Eip1193RequestPayload) => Promise<unknown> };\n\n/**\n * Wraps the wallet provider's `request` to log RPC calls and advance the UI\n * between the message-signature and on-chain onboarding transaction steps.\n */\nfunction instrumentWalletProvider(\n walletProvider: Eip1193ProviderLike,\n emitStep: (step: OnboardingStep) => void,\n trace: OnboardingDebugTrace,\n readOnlyRpcChainId?: number,\n walletRejectionRef?: { current: boolean },\n): () => void {\n const hadOwnRequest = Object.prototype.hasOwnProperty.call(walletProvider, 'request');\n const originalRequest = walletProvider.request.bind(walletProvider);\n let executeStepEmitted = false;\n let signingStepEmitted = false;\n const readOnlyRpcUrl = readOnlyRpcChainId != null\n ? getRpcUrlForChainId(readOnlyRpcChainId)\n : undefined;\n\n walletProvider.request = async function instrumentedRequest(args: Eip1193RequestPayload) {\n const method = args?.method ?? 'unknown';\n trace.push('rpc', method);\n\n if (args?.method === 'eth_sendTransaction' && !executeStepEmitted) {\n executeStepEmitted = true;\n emitStep('retrieving-key');\n } else if (SIGN_RPC_METHODS.has(method)) {\n if (!signingStepEmitted) {\n signingStepEmitted = true;\n emitStep('signing-transaction');\n }\n trace.push('wallet-prompt', `Approve signature in wallet (${method})`);\n }\n\n try {\n if (isMetaMaskMobileBrowser()) {\n if (MOBILE_READ_ONLY_RPC_METHODS.has(method)) {\n const readOnlyProvider = readOnlyRpcUrl\n ? {\n request: ({ method: rpcMethod, params }: Eip1193RequestPayload) =>\n mobileHttpJsonRpc(readOnlyRpcUrl, rpcMethod, params ?? []),\n }\n : { request: originalRequest };\n if (readOnlyRpcUrl) {\n trace.push('rpc-via', `http(${method})`);\n }\n const result = await guardedMobileReadOnlyRpc(\n readOnlyProvider,\n method,\n args.params ?? [],\n );\n trace.push('rpc-ok', method);\n return result;\n }\n if (method === 'wallet_switchEthereumChain' || method === 'wallet_addEthereumChain') {\n clearMetaMaskMobileRpcCache();\n }\n if (SIGN_RPC_METHODS.has(method) || method === 'eth_sendTransaction') {\n trace.push('wallet-send', method);\n }\n const result = await guardedMobileWalletRpc(\n { request: originalRequest },\n method,\n args.params ?? [],\n );\n trace.push('rpc-ok', method);\n return result;\n }\n\n const result = await originalRequest(args);\n trace.push('rpc-ok', method);\n return result;\n } catch (error: unknown) {\n const errMsg = error instanceof Error ? error.message : String(error);\n trace.push('rpc-err', `${method}: ${errMsg}`);\n if (\n walletRejectionRef\n && isUserRejection(error)\n && (SIGN_RPC_METHODS.has(method) || method === 'eth_sendTransaction')\n ) {\n walletRejectionRef.current = true;\n }\n throw error;\n }\n };\n\n return () => {\n if (hadOwnRequest) {\n walletProvider.request = originalRequest;\n } else {\n try {\n delete (walletProvider as { request?: unknown }).request;\n } catch {\n walletProvider.request = originalRequest;\n }\n }\n };\n}\n\nfunction toBigInt(value: BigNumberish | undefined, fallback: bigint): bigint {\n if (value === undefined) return fallback;\n return getBigInt(value);\n}\n\nconst sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\n\n/**\n * Single abstraction for AES key retrieval. Routes to Snap or onboarding contract\n * based on wallet type.\n *\n * - When `isMetaMaskWithSnap === true`: delegates to existing `getAESKeyFromSnap(address)`\n * - When `isMetaMaskWithSnap === false`: uses wagmi connector's EIP-1193 provider to create\n * a `@coti-io/coti-ethers` BrowserProvider, gets a signer, and calls\n * `signer.generateOrRecoverAes()` to retrieve the AES key from the onboarding contract.\n *\n * @param walletTypeInfo - The wallet type information from useWalletType()\n * @returns AesKeyProviderResult with getAesKey function and state indicators\n */\nexport function useAesKeyProvider(walletTypeInfo: WalletTypeInfo): AesKeyProviderResult {\n const [isOnboarding, setIsOnboarding] = useState(false);\n const [onboardingError, setOnboardingError] = useState<string | null>(null);\n const [onboardingWarning, setOnboardingWarning] = useState<string | null>(null);\n const [wasRestoreCancelled, setWasRestoreCancelled] = useState(false);\n const [currentStep, setCurrentStep] = useState<OnboardingStep>('idle');\n const progressCallbackRef = useRef<OnboardingProgressCallback | undefined>();\n const debugTraceRef = useRef(new OnboardingDebugTrace());\n const onboardingInFlightRef = useRef<Promise<string | null> | null>(null);\n\n const { getAESKeyFromSnap, saveAESKeyToSnap, clearSnapCache } = useSnap();\n const { connector, chainId: connectedChainId } = useAccount();\n\n const emitStep = useCallback((step: OnboardingStep, details?: OnboardingProgressDetails) => {\n setCurrentStep(step);\n progressCallbackRef.current?.(step, details);\n }, []);\n\n const reportOnboardingFailure = useCallback((message: string) => {\n setOnboardingError(message);\n emitStep('error', { error: message });\n }, [emitStep]);\n\n const getAesKey = useCallback(\n async (\n address: string,\n onProgress?: OnboardingProgressCallback,\n options: AesKeyProviderOptions = {},\n ): Promise<string | null> => {\n // Store progress callback for use within the flow\n progressCallbackRef.current = onProgress ?? options.onProgress;\n // Clear previous error and debug trace on each new retrieval attempt\n setOnboardingError(null);\n debugTraceRef.current.clear();\n setOnboardingWarning(null);\n setWasRestoreCancelled(false);\n const forceContractOnboarding = options?.forceContractOnboarding === true;\n if (!forceContractOnboarding) {\n emitStep('idle');\n }\n let restoreBackupFailed = false;\n\n const trace = debugTraceRef.current;\n trace.push('start', `wallet=${walletTypeInfo.walletType} mobile=${isMetaMaskMobileBrowser()}`);\n\n if (onboardingInFlightRef.current) {\n trace.push('route', 'onboarding already in flight - joining');\n return onboardingInFlightRef.current;\n }\n\n const skipSnapOnMetaMaskMobile =\n walletTypeInfo.walletType === 'metamask' && isMetaMaskMobileBrowser();\n\n if (forceContractOnboarding) {\n logger.log('ℹ️ Forcing AccountOnboard contract path (skipping Snap read)');\n clearSnapCache();\n }\n\n if (skipSnapOnMetaMaskMobile) {\n trace.push('route', 'MetaMask Mobile — skipping Snap, using contract onboarding');\n logger.log('ℹ️ MetaMask Mobile detected — skipping Snap path (uses eth_accounts)');\n }\n\n // Route 1: MetaMask — try Snap path first unless contract onboarding was forced,\n // we're on MetaMask Mobile, or this is restore-only unlock.\n if (\n walletTypeInfo.walletType === 'metamask'\n && !forceContractOnboarding\n && !skipSnapOnMetaMaskMobile\n && !options.restoreOnly\n ) {\n try {\n const key = await getAESKeyFromSnap(address, { skipCache: true });\n if (key && !isValidAesKey(key)) {\n logger.warn('⚠️ AES key from Snap failed format validation');\n return null;\n }\n if (key) return key;\n // Snap returned null (user cancelled) — don't fall through to contract\n return null;\n } catch (error: unknown) {\n if (isUserRejection(error)) {\n return null;\n }\n // Snap missing, empty, or mismatched — fall through to contract onboarding\n if (\n error instanceof CotiPluginError &&\n (error.code === CotiErrorCode.SNAP_CONNECT_FAILED ||\n error.code === CotiErrorCode.AES_KEY_MISSING ||\n error.code === CotiErrorCode.AES_KEY_MISMATCH)\n ) {\n logger.log('ℹ️ Snap unavailable, empty, or mismatched — falling back to onboard contract');\n clearSnapCache();\n // Fall through to Route 2\n } else if (\n error instanceof Error &&\n (error.message.includes('No account connected') ||\n error.message.includes('Extension context invalidated'))\n ) {\n logger.log('ℹ️ Snap wallet not ready, falling back to onboard contract');\n clearSnapCache();\n // Fall through to Route 2\n } else {\n throw error;\n }\n }\n }\n\n // Route 2: Non-MetaMask wallet (or MetaMask without snap / empty snap) — contract onboarding\n if (!connector) {\n reportOnboardingFailure('No wallet provider available. Please connect your wallet.');\n return null;\n }\n\n const walletRejectionRef = { current: false };\n const onboardingPromise = (async (): Promise<string | null> => {\n try {\n setIsOnboarding(true);\n\n // Get the EIP-1193 provider from the wagmi connector\n const connectorProvider = await connector.getProvider() as Eip1193ProviderLike | null;\n const walletProvider = resolveMetaMaskMobileWalletProvider(\n connectorProvider as Parameters<typeof resolveMetaMaskMobileWalletProvider>[0],\n ) as Eip1193ProviderLike;\n if (isMetaMaskMobileBrowser()) {\n trace.push(\n 'provider',\n walletProvider === connectorProvider ? 'wagmi-connector' : 'native-injected',\n );\n }\n if (!walletProvider?.request) {\n reportOnboardingFailure('Could not get provider from wallet connector.');\n return null;\n }\n\n const config = getPluginConfig();\n const services = config.onboardingServices;\n const servicesEnabled = isOnboardingServicesEnabled();\n const isConnectedCotiChain = connectedChainId === COTI_MAINNET_CHAIN_ID || connectedChainId === COTI_TESTNET_CHAIN_ID;\n const targetCotiChainId = resolveAesKeyChainId(connectedChainId, options.aesKeyChainId);\n const backupContext = { address, chainId: targetCotiChainId };\n\n if (servicesEnabled && services?.fetchEncryptedAesBackup) {\n try {\n emitStep('restoring-backup');\n const backup = options.prefetchedEncryptedBackup === undefined\n ? await services.fetchEncryptedAesBackup(backupContext)\n : options.prefetchedEncryptedBackup;\n if (backup) {\n const provider = new BrowserProvider(walletProvider);\n const signer = isMetaMaskMobileBrowser()\n ? new JsonRpcSigner(provider, address)\n : await provider.getSigner(address);\n emitStep('signing-backup');\n const restoredKey = await decryptAesKeyBackup(backup, signer, backupContext);\n logger.log('✅ AES key restored from encrypted backup');\n\n if (\n options.hydrateSnapFromBackup\n && walletTypeInfo.walletType === 'metamask'\n && canPersistAesKeyToSnap()\n ) {\n emitStep('persisting-key');\n const saved = await saveAESKeyToSnap(restoredKey, address);\n if (!saved) {\n logger.warn('⚠️ Restored AES key but could not persist it to Snap');\n }\n\n if (saved) {\n emitStep('complete');\n } else {\n emitStep('idle');\n }\n // Dedicated hydrate path keeps the raw AES key out of dapp session state.\n return null;\n }\n\n if (\n options.hydrateSnapFromBackup\n && walletTypeInfo.walletType === 'metamask'\n ) {\n logger.log(\n 'ℹ️ Skipping Snap AES persist — origin not authorized for set-aes-key:',\n typeof window !== 'undefined' ? window.location.origin : 'unknown',\n );\n return null;\n }\n\n emitStep('complete');\n return restoredKey;\n }\n } catch (restoreError) {\n if (isUserRejection(restoreError)) {\n setOnboardingWarning('Backup restore was cancelled. Approve the wallet signature to unlock from your encrypted backup.');\n setWasRestoreCancelled(true);\n options.onRestoreCancelled?.();\n emitStep('idle');\n return null;\n }\n const message = restoreError instanceof Error\n ? restoreError.message\n : 'Encrypted AES backup could not be restored.';\n logger.warn('⚠️ AES backup restore failed, falling back to contract onboarding:', restoreError);\n restoreBackupFailed = true;\n setOnboardingWarning(`Encrypted backup could not be restored. Continuing with onboarding. ${message}`);\n }\n }\n\n if (options.restoreOnly) {\n emitStep('idle');\n return null;\n }\n\n // Step: Switch network to COTI Testnet\n emitStep('switching-network');\n trace.push('step', 'switching-network');\n\n // Determine if we need to switch to a COTI chain for onboarding\n const targetCotiChainHex = '0x' + targetCotiChainId.toString(16);\n const originalChainHex = connectedChainId ? '0x' + connectedChainId.toString(16) : null;\n\n // If not on COTI, mute UI chain reactions and switch provider-level\n if (!isConnectedCotiChain) {\n logger.log('🔇 [AesKeyProvider] Muting chain updates, switching to COTI Testnet for onboarding...');\n muteChainUpdates();\n try {\n await walletProvider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: targetCotiChainHex }],\n });\n } catch (switchErr: any) {\n if (switchErr?.code === 4902) {\n try {\n await walletProvider.request({\n method: 'wallet_addEthereumChain',\n params: [{\n chainId: targetCotiChainHex,\n chainName: 'COTI Testnet',\n nativeCurrency: { name: 'COTI', symbol: 'COTI', decimals: 18 },\n rpcUrls: ['https://testnet.coti.io/rpc'],\n blockExplorerUrls: ['https://testnet.cotiscan.io'],\n }],\n });\n } catch {\n unmuteChainUpdates();\n reportOnboardingFailure('Failed to add COTI Testnet to wallet.');\n return null;\n }\n } else {\n unmuteChainUpdates();\n if (switchErr?.code === 4001) {\n emitStep('idle', { cancelled: true });\n return null;\n }\n reportOnboardingFailure('Failed to switch to COTI Testnet for onboarding.');\n return null;\n }\n }\n }\n\n // Step: Create provider and signer\n emitStep('creating-provider');\n trace.push('step', 'creating-provider');\n\n const restoreRequest = instrumentWalletProvider(\n walletProvider,\n emitStep,\n trace,\n targetCotiChainId,\n walletRejectionRef,\n );\n\n // Create a @coti-io/coti-ethers BrowserProvider (now on COTI Testnet).\n // Use JsonRpcSigner directly with the wagmi-connected address — NEVER call\n // BrowserProvider.getSigner(), which always invokes eth_accounts (via hasSigner)\n // and triggers MetaMask Mobile's coalescer stack overflow.\n const provider = new BrowserProvider(walletProvider);\n trace.push('signer', `JsonRpcSigner(${address.slice(0, 10)}…)`);\n let signer;\n try {\n signer = new JsonRpcSigner(provider, address);\n } catch (signerError) {\n restoreRequest();\n throw signerError;\n }\n\n if (isMetaMaskMobileBrowser()) {\n clearMetaMaskMobileRpcCache();\n const rpcUrl = getRpcUrlForChainId(targetCotiChainId);\n await guardedEthChainId({\n request: ({ method, params }) =>\n mobileHttpJsonRpc(rpcUrl, method, params ?? []),\n });\n }\n\n const configuredMinBalanceWei = toBigInt(config.onboardingGrantMinBalanceWei, 0n);\n if (servicesEnabled && services?.grantNativeCoti) {\n let nativeBalance = await provider.getBalance(address);\n const requiredBalanceWei = configuredMinBalanceWei > 0n ? configuredMinBalanceWei : 1n;\n logger.log('[AesKeyProvider] Native COTI balance before onboarding', {\n address,\n chainId: targetCotiChainId,\n nativeBalanceWei: nativeBalance.toString(),\n requiredBalanceWei: requiredBalanceWei.toString(),\n });\n if (nativeBalance < requiredBalanceWei) {\n emitStep('granting-funds');\n try {\n const grantResult = await services.grantNativeCoti({ address, chainId: targetCotiChainId });\n logger.log('[AesKeyProvider] Native COTI grant requested', grantResult);\n\n if (grantResult?.status !== 'skipped') {\n emitStep('waiting-for-funds');\n const pollIntervalMs = config.onboardingGrantPollIntervalMs ?? 2000;\n const timeoutMs = config.onboardingGrantTimeoutMs ?? 60000;\n const startedAt = Date.now();\n\n while (nativeBalance < requiredBalanceWei && Date.now() - startedAt < timeoutMs) {\n await sleep(pollIntervalMs);\n nativeBalance = await provider.getBalance(address);\n logger.log('[AesKeyProvider] Native COTI balance while waiting for grant', {\n address,\n chainId: targetCotiChainId,\n nativeBalanceWei: nativeBalance.toString(),\n requiredBalanceWei: requiredBalanceWei.toString(),\n });\n }\n }\n } catch (grantError) {\n logger.warn('[AesKeyProvider] Native COTI grant unavailable; continuing without grant:', grantError);\n }\n\n if (nativeBalance < requiredBalanceWei) {\n logger.warn('[AesKeyProvider] Native COTI balance remains below onboarding threshold; continuing without grant');\n }\n }\n }\n\n // Step: Execute onboarding - wallet prompts fire from the instrumented RPC hook.\n emitStep('preparing-onboard');\n trace.push('step', 'preparing-onboard');\n\n // Execute onboarding on COTI Testnet. The instrumented request hook above\n // advances the UI to \"Sign Transaction\" on personal_sign and\n // \"Execute Transaction\" when the on-chain tx is sent.\n try {\n trace.push('sdk', 'generateOrRecoverAes()');\n await signer.generateOrRecoverAes();\n trace.push('sdk-ok', 'generateOrRecoverAes() complete');\n } finally {\n restoreRequest();\n }\n\n // Ensure the UI advances past signing even on recover-only paths that\n // never issue an eth_sendTransaction (idempotent if already emitted).\n emitStep('retrieving-key');\n\n const onboardInfo = signer.getUserOnboardInfo();\n const aesKey = onboardInfo?.aesKey ?? null;\n\n if (aesKey && !isValidAesKey(aesKey)) {\n logger.warn('⚠️ AES key from onboard contract failed format validation');\n if (!isConnectedCotiChain && originalChainHex) {\n try {\n await walletProvider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: originalChainHex }],\n });\n } catch {\n logger.warn('⚠️ [AesKeyProvider] Could not switch back to original chain after invalid AES key');\n }\n }\n reportOnboardingFailure('Retrieved AES key has invalid format');\n return null;\n }\n\n logger.log('✅ AES key retrieved successfully:', aesKey?.length, 'characters');\n\n // Step: Switch wallet back to original chain\n emitStep('restoring-network');\n\n if (!isConnectedCotiChain && originalChainHex) {\n logger.log('🔇 [AesKeyProvider] Switching back to:', originalChainHex);\n try {\n await walletProvider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: originalChainHex }],\n });\n } catch {\n logger.warn('⚠️ [AesKeyProvider] Could not switch back to original chain');\n }\n }\n\n // Step: Persist key (MetaMask Snap / encrypted backup) or finalize\n let savedToSnap = false;\n const canSaveToConnectedSnap =\n aesKey\n && walletTypeInfo.walletType === 'metamask'\n && walletTypeInfo.isMetaMaskWithSnap\n && canPersistAesKeyToSnap();\n const canSaveEncryptedBackup =\n aesKey &&\n isValidAesKey(aesKey) &&\n options.saveBackup &&\n servicesEnabled &&\n (services?.saveEncryptedAesBackup || services?.replaceEncryptedAesBackup);\n\n if (canSaveToConnectedSnap) {\n emitStep('persisting-key');\n trace.push('step', 'persisting-key');\n savedToSnap = await saveAESKeyToSnap(aesKey, address);\n if (!savedToSnap) {\n logger.warn('⚠️ AES key retrieved but could not persist to Snap');\n setOnboardingWarning(\n 'Onboarding succeeded, but the AES key could not be saved to MetaMask Snap. You can retry by unlocking again.',\n );\n }\n } else if (\n aesKey\n && walletTypeInfo.walletType === 'metamask'\n && canPersistAesKeyToSnap()\n && !walletTypeInfo.isMetaMaskWithSnap\n ) {\n logger.log(\n 'ℹ️ Skipping Snap AES persist — Snap is not connected to this origin',\n );\n }\n\n const skipEncryptedBackupForSnap =\n canSaveToConnectedSnap && savedToSnap;\n\n if (\n canSaveEncryptedBackup &&\n !skipEncryptedBackupForSnap &&\n aesKey\n ) {\n const backupResult = await persistEncryptedAesBackup({\n aesKey,\n address,\n chainId: targetCotiChainId,\n connector,\n preferReplace: restoreBackupFailed,\n onBeforeSign: () => emitStep('signing-backup'),\n });\n\n if (backupResult.status === 'failed') {\n logger.warn(\n '⚠️ AES key retrieved but encrypted backup save failed:',\n backupResult.message,\n );\n setOnboardingWarning(\n `Onboarding succeeded, but encrypted backup was not saved. ${backupResult.message}`,\n );\n } else if (backupResult.status === 'cancelled') {\n logger.warn('⚠️ AES key retrieved but encrypted backup save was cancelled');\n setOnboardingWarning(\n 'Onboarding succeeded, but encrypted backup save was cancelled. You can save it later by re-entering your AES key.',\n );\n }\n }\n\n // Step: Complete\n if (aesKey && isValidAesKey(aesKey)) {\n emitStep('complete');\n trace.push('step', 'complete');\n }\n\n return aesKey;\n } catch (error: unknown) {\n // On error, attempt to switch wallet back to the original chain\n if (connectedChainId !== COTI_MAINNET_CHAIN_ID && connectedChainId !== COTI_TESTNET_CHAIN_ID && connectedChainId) {\n try {\n const connectorProvider = await connector.getProvider() as Eip1193ProviderLike | null;\n const wp = resolveMetaMaskMobileWalletProvider(\n connectorProvider as Parameters<typeof resolveMetaMaskMobileWalletProvider>[0],\n ) as Eip1193ProviderLike;\n await wp?.request?.({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: '0x' + connectedChainId.toString(16) }],\n });\n } catch {\n logger.warn('⚠️ [AesKeyProvider] Could not restore original chain after error');\n }\n }\n\n // EIP-1193 error code 4001: user rejected the signature request.\n // coti-ethers onboard() also rethrows a generic \"unable to onboard user.\" message\n // after personal_sign rejection — walletRejectionRef preserves that signal.\n const signRejectedDuringOnboarding = walletRejectionRef.current;\n if (isUserRejection(error) || signRejectedDuringOnboarding) {\n emitStep('idle', { cancelled: true });\n return null;\n }\n\n if (isInsufficientFundsError(error)) {\n const errorMessage = 'Insufficient native COTI for onboarding gas. Add COTI and retry.';\n logger.warn('[AesKeyProvider] Insufficient native COTI for onboarding; wallet surfaced the error');\n reportOnboardingFailure(errorMessage);\n return null;\n }\n\n // Set error state for UI display\n const errorMessage = formatOnboardingError(error);\n reportOnboardingFailure(errorMessage);\n trace.push('error', errorMessage);\n logger.error('❌ Onboarding contract AES key retrieval failed:', error);\n return null;\n } finally {\n // Reduced delay: Components 1 & 2 now guard against stale chain-change events\n // resetting private balances. 500ms is sufficient to absorb the immediate\n // chainChanged event from the switch-back.\n if (isChainUpdatesMuted()) {\n await new Promise(resolve => setTimeout(resolve, 500));\n unmuteChainUpdates();\n logger.log('🔊 [AesKeyProvider] Chain updates unmuted');\n }\n setIsOnboarding(false);\n progressCallbackRef.current = undefined;\n }\n })();\n\n onboardingInFlightRef.current = onboardingPromise;\n try {\n return await onboardingPromise;\n } finally {\n if (onboardingInFlightRef.current === onboardingPromise) {\n onboardingInFlightRef.current = null;\n }\n }\n },\n [walletTypeInfo.walletType, getAESKeyFromSnap, saveAESKeyToSnap, clearSnapCache, connector, connectedChainId, emitStep, reportOnboardingFailure]\n );\n\n return {\n getAesKey,\n isOnboarding,\n onboardingError,\n onboardingWarning,\n wasRestoreCancelled,\n currentStep,\n };\n}\n","import { ethers, type TypedDataDomain, type TypedDataField } from 'ethers';\nimport type { EncryptedAesBackup } from '../config/plugin';\nimport { validateAesKey } from './aesKey';\n\nexport interface AesBackupSigner {\n signTypedData: (\n domain: TypedDataDomain,\n types: Record<string, TypedDataField[]>,\n value: Record<string, unknown>,\n ) => Promise<string>;\n}\n\nexport interface AesBackupVaultContext {\n address: string;\n chainId: number;\n}\n\nconst BACKUP_DOMAIN_NAME = 'COTI AES Backup';\nconst BACKUP_DOMAIN_VERSION = '1';\n\nconst BACKUP_TYPES = {\n AesBackup: [\n { name: 'purpose', type: 'string' },\n { name: 'address', type: 'address' },\n { name: 'chainId', type: 'uint256' },\n { name: 'version', type: 'uint256' },\n ],\n} satisfies Record<string, TypedDataField[]>;\n\nconst bytesToBase64 = (bytes: Uint8Array) => btoa(String.fromCharCode(...bytes));\n\nconst base64ToBytes = (value: string) =>\n Uint8Array.from(atob(value), char => char.charCodeAt(0));\n\nconst getDomain = (): TypedDataDomain => ({\n name: BACKUP_DOMAIN_NAME,\n version: BACKUP_DOMAIN_VERSION,\n});\n\nconst getMessage = ({ address, chainId }: AesBackupVaultContext) => ({\n purpose: 'Encrypt and decrypt your COTI AES key backup',\n address,\n chainId,\n version: 1,\n});\n\nconst deriveCryptoKey = async (signature: string): Promise<CryptoKey> => {\n const signatureHash = ethers.keccak256(ethers.toUtf8Bytes(signature));\n const keyBytes = ethers.getBytes(signatureHash);\n const rawKey = keyBytes.buffer.slice(\n keyBytes.byteOffset,\n keyBytes.byteOffset + keyBytes.byteLength,\n ) as ArrayBuffer;\n\n return crypto.subtle.importKey(\n 'raw',\n rawKey,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt'],\n );\n};\n\nconst signBackupContext = (signer: AesBackupSigner, context: AesBackupVaultContext) =>\n signer.signTypedData(getDomain(), BACKUP_TYPES, getMessage(context));\n\nexport const encryptAesKeyBackup = async (\n aesKey: string,\n signer: AesBackupSigner,\n context: AesBackupVaultContext,\n): Promise<EncryptedAesBackup> => {\n const normalizedKey = validateAesKey(aesKey);\n const signature = await signBackupContext(signer, context);\n const wrappingKey = await deriveCryptoKey(signature);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = new Uint8Array(\n await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n wrappingKey,\n new TextEncoder().encode(normalizedKey),\n ),\n );\n\n return {\n version: 1,\n address: context.address.toLowerCase(),\n chainId: context.chainId,\n signatureKind: 'eip712',\n iv: bytesToBase64(iv),\n ciphertext: bytesToBase64(ciphertext),\n createdAt: new Date().toISOString(),\n };\n};\n\nexport const decryptAesKeyBackup = async (\n backup: EncryptedAesBackup,\n signer: AesBackupSigner,\n context: AesBackupVaultContext,\n): Promise<string> => {\n if (backup.version !== 1 || backup.signatureKind !== 'eip712') {\n throw new Error('Unsupported AES backup format.');\n }\n\n if (backup.address.toLowerCase() !== context.address.toLowerCase()) {\n throw new Error('AES backup address does not match connected wallet.');\n }\n\n if (backup.chainId !== context.chainId) {\n throw new Error('AES backup network does not match current COTI network.');\n }\n\n const signature = await signBackupContext(signer, context);\n const wrappingKey = await deriveCryptoKey(signature);\n const decrypted = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: base64ToBytes(backup.iv) },\n wrappingKey,\n base64ToBytes(backup.ciphertext),\n );\n\n return validateAesKey(new TextDecoder().decode(decrypted));\n};\n\n","import { getPluginConfig } from '../config/plugin';\n\n/**\n * Origins allowed by published @coti-io/coti-snap to invoke set-aes-key.\n * Must stay in sync with the snap's internal whitelist (security audit).\n */\nconst PUBLISHED_SNAP_AES_WRITE_ORIGINS = new Set([\n 'https://metamask.coti.io',\n 'https://dev.metamask.coti.io',\n]);\n\n/**\n * Returns true when the current page may call wallet_invokeSnap set-aes-key.\n *\n * Checks both the hard-coded published origins and any additional origins\n * declared via configureCotiPlugin({ additionalSnapAesWriteOrigins }).\n *\n * The Snap manifest's allowedOrigins for set-aes-key must also include any\n * additional origin for the persist to actually succeed — a plugin-only change\n * is not sufficient.\n */\nexport function canPersistAesKeyToSnap(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n const extra = getPluginConfig().additionalSnapAesWriteOrigins ?? [];\n const allowed = extra.length > 0\n ? new Set([...PUBLISHED_SNAP_AES_WRITE_ORIGINS, ...extra])\n : PUBLISHED_SNAP_AES_WRITE_ORIGINS;\n return allowed.has(window.location.origin);\n}\n","import {\n assertAesKeyChainId,\n getPluginConfig,\n isAesKeyChainId,\n type AesKeyChainId,\n type EncryptedAesBackup,\n} from '../config/plugin';\nimport { COTI_TESTNET_CHAIN_ID } from '../config/chains';\nimport { CotiPluginError, CotiErrorCode } from '../errors';\nimport { logger } from './logger';\nimport { isOnboardingServicesEnabled } from './onboardingServices';\n\nimport type { AesKeyProviderOptions } from '../hooks/useAesKeyProvider';\n\n/** How private AES material should be accessed for unlock and crypto ops. */\nexport type AesAccessMode = 'snap' | 'local' | 'onboard';\n\nexport interface AesAccessStrategy {\n mode: AesAccessMode;\n aesKeyChainId: AesKeyChainId;\n snapInstalled: boolean;\n snapHasKey: boolean;\n hasEncryptedBackup: boolean;\n /** Populated when a backup probe loaded the encrypted blob. */\n encryptedBackup?: EncryptedAesBackup | null;\n}\n\nexport interface ResolveAesAccessStrategyInput {\n address: string;\n chainId?: number;\n aesKeyChainId?: number;\n snapInstalled: boolean;\n sessionAesKey?: string | null;\n hasAesKeyInSnap: (accountAddress?: string) => Promise<boolean | null>;\n /** Re-checks Snap availability when key probe returns null (avoids false errors). */\n confirmSnapInstalled?: () => Promise<boolean>;\n snapKeyProbeRetries?: number;\n}\n\nasync function fetchEncryptedBackupProbe(\n address: string,\n chainId: number,\n): Promise<EncryptedAesBackup | null> {\n const services = getPluginConfig().onboardingServices;\n if (!isOnboardingServicesEnabled() || !services?.fetchEncryptedAesBackup) {\n return null;\n }\n\n try {\n return await services.fetchEncryptedAesBackup({ address, chainId });\n } catch (error) {\n logger.warn('[AesAccess] local backup probe failed:', error);\n return null;\n }\n}\n\nasync function probeLocalBackup(address: string, chainId: number): Promise<boolean> {\n const backup = await fetchEncryptedBackupProbe(address, chainId);\n return backup != null;\n}\n\nconst sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\n\nexport function resolveAesKeyChainId(\n currentChainId?: number | null,\n overrideChainId?: number | null,\n): AesKeyChainId {\n const configuredChainId = getPluginConfig().aesKeyChainId;\n assertAesKeyChainId(configuredChainId);\n\n if (overrideChainId !== undefined && overrideChainId !== null) {\n assertAesKeyChainId(overrideChainId);\n return overrideChainId;\n }\n\n if (configuredChainId !== undefined) {\n return configuredChainId;\n }\n\n if (isAesKeyChainId(currentChainId)) {\n return currentChainId;\n }\n\n return COTI_TESTNET_CHAIN_ID;\n}\n\nasync function probeSnapKeyWithRetry(\n hasAesKeyInSnap: (accountAddress?: string) => Promise<boolean | null>,\n address: string,\n retries: number,\n confirmSnapInstalled?: () => Promise<boolean>,\n): Promise<boolean> {\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n const result = await hasAesKeyInSnap(address);\n if (result !== null) return result;\n if (attempt < retries) await sleep(250);\n }\n\n if (confirmSnapInstalled && !(await confirmSnapInstalled())) {\n return false;\n }\n\n throw new CotiPluginError(\n CotiErrorCode.SNAP_KEY_CHECK_FAILED,\n 'Could not check Snap AES key.',\n );\n}\n\n/**\n * Single routing table for AES unlock / crypto:\n * 1. no snap + no local backup → onboard\n * 2. snap + no snap key + no local backup → onboard (persist to snap when possible)\n * 3. snap + no snap key + local backup → local key only\n * 4. snap + snap key + local backup → snap\n * 5. snap + snap key + no local backup → snap\n */\nexport function resolveAesAccessMode(input: {\n snapInstalled: boolean;\n snapHasKey: boolean;\n hasEncryptedBackup: boolean;\n sessionAesKey?: string | null;\n}): AesAccessMode {\n if (input.snapInstalled && input.snapHasKey) {\n return 'snap';\n }\n if (input.hasEncryptedBackup || input.sessionAesKey) {\n return 'local';\n }\n return 'onboard';\n}\n\nexport async function resolveAesAccessStrategy(\n input: ResolveAesAccessStrategyInput,\n): Promise<AesAccessStrategy> {\n const aesKeyChainId = resolveAesKeyChainId(input.chainId, input.aesKeyChainId);\n let snapHasKey = false;\n let encryptedBackup: EncryptedAesBackup | null;\n\n if (input.snapInstalled) {\n const backupProbe = fetchEncryptedBackupProbe(input.address, aesKeyChainId);\n const [snapResult, backupResult] = await Promise.all([\n probeSnapKeyWithRetry(\n input.hasAesKeyInSnap,\n input.address,\n input.snapKeyProbeRetries ?? 1,\n input.confirmSnapInstalled,\n ),\n backupProbe,\n ]);\n snapHasKey = snapResult;\n encryptedBackup = snapHasKey ? null : backupResult;\n } else {\n encryptedBackup = await fetchEncryptedBackupProbe(input.address, aesKeyChainId);\n }\n const hasEncryptedBackup = encryptedBackup != null;\n\n const mode = resolveAesAccessMode({\n snapInstalled: input.snapInstalled,\n snapHasKey,\n hasEncryptedBackup,\n sessionAesKey: input.sessionAesKey,\n });\n\n logger.log('[AesAccess] resolved strategy', {\n mode,\n aesKeyChainId,\n snapInstalled: input.snapInstalled,\n snapHasKey,\n hasEncryptedBackup,\n hasSessionKey: !!input.sessionAesKey,\n });\n\n return {\n mode,\n aesKeyChainId,\n snapInstalled: input.snapInstalled,\n snapHasKey,\n hasEncryptedBackup,\n encryptedBackup,\n };\n}\n\n/**\n * Restore-only routing: load encrypted backup first so the wallet sign prompt is\n * not blocked by Snap probes or duplicate backup fetches.\n */\nexport async function resolveRestoreAesAccessStrategy(\n input: ResolveAesAccessStrategyInput,\n): Promise<AesAccessStrategy> {\n const aesKeyChainId = resolveAesKeyChainId(input.chainId, input.aesKeyChainId);\n const encryptedBackup = await fetchEncryptedBackupProbe(input.address, aesKeyChainId);\n if (encryptedBackup) {\n logger.log('[AesAccess] restore probe: encrypted backup found — fast local path');\n return {\n mode: 'local',\n aesKeyChainId,\n snapInstalled: input.snapInstalled,\n snapHasKey: false,\n hasEncryptedBackup: true,\n encryptedBackup,\n };\n }\n\n return resolveAesAccessStrategy(input);\n}\n\nexport interface AesUnlockPlan {\n unlockOptions: AesKeyProviderOptions & { validateOnUnlock: true };\n checkSnap: boolean;\n keyForUnlock?: string;\n accessMode?: AesAccessMode;\n}\n\n/** Maps a resolved strategy to balance-updater / getAesKey options. */\nexport function buildUnlockPlanFromStrategy(\n strategy: AesAccessStrategy,\n unlockOptions: AesKeyProviderOptions & { validateOnUnlock: true },\n sessionKey?: string,\n): AesUnlockPlan {\n switch (strategy.mode) {\n case 'snap':\n return {\n unlockOptions: { ...unlockOptions, snapSideDecrypt: true },\n checkSnap: false,\n keyForUnlock: undefined,\n accessMode: strategy.mode,\n };\n case 'local':\n return {\n unlockOptions: sessionKey\n ? unlockOptions\n : {\n ...unlockOptions,\n restoreOnly: true,\n prefetchedEncryptedBackup: strategy.encryptedBackup,\n },\n checkSnap: !sessionKey,\n keyForUnlock: sessionKey,\n accessMode: strategy.mode,\n };\n case 'onboard':\n return {\n unlockOptions: unlockOptions.restoreOnly\n ? unlockOptions\n : { ...unlockOptions, forceContractOnboarding: true },\n checkSnap: !sessionKey,\n keyForUnlock: sessionKey,\n accessMode: strategy.mode,\n };\n }\n}\n\nexport function shouldUseSnapCrypto(strategy: AesAccessStrategy): boolean {\n return strategy.mode === 'snap';\n}\n\nexport function shouldUseLocalCrypto(\n strategy: AesAccessStrategy,\n sessionAesKey?: string | null,\n): boolean {\n return strategy.mode === 'local' && !!sessionAesKey;\n}\n","import { getPluginConfig } from '../config/plugin';\n\nexport function isOnboardingServicesEnabled(): boolean {\n const mode = getPluginConfig().onboardingServices?.mode;\n return mode === 'custom' || mode === 'official';\n}\n","import { BrowserProvider, JsonRpcSigner } from '@coti-io/coti-ethers';\nimport type { Connector } from 'wagmi';\nimport { getPluginConfig } from '../config/plugin';\nimport { encryptAesKeyBackup } from '../crypto/aesKeyBackupVault';\nimport { logger } from './logger';\nimport { isOnboardingServicesEnabled } from './onboardingServices';\nimport { isUserRejection } from './walletErrors';\nimport type { EIP1193Provider } from './ethereum';\nimport {\n isMetaMaskMobileBrowser,\n resolveMetaMaskMobileWalletProvider,\n} from './metaMaskMobile';\n\nexport type PersistEncryptedAesBackupResult =\n | { status: 'saved' }\n | { status: 'skipped' }\n | { status: 'cancelled' }\n | { status: 'failed'; message: string };\n\nexport async function persistEncryptedAesBackup(params: {\n aesKey: string;\n address: string;\n chainId: number;\n connector: Connector;\n preferReplace?: boolean;\n onBeforeSign?: () => void;\n}): Promise<PersistEncryptedAesBackupResult> {\n const services = getPluginConfig().onboardingServices;\n if (\n !isOnboardingServicesEnabled()\n || (!services?.saveEncryptedAesBackup && !services?.replaceEncryptedAesBackup)\n ) {\n return { status: 'skipped' };\n }\n\n const backupContext = {\n address: params.address,\n chainId: params.chainId,\n };\n\n try {\n const connectorProvider = await params.connector.getProvider() as EIP1193Provider | null;\n const walletProvider = resolveMetaMaskMobileWalletProvider(\n connectorProvider as Parameters<typeof resolveMetaMaskMobileWalletProvider>[0],\n ) as EIP1193Provider;\n\n if (!walletProvider?.request) {\n return { status: 'failed', message: 'Could not get provider from wallet connector.' };\n }\n\n const provider = new BrowserProvider(walletProvider);\n const signer = isMetaMaskMobileBrowser()\n ? new JsonRpcSigner(provider, params.address)\n : await provider.getSigner(params.address);\n\n params.onBeforeSign?.();\n\n const backup = await encryptAesKeyBackup(params.aesKey, signer, backupContext);\n\n let existingBackup = null;\n if (!params.preferReplace && services.fetchEncryptedAesBackup) {\n try {\n existingBackup = await services.fetchEncryptedAesBackup(backupContext);\n } catch (error) {\n logger.warn('[AesBackup] Existing backup probe failed:', error);\n }\n }\n\n const saveBackup = (params.preferReplace || existingBackup) && services.replaceEncryptedAesBackup\n ? services.replaceEncryptedAesBackup\n : services.saveEncryptedAesBackup;\n\n if (!saveBackup) {\n return { status: 'skipped' };\n }\n\n await saveBackup({ ...backupContext, backup });\n return { status: 'saved' };\n } catch (error) {\n if (isUserRejection(error)) {\n return { status: 'cancelled' };\n }\n\n const message = error instanceof Error\n ? error.message\n : 'Encrypted AES backup could not be saved.';\n return { status: 'failed', message };\n }\n}\n","const EIP_1193_USER_REJECTED = 4001;\n\nexport function isUserRejection(error: unknown): boolean {\n if (error && typeof error === 'object') {\n const err = error as {\n code?: number | string;\n message?: string;\n reason?: string;\n info?: { error?: { code?: number | string; message?: string } };\n };\n if (err.code === EIP_1193_USER_REJECTED) return true;\n if (err.info?.error?.code === EIP_1193_USER_REJECTED) return true;\n if (err.code === 'ACTION_REJECTED' || err.reason === 'rejected') return true;\n const message = `${err.message ?? ''} ${err.info?.error?.message ?? ''}`.toLowerCase();\n if (\n message.includes('user rejected')\n || message.includes('user denied')\n || message.includes('rejected the request')\n || message.includes('request rejected')\n || message.includes('action_rejected')\n || message.includes('user cancelled')\n || message.includes('user canceled')\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (error && typeof error === 'object' && 'message' in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === 'string') return message;\n }\n return String(error);\n}\n\nexport function isInsufficientFundsError(error: unknown): boolean {\n const message = getErrorMessage(error).toLowerCase();\n return (\n message.includes('insufficient funds')\n || message.includes('insufficient balance')\n || message.includes('account balance is 0')\n || message.includes('not enough coti')\n || message.includes('not enough balance')\n || message.includes('insufficient funds for transfer')\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { logger } from '../../lib/logger';\n\n/** Wallet-bound session AES key (prevents cross-account key bleed). */\nexport const usePrivacyBridgeSessionKey = (walletAddress: string) => {\n const [sessionKeyRecord, setSessionKeyRecord] = useState<{ wallet: string; key: string } | null>(\n null,\n );\n const [arePrivateBalancesHidden, setArePrivateBalancesHidden] = useState(true);\n\n const sessionAesKey = useMemo(() => {\n if (!sessionKeyRecord || !walletAddress) return null;\n if (sessionKeyRecord.wallet.toLowerCase() !== walletAddress.toLowerCase()) return null;\n return sessionKeyRecord.key;\n }, [sessionKeyRecord, walletAddress]);\n\n const setSessionAesKey = useCallback(\n (key: string | null, keyWallet?: string) => {\n if (key == null || key === '') {\n setSessionKeyRecord(null);\n return;\n }\n const w = keyWallet ?? walletAddress;\n if (!w) {\n logger.warn('setSessionAesKey: no wallet for key binding; clearing');\n setSessionKeyRecord(null);\n return;\n }\n setSessionKeyRecord({ wallet: w.toLowerCase(), key });\n },\n [walletAddress],\n );\n\n return {\n sessionAesKey,\n setSessionAesKey,\n arePrivateBalancesHidden,\n setArePrivateBalancesHidden,\n };\n};\n","import { useCallback, useMemo } from 'react';\nimport { useAccount as useWagmiAccount, useConfig } from 'wagmi';\nimport { useMetamask } from '../../hooks/useMetamask';\nimport { useNetworkEnforcer } from '../../hooks/useNetworkEnforcer';\nimport { getNetworkNameForChain, getWalletNetworkConfigs } from '../../chains';\nimport { logger } from '../../lib/logger';\nimport { truncateAddress } from '../../lib/format';\nimport type { PrivacyBridgeSessionCore, UpdateAccountStateRef } from './sessionShared';\n\ninterface UsePrivacyBridgeNetworkSessionOptions {\n core: PrivacyBridgeSessionCore;\n updateAccountStateRef: UpdateAccountStateRef;\n}\n\ninterface WalletConnectEip155Namespace {\n chains?: string[];\n accounts?: string[];\n methods?: string[];\n}\n\n// Native URL schemes used to foreground the wallet app so the user sees the\n// wallet_addEthereumChain approval prompt (WalletConnect requests are silent\n// while the wallet app is backgrounded, unless it has push enabled).\nconst WALLET_DEEPLINK_SCHEMES: Record<string, string> = {\n zerion: 'zerion://',\n trust: 'trust://',\n onekey: 'onekey-wallet://',\n metaMask: 'metamask://',\n};\n\nconst isMobileBrowser = (): boolean =>\n typeof navigator !== 'undefined' && (\n /android|iphone|ipod/i.test(navigator.userAgent)\n || /ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)\n );\n\nconst foregroundWalletApp = (connector: { id: string; rkDetails?: { id?: string } } | undefined): void => {\n if (!isMobileBrowser() || typeof window === 'undefined' || !connector) return;\n const walletId = connector.rkDetails?.id ?? connector.id;\n const scheme = WALLET_DEEPLINK_SCHEMES[walletId];\n if (!scheme) return;\n // Give the relay websocket a moment to flush the request before the browser\n // is backgrounded by the app switch.\n setTimeout(() => {\n window.location.href = scheme;\n }, 300);\n};\n\n/** MetaMask + wagmi network switching and effective chain id. */\nexport const usePrivacyBridgeNetworkSession = ({\n core,\n updateAccountStateRef,\n}: UsePrivacyBridgeNetworkSessionOptions) => {\n const {\n isConnected,\n walletAddress,\n hasSnap,\n wagmiSyncRef,\n disconnectingRef,\n metamaskExplicitConnect,\n setSessionAesKey,\n setArePrivateBalancesHidden,\n executeSnapCheck,\n } = core;\n\n const { address: wagmiAddress, isConnected: wagmiConnected, chainId: wagmiChainId, connector: wagmiConnector } =\n useWagmiAccount();\n const wagmiConfig = useConfig();\n\n const switchNetworkViaWagmiProvider = useCallback(async (targetChainId: string): Promise<boolean> => {\n if (!wagmiConnector) {\n logger.warn('[switchNetworkViaWagmi] No wagmi connector available');\n return false;\n }\n\n let provider: any;\n try {\n provider = await wagmiConnector.getProvider();\n } catch (e) {\n logger.warn('[switchNetworkViaWagmi] Failed to get provider from connector:', e);\n return false;\n }\n\n if (!provider?.request) {\n logger.warn('[switchNetworkViaWagmi] Provider has no request method');\n return false;\n }\n\n const networks = getWalletNetworkConfigs();\n\n // WalletConnect sessions never surface MetaMask's 4902 \"unrecognized chain\"\n // error, so the add-chain fallback below would never fire. Instead, read the\n // approved session namespace: if the target chain is missing, push it with\n // wallet_addEthereumChain (EIP-3085) before switching, and deep-link the\n // wallet app to the foreground so the user sees the approval prompt.\n const wcSession = provider.session as\n | { namespaces?: Record<string, WalletConnectEip155Namespace> }\n | undefined;\n if (provider.isWalletConnect || wcSession?.namespaces) {\n const eip155 = wcSession?.namespaces?.['eip155'];\n const approvedChains = new Set<string>([\n ...(eip155?.chains ?? []),\n ...(eip155?.accounts ?? []).map(account => account.split(':').slice(0, 2).join(':')),\n ]);\n const targetCaip = `eip155:${parseInt(targetChainId, 16)}`;\n\n if (!approvedChains.has(targetCaip)) {\n const networkConfig = networks[targetChainId];\n if (!networkConfig) {\n logger.error('[switchNetworkViaWagmi] No network config for chainId', targetChainId);\n return false;\n }\n if (eip155?.methods && !eip155.methods.includes('wallet_addEthereumChain')) {\n logger.error(\n '[switchNetworkViaWagmi] Wallet session does not allow wallet_addEthereumChain;',\n 'the network must be added manually in the wallet app',\n );\n return false;\n }\n try {\n const addRequest = provider.request({\n method: 'wallet_addEthereumChain',\n params: [networkConfig],\n });\n foregroundWalletApp(wagmiConnector as { id: string; rkDetails?: { id?: string } });\n await addRequest;\n } catch (addError) {\n logger.error('[switchNetworkViaWagmi] Wallet rejected wallet_addEthereumChain:', addError);\n return false;\n }\n }\n\n try {\n await provider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: targetChainId }],\n });\n return true;\n } catch (switchError) {\n logger.error('[switchNetworkViaWagmi] Failed to switch after add:', switchError);\n return false;\n }\n }\n\n try {\n await provider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: targetChainId }],\n });\n return true;\n } catch (switchError: any) {\n if (switchError.code === 4902) {\n const networkConfig = networks[targetChainId];\n if (!networkConfig) {\n logger.error('[switchNetworkViaWagmi] No network config for chainId', targetChainId);\n return false;\n }\n try {\n await provider.request({\n method: 'wallet_addEthereumChain',\n params: [networkConfig],\n });\n return true;\n } catch (addError) {\n logger.error('[switchNetworkViaWagmi] Failed to add chain:', addError);\n return false;\n }\n }\n logger.error('[switchNetworkViaWagmi] Failed to switch:', switchError);\n return false;\n }\n }, [wagmiConnector]);\n\n const {\n connectWallet,\n checkNetwork,\n switchNetwork: metamaskSwitchNetwork,\n networkName: metamaskNetworkName,\n COTI_MAINNET_ID,\n COTI_TESTNET_ID,\n SEPOLIA_ID,\n chainId: metamaskChainId,\n registerEthereumInitializedListener,\n } = useMetamask({\n onNetworkChanged: async () => {\n // wagmi/RainbowKit already reacts to chain changes (wagmiChainId updates\n // and usePrivacyBridgeWagmiSync resyncs account state). A full page reload\n // here would drop the wagmi connection (reconnectOnMount: false), forcing\n // the user to reconnect after every network switch.\n if (wagmiSyncRef.current || wagmiConnected || disconnectingRef.current) {\n logger.log('Ignoring MetaMask chainChanged — wagmi is managing connection');\n return;\n }\n // Non-wagmi (injected MetaMask) path: soft-resync account/network state\n // instead of reloading the page.\n if (walletAddress) {\n await updateAccountStateRef.current?.(walletAddress, hasSnap, false);\n }\n },\n onAccountChanged: async account => {\n if (wagmiSyncRef.current || wagmiConnected || disconnectingRef.current) {\n logger.log('Ignoring MetaMask accountsChanged — wagmi is managing connection');\n return;\n }\n\n if (!metamaskExplicitConnect.current && !isConnected) {\n logger.log(\"Ignoring MetaMask auto-detection — user hasn't clicked MetaMask\");\n return;\n }\n\n if (walletAddress && account.toLowerCase() === walletAddress.toLowerCase()) {\n logger.log('Account unchanged, skipping session reset');\n return;\n }\n\n logger.log('Account changed, clearing sessionAesKey and locking', truncateAddress(account));\n setSessionAesKey(null);\n setArePrivateBalancesHidden(true);\n await updateAccountStateRef.current?.(account, hasSnap, false);\n },\n onSnapCheck: async account => {\n if (wagmiSyncRef.current || wagmiConnected || disconnectingRef.current) return;\n if (!metamaskExplicitConnect.current && !isConnected) return;\n\n await executeSnapCheck(async () => {\n await updateAccountStateRef.current?.(account, true, false);\n return true;\n });\n },\n });\n\n const switchNetwork = useCallback(async (targetChainId: string): Promise<boolean> => {\n if (wagmiSyncRef.current) return switchNetworkViaWagmiProvider(targetChainId);\n return metamaskSwitchNetwork(targetChainId);\n }, [switchNetworkViaWagmiProvider, metamaskSwitchNetwork, wagmiSyncRef]);\n\n const chainId = useMemo(() => {\n if (wagmiConnected && wagmiChainId) return wagmiChainId.toString();\n return metamaskChainId;\n }, [wagmiConnected, wagmiChainId, metamaskChainId]);\n\n const networkEnforcer = useNetworkEnforcer(chainId, switchNetwork);\n const currentChainId = chainId ? Number(chainId) : undefined;\n const networkName = useMemo(\n () => (chainId ? getNetworkNameForChain(chainId) : metamaskNetworkName),\n [chainId, metamaskNetworkName],\n );\n\n return {\n connectWallet,\n checkNetwork,\n registerEthereumInitializedListener,\n switchNetwork,\n chainId,\n currentChainId,\n networkName,\n COTI_MAINNET_ID,\n COTI_TESTNET_ID,\n SEPOLIA_ID,\n wagmiAddress,\n wagmiConnected,\n wagmiChainId,\n wagmiConnector,\n wagmiConfig,\n ...networkEnforcer,\n };\n};\n\nexport type PrivacyBridgeNetworkSession = ReturnType<typeof usePrivacyBridgeNetworkSession>;\n","import { useCallback, useEffect, useRef } from 'react';\nimport { useAccount } from 'wagmi';\nimport { useBalanceUpdater } from '../../hooks/useBalanceUpdater';\nimport { isChainUpdatesMuted } from '../../lib/chainMute';\nimport { logger } from '../../lib/logger';\nimport { getMetaMaskProvider } from '../../lib/ethereum';\nimport { validateMetaMaskAesKeyOnUnlock as validateMetaMaskAesKeyOnUnlockFn } from '../../crypto/aesKeyValidation';\nimport { useWalletType } from '../../hooks/useWalletType';\nimport {\n getInitialPublicTokens,\n getInitialPrivateTokens,\n} from '../../hooks/usePrivacyBridge';\nimport type { PrivacyBridgeNetworkSession } from './usePrivacyBridgeNetworkSession';\nimport type { PrivacyBridgeSessionCore, UpdateAccountStateRef } from './sessionShared';\nimport type { AesKeyProviderOptions } from '../../hooks/useAesKeyProvider';\n\ninterface UsePrivacyBridgeAccountSyncOptions {\n core: PrivacyBridgeSessionCore;\n network: PrivacyBridgeNetworkSession;\n updateAccountStateRef: UpdateAccountStateRef;\n}\n\n/** Balance refresh, token list resets, and session-key-driven account updates. */\nexport const usePrivacyBridgeAccountSync = ({\n core,\n network,\n updateAccountStateRef,\n}: UsePrivacyBridgeAccountSyncOptions) => {\n const {\n setWalletAddress,\n setIsConnected,\n setHasSnap,\n setPublicTokens,\n setPrivateTokens,\n sessionAesKey,\n setSessionAesKey,\n arePrivateBalancesHidden,\n setArePrivateBalancesHidden,\n fetchPrivateBalance,\n getAesKeyFromProvider,\n getAESKeyFromSnap,\n isConnected,\n hasSnap,\n walletAddress,\n wagmiSyncRef,\n checkSnapStatus,\n } = core;\n\n const { checkNetwork, currentChainId, wagmiChainId } = network;\n const { chainId: connectedChainId } = useAccount();\n const walletTypeInfo = useWalletType();\n\n const validateMetaMaskAesKeyOnUnlock = useCallback(\n async (snapKey: string, accountAddress: string, chainIdOverride?: number | null) => {\n if (walletTypeInfo.walletType !== 'metamask') return;\n\n const provider = getMetaMaskProvider();\n if (!provider) {\n throw new Error('MetaMask provider not available for AES key validation.');\n }\n\n await validateMetaMaskAesKeyOnUnlockFn(\n snapKey,\n accountAddress,\n provider,\n chainIdOverride ?? connectedChainId ?? null,\n );\n },\n [walletTypeInfo.walletType, connectedChainId],\n );\n\n const getAESKeyForCurrentNetwork = useCallback(\n async (\n accountAddress: string,\n options?: { skipCache?: boolean } & AesKeyProviderOptions,\n ) => {\n if (\n options?.skipCache\n && walletTypeInfo.walletType === 'metamask'\n && !options.forceContractOnboarding\n && !options.restoreOnly\n ) {\n return getAESKeyFromSnap(accountAddress, { skipCache: true });\n }\n\n // Always prioritize the in-memory session key — avoids any interactive prompts\n // during automatic balance refreshes.\n if (sessionAesKey && !options?.forceContractOnboarding) return sessionAesKey;\n\n // Fall through to the wallet-type-aware provider (useAesKeyProvider).\n // For MetaMask: tries Snap (non-interactive if already connected)\n // For non-MetaMask: triggers contract onboarding (interactive — but only called\n // when checkSnap=true, i.e. explicit user-initiated unlock flows).\n return options === undefined\n ? getAesKeyFromProvider(accountAddress)\n : getAesKeyFromProvider(accountAddress, options.onProgress, options);\n },\n [sessionAesKey, getAesKeyFromProvider, getAESKeyFromSnap],\n );\n\n const { updateAccountState } = useBalanceUpdater({\n setWalletAddress,\n setIsConnected,\n setHasSnap,\n setPublicTokens,\n setPrivateTokens,\n checkNetwork,\n getAESKeyFromSnap: getAESKeyForCurrentNetwork,\n fetchPrivateBalance,\n canUseSnapOperations:\n walletTypeInfo.walletType === 'metamask'\n && (walletTypeInfo.isMetaMaskWithSnap || hasSnap),\n snapDecryptOptions: {\n decryptCtUint64: core.decryptCtUint64ViaSnap,\n decryptCtUint256: core.decryptCtUint256ViaSnap,\n },\n sessionAesKey,\n setSessionAesKey,\n validateMetaMaskAesKeyOnUnlock,\n });\n\n updateAccountStateRef.current = updateAccountState;\n\n // Proactively detect Snap on MetaMask wallet connect so hasSnap is available\n // before the user triggers refreshPrivateBalances / unlock routing.\n useEffect(() => {\n if (\n walletTypeInfo.walletType !== 'metamask'\n || !walletAddress\n || hasSnap\n ) {\n return;\n }\n\n checkSnapStatus().catch(() => {\n // Non-fatal — hasSnap stays false and unlock falls back to contract path.\n });\n }, [walletAddress, walletTypeInfo.walletType, hasSnap, checkSnapStatus]);\n\n useEffect(() => {\n if (isChainUpdatesMuted()) return;\n\n if (!isConnected) {\n setPublicTokens(getInitialPublicTokens(currentChainId));\n setPrivateTokens(getInitialPrivateTokens(currentChainId));\n }\n }, [isConnected, currentChainId, setPublicTokens, setPrivateTokens]);\n\n // Track the previous sessionAesKey value so we only auto-unlock when the key\n // *arrives* for the first time (null → value), not on every render where a key\n // is already present but balances happen to be hidden (e.g. after a manual lock).\n const prevSessionAesKeyRef = useRef<string | null>(null);\n\n useEffect(() => {\n const keyJustArrived = !prevSessionAesKeyRef.current && !!sessionAesKey;\n prevSessionAesKeyRef.current = sessionAesKey;\n\n if (keyJustArrived && sessionAesKey && walletAddress && arePrivateBalancesHidden) {\n logger.log('Session AES Key arrived — refreshing private balances...');\n const chainOverride = wagmiSyncRef.current ? wagmiChainId : undefined;\n updateAccountState(walletAddress, false, true, sessionAesKey, chainOverride).then((success) => {\n if (success) {\n setArePrivateBalancesHidden(false);\n }\n });\n }\n }, [\n sessionAesKey,\n walletAddress,\n arePrivateBalancesHidden,\n updateAccountState,\n setArePrivateBalancesHidden,\n wagmiSyncRef,\n wagmiChainId,\n ]);\n\n return { updateAccountState, currentChainId };\n};\n\nexport type PrivacyBridgeAccountSync = ReturnType<typeof usePrivacyBridgeAccountSync>;\n","import { useEffect, useRef } from 'react';\nimport { getPluginConfig } from '../../config/plugin';\nimport { mapConnectorIdToWalletType } from '../../hooks/useWalletType';\nimport { isChainUpdatesMuted } from '../../lib/chainMute';\nimport { logger } from '../../lib/logger';\nimport { truncateAddress } from '../../lib/format';\nimport { clearAesKeyValidatedForUnlock } from '../../crypto/aesKeyValidation';\nimport { getInitialPrivateTokens } from '../../hooks/usePrivacyBridge';\nimport type { PrivacyBridgeAccountSync } from './usePrivacyBridgeAccountSync';\nimport type { PrivacyBridgeNetworkSession } from './usePrivacyBridgeNetworkSession';\nimport type { PrivacyBridgeSessionCore } from './sessionShared';\n\ninterface UsePrivacyBridgeWagmiSyncOptions {\n core: PrivacyBridgeSessionCore;\n network: PrivacyBridgeNetworkSession;\n accountSync: PrivacyBridgeAccountSync;\n}\n\n/** Syncs RainbowKit/wagmi connection state into the bridge session. */\nexport const usePrivacyBridgeWagmiSync = ({\n core,\n network,\n accountSync,\n}: UsePrivacyBridgeWagmiSyncOptions) => {\n const {\n isConnected,\n walletAddress,\n setIsConnected,\n setWalletAddress,\n setHasSnap,\n wagmiSyncRef,\n disconnectingRef,\n setSessionAesKey,\n setArePrivateBalancesHidden,\n setPrivateTokens,\n checkSnapStatus,\n clearSnapCache,\n setMetamaskDetected,\n } = core;\n\n const {\n wagmiAddress,\n wagmiConnected,\n wagmiChainId,\n wagmiConnector,\n } = network;\n\n const { updateAccountState } = accountSync;\n\n useEffect(() => {\n if (wagmiConnected && wagmiAddress && !isConnected && !disconnectingRef.current) {\n logger.log('RainbowKit connection detected, syncing to context', {\n address: truncateAddress(wagmiAddress),\n chainId: wagmiChainId,\n });\n wagmiSyncRef.current = true;\n updateAccountState(wagmiAddress, false, true, undefined, wagmiChainId);\n\n const isMetaMask = mapConnectorIdToWalletType(wagmiConnector?.id) === 'metamask';\n if (isMetaMask) {\n logger.log('MetaMask detected via RainbowKit — checking Snap...');\n void checkSnapStatus();\n }\n }\n\n if (!wagmiConnected && wagmiSyncRef.current) {\n logger.log('RainbowKit disconnected, clearing context');\n wagmiSyncRef.current = false;\n disconnectingRef.current = false;\n setIsConnected(false);\n setWalletAddress('');\n setHasSnap(false);\n setMetamaskDetected(false);\n if (getPluginConfig().clearSessionKeyOnWagmiDisconnect) {\n setSessionAesKey(null);\n clearSnapCache();\n }\n setArePrivateBalancesHidden(true);\n }\n\n if (wagmiConnected && wagmiAddress && isConnected && wagmiAddress !== walletAddress) {\n logger.log('RainbowKit account switched', truncateAddress(wagmiAddress));\n if (walletAddress) clearAesKeyValidatedForUnlock(walletAddress);\n clearAesKeyValidatedForUnlock(wagmiAddress);\n setSessionAesKey(null);\n clearSnapCache();\n setArePrivateBalancesHidden(true);\n setPrivateTokens(getInitialPrivateTokens(wagmiChainId));\n updateAccountState(wagmiAddress, false, false, undefined, wagmiChainId);\n }\n }, [\n wagmiConnected,\n wagmiAddress,\n walletAddress,\n isConnected,\n wagmiChainId,\n wagmiConnector,\n updateAccountState,\n wagmiSyncRef,\n setIsConnected,\n setWalletAddress,\n setHasSnap,\n setSessionAesKey,\n setArePrivateBalancesHidden,\n setPrivateTokens,\n checkSnapStatus,\n clearSnapCache,\n setMetamaskDetected,\n ]);\n\n useEffect(() => {\n if (wagmiConnected && wagmiConnector) {\n const isMetaMask = mapConnectorIdToWalletType(wagmiConnector.id) === 'metamask';\n setMetamaskDetected(isMetaMask);\n if (!isMetaMask) {\n setHasSnap(false);\n }\n return;\n }\n if (!wagmiConnected && wagmiSyncRef.current) {\n setMetamaskDetected(false);\n setHasSnap(false);\n }\n }, [wagmiConnected, wagmiConnector, wagmiSyncRef, setMetamaskDetected, setHasSnap]);\n\n const prevWagmiChainIdRef = useRef<number | undefined>(undefined);\n useEffect(() => {\n if (wagmiConnected && wagmiAddress && isConnected && wagmiAddress === walletAddress && wagmiChainId) {\n if (prevWagmiChainIdRef.current !== undefined && prevWagmiChainIdRef.current !== wagmiChainId) {\n if (isChainUpdatesMuted()) {\n logger.log('[ChainMuted] Ignoring chain change during onboarding', {\n from: prevWagmiChainIdRef.current,\n to: wagmiChainId,\n });\n prevWagmiChainIdRef.current = wagmiChainId;\n return;\n }\n // When a session AES key exists, private balances are already correct.\n // Re-fetch with the key to avoid resetting private tokens to zero.\n if (core.sessionAesKey) {\n logger.log('[ChainChange] sessionAesKey present — refreshing with private balances', {\n from: prevWagmiChainIdRef.current,\n to: wagmiChainId,\n });\n prevWagmiChainIdRef.current = wagmiChainId;\n updateAccountState(wagmiAddress, true, true, core.sessionAesKey, wagmiChainId);\n return;\n }\n logger.log('RainbowKit chain changed', {\n from: prevWagmiChainIdRef.current,\n to: wagmiChainId,\n });\n updateAccountState(wagmiAddress, false, true, undefined, wagmiChainId);\n }\n prevWagmiChainIdRef.current = wagmiChainId;\n }\n }, [wagmiConnected, wagmiAddress, walletAddress, isConnected, wagmiChainId, updateAccountState, core.sessionAesKey]);\n};\n","import { useRef } from 'react';\nimport { logger } from '../../lib/logger';\nimport { forceWagmiSessionClear } from '../../lib/wagmiDisconnect';\nimport { isMultipleWalletsError } from '../../utils/walletErrors';\nimport {\n getInitialPublicTokens,\n getInitialPrivateTokens,\n} from '../../hooks/usePrivacyBridge';\nimport type { PrivacyBridgeAccountSync } from './usePrivacyBridgeAccountSync';\nimport type { PrivacyBridgeNetworkSession } from './usePrivacyBridgeNetworkSession';\nimport type { PrivacyBridgeSessionCore } from './sessionShared';\n\ninterface UsePrivacyBridgeWalletConnectionOptions {\n core: PrivacyBridgeSessionCore;\n network: PrivacyBridgeNetworkSession;\n accountSync: PrivacyBridgeAccountSync;\n}\n\n/** MetaMask connect/disconnect flows. */\nexport const usePrivacyBridgeWalletConnection = ({\n core,\n network,\n accountSync,\n}: UsePrivacyBridgeWalletConnectionOptions) => {\n const {\n modals: { setShowInstallModal, setShowMultipleWalletsModal },\n metamaskExplicitConnect,\n ethereumListenerRegistered,\n isConnected,\n setIsConnected,\n setWalletAddress,\n setHasSnap,\n setPublicTokens,\n setPrivateTokens,\n setSessionAesKey,\n setArePrivateBalancesHidden,\n clearSnapCache,\n wagmiSyncRef,\n disconnectingRef,\n setMetamaskDetected,\n } = core;\n\n const {\n connectWallet,\n registerEthereumInitializedListener,\n wagmiConnected,\n wagmiConnector,\n wagmiConfig,\n } = network;\n const { updateAccountState, currentChainId } = accountSync;\n\n const handleConnectRef = useRef<() => Promise<void>>();\n\n const handleConnect = async () => {\n if (!window.ethereum && ethereumListenerRegistered.current) return;\n metamaskExplicitConnect.current = true;\n try {\n const connected = await connectWallet(async account => {\n await updateAccountState(account, false, false);\n });\n if (connected && !wagmiSyncRef.current && !wagmiConnected) {\n setMetamaskDetected(true);\n }\n } catch (error: any) {\n logger.error('Connection failed:', error);\n\n if (isMultipleWalletsError(error?.message)) {\n setShowMultipleWalletsModal(true);\n return;\n }\n\n if (error.message === 'METAMASK_NOT_INSTALLED') {\n setShowInstallModal(true);\n if (!ethereumListenerRegistered.current) {\n registerEthereumInitializedListener(() => {\n ethereumListenerRegistered.current = false;\n setShowInstallModal(false);\n handleConnectRef.current?.();\n });\n ethereumListenerRegistered.current = true;\n }\n }\n }\n };\n\n handleConnectRef.current = handleConnect;\n\n const handleDisconnect = async () => {\n const wasConnected = wagmiSyncRef.current || wagmiConnected || isConnected;\n if (wasConnected) {\n disconnectingRef.current = true;\n }\n\n metamaskExplicitConnect.current = false;\n\n const shouldClearWagmi = wagmiConnected || wagmiSyncRef.current || !!wagmiConnector;\n wagmiSyncRef.current = false;\n\n if (shouldClearWagmi) {\n await forceWagmiSessionClear(wagmiConfig, wagmiConnector);\n }\n\n setIsConnected(false);\n setWalletAddress('');\n setHasSnap(false);\n setMetamaskDetected(false);\n setPublicTokens(getInitialPublicTokens(currentChainId));\n setPrivateTokens(getInitialPrivateTokens(currentChainId));\n setSessionAesKey(null);\n setArePrivateBalancesHidden(true);\n setShowMultipleWalletsModal(false);\n clearSnapCache();\n disconnectingRef.current = false;\n logger.log('Disconnected wallet');\n };\n\n return { handleConnect, handleDisconnect };\n};\n","import type { Config, Connection, Connector } from '../createConfig.js'\nimport type { BaseErrorType, ErrorType } from '../errors/base.js'\nimport type {\n ConnectorNotConnectedErrorType,\n ConnectorNotFoundErrorType,\n} from '../errors/config.js'\nimport type { ConnectorParameter } from '../types/properties.js'\n\nexport type DisconnectParameters = ConnectorParameter\n\nexport type DisconnectReturnType = void\n\nexport type DisconnectErrorType =\n | ConnectorNotFoundErrorType\n | ConnectorNotConnectedErrorType\n // base\n | BaseErrorType\n | ErrorType\n\n/** https://wagmi.sh/core/api/actions/disconnect */\nexport async function disconnect(\n config: Config,\n parameters: DisconnectParameters = {},\n): Promise<DisconnectReturnType> {\n let connector: Connector | undefined\n if (parameters.connector) connector = parameters.connector\n else {\n const { connections, current } = config.state\n const connection = connections.get(current!)\n connector = connection?.connector\n }\n\n const connections = config.state.connections\n\n if (connector) {\n await connector.disconnect()\n connector.emitter.off('change', config._internal.events.change)\n connector.emitter.off('disconnect', config._internal.events.disconnect)\n connector.emitter.on('connect', config._internal.events.connect)\n\n connections.delete(connector.uid)\n }\n\n config.setState((x) => {\n // if no connections exist, move to disconnected state\n if (connections.size === 0)\n return {\n ...x,\n connections: new Map(),\n current: null,\n status: 'disconnected',\n }\n\n // switch over to another connection\n const nextConnection = connections.values().next().value as Connection\n return {\n ...x,\n connections: new Map(connections),\n current: nextConnection.connector.uid,\n }\n })\n\n // Set recent connector if exists\n {\n const current = config.state.current\n if (!current) return\n const connector = config.state.connections.get(current)?.connector\n if (!connector) return\n await config.storage?.setItem('recentConnectorId', connector.id)\n }\n}\n","////////////////////////////////////////////////////////////////////////////////\n// Actions\n////////////////////////////////////////////////////////////////////////////////\n\n// biome-ignore lint/performance/noBarrelFile: entrypoint module\nexport {\n type CallErrorType,\n type CallParameters,\n type CallReturnType,\n call,\n} from '../actions/call.js'\n\nexport {\n type ConnectErrorType,\n type ConnectParameters,\n type ConnectReturnType,\n connect,\n} from '../actions/connect.js'\n\nexport {\n type DeployContractErrorType,\n type DeployContractParameters,\n type DeployContractReturnType,\n deployContract,\n} from '../actions/deployContract.js'\n\nexport {\n type DisconnectErrorType,\n type DisconnectParameters,\n type DisconnectReturnType,\n disconnect,\n} from '../actions/disconnect.js'\nexport {\n type EstimateFeesPerGasErrorType,\n type EstimateFeesPerGasParameters,\n type EstimateFeesPerGasReturnType,\n estimateFeesPerGas,\n} from '../actions/estimateFeesPerGas.js'\nexport {\n type EstimateGasErrorType,\n type EstimateGasParameters,\n type EstimateGasReturnType,\n estimateGas,\n} from '../actions/estimateGas.js'\n\nexport {\n type EstimateMaxPriorityFeePerGasErrorType,\n type EstimateMaxPriorityFeePerGasParameters,\n type EstimateMaxPriorityFeePerGasReturnType,\n estimateMaxPriorityFeePerGas,\n} from '../actions/estimateMaxPriorityFeePerGas.js'\n\nexport {\n type GetAccountReturnType,\n getAccount,\n} from '../actions/getAccount.js'\n\nexport {\n type GetBalanceErrorType,\n type GetBalanceParameters,\n type GetBalanceReturnType,\n getBalance,\n /** @deprecated use `getBalance` instead */\n getBalance as fetchBalance,\n} from '../actions/getBalance.js'\n\nexport {\n type GetBlockErrorType,\n type GetBlockParameters,\n type GetBlockReturnType,\n getBlock,\n} from '../actions/getBlock.js'\n\nexport {\n type GetBlockNumberErrorType,\n type GetBlockNumberParameters,\n type GetBlockNumberReturnType,\n getBlockNumber,\n /** @deprecated use `getBlockNumber` instead */\n getBlockNumber as fetchBlockNumber,\n} from '../actions/getBlockNumber.js'\n\nexport {\n type GetBlockTransactionCountErrorType,\n type GetBlockTransactionCountParameters,\n type GetBlockTransactionCountReturnType,\n getBlockTransactionCount,\n} from '../actions/getBlockTransactionCount.js'\n\nexport {\n type GetBytecodeErrorType,\n type GetBytecodeParameters,\n type GetBytecodeReturnType,\n getBytecode,\n} from '../actions/getBytecode.js'\n\nexport {\n type GetCallsStatusErrorType,\n type GetCallsStatusParameters,\n type GetCallsStatusReturnType,\n getCallsStatus,\n} from '../actions/getCallsStatus.js'\n\nexport {\n type GetCapabilitiesErrorType,\n type GetCapabilitiesParameters,\n type GetCapabilitiesReturnType,\n getCapabilities,\n} from '../actions/getCapabilities.js'\n\nexport {\n type GetChainIdReturnType,\n getChainId,\n} from '../actions/getChainId.js'\n\nexport {\n type GetChainsReturnType,\n getChains,\n} from '../actions/getChains.js'\n\nexport {\n type GetClientParameters,\n type GetClientReturnType,\n getClient,\n} from '../actions/getClient.js'\n\nexport {\n type GetConnectionsReturnType,\n getConnections,\n} from '../actions/getConnections.js'\nexport {\n type GetConnectorClientErrorType,\n type GetConnectorClientParameters,\n type GetConnectorClientReturnType,\n getConnectorClient,\n} from '../actions/getConnectorClient.js'\nexport {\n type GetConnectorsReturnType,\n getConnectors,\n} from '../actions/getConnectors.js'\n\nexport {\n type GetEnsAddressErrorType,\n type GetEnsAddressParameters,\n type GetEnsAddressReturnType,\n getEnsAddress,\n /** @deprecated use `getEnsAddress` instead */\n getEnsAddress as fetchEnsAddress,\n} from '../actions/getEnsAddress.js'\n\nexport {\n type GetEnsAvatarErrorType,\n type GetEnsAvatarParameters,\n type GetEnsAvatarReturnType,\n getEnsAvatar,\n /** @deprecated use `getEnsAvatar` instead */\n getEnsAvatar as fetchEnsAvatar,\n} from '../actions/getEnsAvatar.js'\n\nexport {\n type GetEnsNameErrorType,\n type GetEnsNameParameters,\n type GetEnsNameReturnType,\n getEnsName,\n /** @deprecated */\n getEnsName as fetchEnsName,\n} from '../actions/getEnsName.js'\n\nexport {\n type GetEnsResolverErrorType,\n type GetEnsResolverParameters,\n type GetEnsResolverReturnType,\n getEnsResolver,\n /** @deprecated use `getEnsResolver` instead */\n getEnsResolver as fetchEnsResolver,\n} from '../actions/getEnsResolver.js'\n\nexport {\n type GetEnsTextErrorType,\n type GetEnsTextParameters,\n type GetEnsTextReturnType,\n getEnsText,\n} from '../actions/getEnsText.js'\n\nexport {\n type GetFeeHistoryErrorType,\n type GetFeeHistoryParameters,\n type GetFeeHistoryReturnType,\n getFeeHistory,\n} from '../actions/getFeeHistory.js'\n\nexport {\n type GetGasPriceErrorType,\n type GetGasPriceParameters,\n type GetGasPriceReturnType,\n getGasPrice,\n} from '../actions/getGasPrice.js'\n\nexport {\n type GetProofErrorType,\n type GetProofParameters,\n type GetProofReturnType,\n getProof,\n} from '../actions/getProof.js'\n\nexport {\n type GetPublicClientParameters,\n type GetPublicClientReturnType,\n getPublicClient,\n} from '../actions/getPublicClient.js'\n\nexport {\n type GetStorageAtErrorType,\n type GetStorageAtParameters,\n type GetStorageAtReturnType,\n getStorageAt,\n} from '../actions/getStorageAt.js'\n\nexport {\n type GetTokenErrorType,\n type GetTokenParameters,\n type GetTokenReturnType,\n getToken,\n /** @deprecated use `getToken` instead */\n getToken as fetchToken,\n} from '../actions/getToken.js'\n\nexport {\n type GetTransactionErrorType,\n type GetTransactionParameters,\n type GetTransactionReturnType,\n getTransaction,\n /** @deprecated use `getTransaction` instead */\n getTransaction as fetchTransaction,\n} from '../actions/getTransaction.js'\n\nexport {\n type GetTransactionConfirmationsErrorType,\n type GetTransactionConfirmationsParameters,\n type GetTransactionConfirmationsReturnType,\n getTransactionConfirmations,\n} from '../actions/getTransactionConfirmations.js'\n\nexport {\n type GetTransactionCountErrorType,\n type GetTransactionCountParameters,\n type GetTransactionCountReturnType,\n getTransactionCount,\n} from '../actions/getTransactionCount.js'\n\nexport {\n type GetTransactionReceiptErrorType,\n type GetTransactionReceiptParameters,\n type GetTransactionReceiptReturnType,\n getTransactionReceipt,\n} from '../actions/getTransactionReceipt.js'\n\nexport {\n type GetWalletClientErrorType,\n type GetWalletClientParameters,\n type GetWalletClientReturnType,\n getWalletClient,\n} from '../actions/getWalletClient.js'\n\nexport {\n type MulticallParameters,\n type MulticallReturnType,\n multicall,\n} from '../actions/multicall.js'\n\nexport {\n type PrepareTransactionRequestErrorType,\n type PrepareTransactionRequestParameters,\n type PrepareTransactionRequestReturnType,\n prepareTransactionRequest,\n} from '../actions/prepareTransactionRequest.js'\n\nexport {\n type ReadContractErrorType,\n type ReadContractParameters,\n type ReadContractReturnType,\n readContract,\n} from '../actions/readContract.js'\n\nexport {\n type ReadContractsErrorType,\n type ReadContractsParameters,\n type ReadContractsReturnType,\n readContracts,\n} from '../actions/readContracts.js'\n\nexport {\n type ReconnectErrorType,\n type ReconnectParameters,\n type ReconnectReturnType,\n reconnect,\n} from '../actions/reconnect.js'\n\nexport {\n type SendCallsErrorType,\n type SendCallsParameters,\n type SendCallsReturnType,\n sendCalls,\n} from '../actions/sendCalls.js'\n\nexport {\n type SendCallsSyncErrorType,\n type SendCallsSyncParameters,\n type SendCallsSyncReturnType,\n sendCallsSync,\n} from '../actions/sendCallsSync.js'\n\nexport {\n type SendTransactionErrorType,\n type SendTransactionParameters,\n type SendTransactionReturnType,\n sendTransaction,\n} from '../actions/sendTransaction.js'\n\nexport {\n type SendTransactionSyncErrorType,\n type SendTransactionSyncParameters,\n type SendTransactionSyncReturnType,\n sendTransactionSync,\n} from '../actions/sendTransactionSync.js'\n\nexport {\n type ShowCallsStatusErrorType,\n type ShowCallsStatusParameters,\n type ShowCallsStatusReturnType,\n showCallsStatus,\n} from '../actions/showCallsStatus.js'\n\nexport {\n type SignMessageErrorType,\n type SignMessageParameters,\n type SignMessageReturnType,\n signMessage,\n} from '../actions/signMessage.js'\n\nexport {\n type SignTypedDataErrorType,\n type SignTypedDataParameters,\n type SignTypedDataReturnType,\n signTypedData,\n} from '../actions/signTypedData.js'\n\nexport {\n type SimulateContractErrorType,\n type SimulateContractParameters,\n type SimulateContractReturnType,\n simulateContract,\n} from '../actions/simulateContract.js'\n\nexport {\n type SwitchAccountErrorType,\n type SwitchAccountParameters,\n type SwitchAccountReturnType,\n switchAccount,\n} from '../actions/switchAccount.js'\n\nexport {\n type SwitchChainErrorType,\n type SwitchChainParameters,\n type SwitchChainReturnType,\n switchChain,\n /** @deprecated use `switchChain` instead */\n switchChain as switchNetwork,\n} from '../actions/switchChain.js'\n\nexport {\n type VerifyMessageErrorType,\n type VerifyMessageParameters,\n type VerifyMessageReturnType,\n verifyMessage,\n} from '../actions/verifyMessage.js'\n\nexport {\n type VerifyTypedDataErrorType,\n type VerifyTypedDataParameters,\n type VerifyTypedDataReturnType,\n verifyTypedData,\n} from '../actions/verifyTypedData.js'\n\nexport {\n type WaitForCallsStatusErrorType,\n type WaitForCallsStatusParameters,\n type WaitForCallsStatusReturnType,\n waitForCallsStatus,\n} from '../actions/waitForCallsStatus.js'\nexport {\n type WaitForTransactionReceiptErrorType,\n type WaitForTransactionReceiptParameters,\n type WaitForTransactionReceiptReturnType,\n waitForTransactionReceipt,\n /** @deprecated use `waitForTransactionReceipt` instead */\n waitForTransactionReceipt as waitForTransaction,\n} from '../actions/waitForTransactionReceipt.js'\nexport {\n type WatchAccountParameters,\n type WatchAccountReturnType,\n watchAccount,\n} from '../actions/watchAccount.js'\nexport {\n type WatchAssetErrorType,\n type WatchAssetParameters,\n type WatchAssetReturnType,\n watchAsset,\n} from '../actions/watchAsset.js'\n\nexport {\n type WatchBlockNumberParameters,\n type WatchBlockNumberReturnType,\n watchBlockNumber,\n} from '../actions/watchBlockNumber.js'\nexport {\n type WatchBlocksParameters,\n type WatchBlocksReturnType,\n watchBlocks,\n} from '../actions/watchBlocks.js'\nexport {\n type WatchChainIdParameters,\n type WatchChainIdReturnType,\n watchChainId,\n} from '../actions/watchChainId.js'\nexport {\n type WatchClientParameters,\n type WatchClientReturnType,\n watchClient,\n} from '../actions/watchClient.js'\nexport {\n type WatchConnectionsParameters,\n type WatchConnectionsReturnType,\n watchConnections,\n} from '../actions/watchConnections.js'\nexport {\n type WatchConnectorsParameters,\n type WatchConnectorsReturnType,\n watchConnectors,\n} from '../actions/watchConnectors.js'\nexport {\n type WatchContractEventParameters,\n type WatchContractEventReturnType,\n watchContractEvent,\n} from '../actions/watchContractEvent.js'\nexport {\n type WatchPendingTransactionsParameters,\n type WatchPendingTransactionsReturnType,\n watchPendingTransactions,\n} from '../actions/watchPendingTransactions.js'\nexport {\n type WatchPublicClientParameters,\n type WatchPublicClientReturnType,\n watchPublicClient,\n} from '../actions/watchPublicClient.js'\n\nexport {\n type WriteContractErrorType,\n type WriteContractParameters,\n type WriteContractReturnType,\n writeContract,\n} from '../actions/writeContract.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Connectors\n////////////////////////////////////////////////////////////////////////////////\n\nexport {\n type ConnectorEventMap,\n type CreateConnectorFn,\n createConnector,\n} from '../connectors/createConnector.js'\n\nexport {\n type InjectedParameters,\n injected,\n} from '../connectors/injected.js'\n\nexport {\n type MockParameters,\n mock,\n} from '../connectors/mock.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// createConfig\n////////////////////////////////////////////////////////////////////////////////\n\nexport {\n type Config,\n type Connection,\n type Connector,\n type CreateConfigParameters,\n createConfig,\n type PartializedState,\n type State,\n type Transport,\n} from '../createConfig.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// createStorage\n////////////////////////////////////////////////////////////////////////////////\n\nexport {\n type CreateStorageParameters,\n createStorage,\n noopStorage,\n type Storage,\n type StorageItemMap,\n} from '../createStorage.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Hydrate\n////////////////////////////////////////////////////////////////////////////////\n\nexport { hydrate } from '../hydrate.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Errors\n////////////////////////////////////////////////////////////////////////////////\n\nexport { BaseError } from '../errors/base.js'\n\nexport {\n ChainNotConfiguredError,\n type ChainNotConfiguredErrorType,\n ConnectorAccountNotFoundError,\n type ConnectorAccountNotFoundErrorType,\n ConnectorAlreadyConnectedError,\n type ConnectorAlreadyConnectedErrorType,\n ConnectorChainMismatchError,\n type ConnectorChainMismatchErrorType,\n ConnectorNotConnectedError,\n type ConnectorNotConnectedErrorType,\n ConnectorNotFoundError,\n type ConnectorNotFoundErrorType,\n ConnectorUnavailableReconnectingError,\n type ConnectorUnavailableReconnectingErrorType,\n} from '../errors/config.js'\n\nexport {\n ProviderNotFoundError,\n type ProviderNotFoundErrorType,\n SwitchChainNotSupportedError,\n type SwitchChainNotSupportedErrorType,\n} from '../errors/connector.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Transports\n////////////////////////////////////////////////////////////////////////////////\n\nexport { custom, http, webSocket } from 'viem'\n\nexport {\n type ConnectorTransport,\n type ConnectorTransportConfig,\n unstable_connector,\n} from '../transports/connector.js'\n\nexport { fallback } from '../transports/fallback.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Types\n////////////////////////////////////////////////////////////////////////////////\n\nexport type { SelectChains } from '../types/chain.js'\n\nexport type { Register, ResolvedRegister } from '../types/register.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Utilities\n////////////////////////////////////////////////////////////////////////////////\n\nexport {\n cookieStorage,\n cookieToInitialState,\n parseCookie,\n} from '../utils/cookie.js'\n\nexport { deepEqual } from '../utils/deepEqual.js'\n\nexport { deserialize } from '../utils/deserialize.js'\n\nexport { extractRpcUrls } from '../utils/extractRpcUrls.js'\n\nexport { normalizeChainId } from '../utils/normalizeChainId.js'\n\nexport { serialize } from '../utils/serialize.js'\n\n////////////////////////////////////////////////////////////////////////////////\n// Version\n////////////////////////////////////////////////////////////////////////////////\n\nexport { version } from '../version.js'\n","import { disconnect, type Config } from '@wagmi/core';\nimport type { Connector } from '@wagmi/core';\nimport { logger } from './logger';\n\n/**\n * Fully tears down the wagmi session so a page refresh does not auto-reconnect.\n * Falls back to clearing persisted storage when connector.disconnect() fails.\n */\nexport async function forceWagmiSessionClear(\n config: Config,\n connector?: Connector | null,\n): Promise<void> {\n const connectorId = connector?.id;\n let disconnectSucceeded = false;\n\n try {\n await disconnect(config);\n disconnectSucceeded = true;\n } catch (err) {\n logger.warn('[forceWagmiSessionClear] disconnect() failed:', err);\n }\n\n if (connectorId && config.storage && !disconnectSucceeded) {\n try {\n await config.storage.setItem(`${connectorId}.disconnected`, true);\n } catch (err) {\n logger.warn('[forceWagmiSessionClear] failed to set disconnected shim:', err);\n }\n }\n\n try {\n await config.storage?.removeItem('recentConnectorId');\n } catch {\n /* non-fatal */\n }\n\n config.setState((state) => ({\n ...state,\n connections: new Map(),\n current: null,\n status: 'disconnected',\n }));\n\n // Do not call wallet_revokePermissions — it breaks immediate reconnect without refresh.\n}\n","import { useCallback } from 'react';\nimport { useAccount } from 'wagmi';\nimport { logger } from '../../lib/logger';\nimport { resolveConnectedProvider } from '../../lib/ethereum';\nimport { CotiPluginError, CotiErrorCode } from '../../errors';\nimport { clearAesKeyValidatedForUnlock, getValidatedAesKeyForUnlock } from '../../crypto/aesKeyValidation';\nimport {\n getInitialPrivateTokens,\n} from '../../hooks/usePrivacyBridge';\nimport { useWalletType } from '../../hooks/useWalletType';\nimport type { PrivacyBridgeAccountSync } from './usePrivacyBridgeAccountSync';\nimport type { PrivacyBridgeNetworkSession } from './usePrivacyBridgeNetworkSession';\nimport type { PrivacyBridgeSessionCore } from './sessionShared';\nimport type { AesKeyProviderOptions } from '../../hooks/useAesKeyProvider';\nimport { normalizeAesKey } from '../../crypto/aesKey';\nimport { resolveAesKeyChainId } from '../../lib/aesAccessStrategy';\nimport { persistEncryptedAesBackup } from '../../lib/persistEncryptedAesBackup';\nimport {\n type AesUnlockPlan,\n buildUnlockPlanFromStrategy,\n resolveAesAccessStrategy,\n resolveRestoreAesAccessStrategy,\n shouldUseLocalCrypto,\n shouldUseSnapCrypto,\n} from '../../lib/aesAccessStrategy';\nimport {\n sendPrivateTokenTransfer,\n type ExecutePrivateTokenTransferResult,\n} from '../../hooks/privacyBridge/executePrivateTokenTransfer';\nimport {\n decryptPrivateCtUint256,\n encryptPrivateCtUint256,\n parseCtUint256Json,\n parsePrivateAmountToWei,\n formatPrivateAmountFromWei,\n serializeCtUint256,\n} from '../../hooks/privacyBridge/privateValueCrypto';\n\ninterface UsePrivacyBridgeUnlockSessionOptions {\n core: PrivacyBridgeSessionCore;\n network: PrivacyBridgeNetworkSession;\n accountSync: PrivacyBridgeAccountSync;\n}\n\n/** Snap/AES unlock, private balance refresh, and hard lock flows. */\nexport const usePrivacyBridgeUnlockSession = ({\n core,\n network,\n accountSync,\n}: UsePrivacyBridgeUnlockSessionOptions) => {\n const {\n walletAddress,\n sessionAesKey,\n setSnapError,\n setSessionAesKey,\n aesKeyChainId,\n setAesKeyChainId,\n arePrivateBalancesHidden,\n setArePrivateBalancesHidden,\n handleManualOnboarding,\n handleKeyVerification,\n clearSnapCache,\n setPrivateTokens,\n wagmiSyncRef,\n hasAesKeyInSnap,\n checkSnapStatus,\n getAESKeyFromSnap,\n encryptUint256ViaSnap,\n decryptCtUint256ViaSnap,\n } = core;\n\n const { wagmiChainId } = network;\n const { updateAccountState, currentChainId } = accountSync;\n const walletTypeInfo = useWalletType();\n // Connector for the wallet the user selected via RainbowKit/wagmi — used to\n // resolve the EIP-1193 provider instead of window.ethereum, which is\n // unreliable when multiple wallet extensions are installed.\n const { connector } = useAccount();\n\n const commitAesKeyUnlock = async (key: string): Promise<void> => {\n if (!walletAddress) throw new Error('Connect your wallet first.');\n\n const chainOverride = wagmiSyncRef.current ? wagmiChainId : undefined;\n try {\n const success = await updateAccountState(walletAddress, true, true, key, chainOverride);\n if (!success) {\n throw new Error('Could not unlock private balances. Try again.');\n }\n setSessionAesKey(key, walletAddress);\n setSnapError(null);\n setArePrivateBalancesHidden(false);\n } catch (err: unknown) {\n if (\n err instanceof CotiPluginError\n && (err.code === CotiErrorCode.AES_KEY_MISMATCH\n || err.code === CotiErrorCode.ACCOUNT_NOT_ONBOARDED)\n ) {\n setSessionAesKey(null);\n clearAesKeyValidatedForUnlock(walletAddress);\n clearSnapCache();\n setArePrivateBalancesHidden(true);\n }\n throw err;\n }\n };\n\n const handleOnboard = async () => {\n const key = await handleManualOnboarding();\n if (!key || !walletAddress) return key;\n\n await commitAesKeyUnlock(key);\n return key;\n };\n\n const saveManualAesKey = async (\n aesKey: string,\n options?: Pick<AesKeyProviderOptions, 'saveBackup' | 'onProgress'>,\n ): Promise<{ backupWarning?: string; backupCancelled?: boolean }> => {\n if (!walletAddress) throw new Error('Connect your wallet first.');\n\n // Normalize and validate in-memory only — no localStorage persistence unless saveBackup is enabled.\n let key: string;\n try {\n key = normalizeAesKey(aesKey.trim());\n } catch {\n throw new Error('AES key must be 32 hexadecimal characters.');\n }\n\n await commitAesKeyUnlock(key);\n\n if (options?.saveBackup && connector) {\n const targetChainId = resolveAesKeyChainId(\n wagmiSyncRef.current ? wagmiChainId : Number(currentChainId),\n aesKeyChainId,\n );\n const backupResult = await persistEncryptedAesBackup({\n aesKey: key,\n address: walletAddress,\n chainId: targetChainId,\n connector,\n onBeforeSign: () => options.onProgress?.('signing-backup'),\n });\n options.onProgress?.('idle');\n\n if (backupResult.status === 'failed') {\n logger.warn(\n 'Manual AES unlock succeeded but encrypted backup save failed:',\n backupResult.message,\n );\n return {\n backupWarning: `Encrypted backup was not saved. ${backupResult.message}`,\n };\n } else if (backupResult.status === 'cancelled') {\n logger.warn('Manual AES unlock succeeded but encrypted backup save was cancelled.');\n return {\n backupWarning: 'Encrypted backup save was cancelled. Your key works for this session.',\n backupCancelled: true,\n };\n }\n }\n return {};\n };\n\n const refreshPublicBalances = useCallback(async () => {\n if (!walletAddress) return false;\n\n logger.log('Triggering public balance fetch...');\n try {\n const chainOverride = wagmiSyncRef.current ? wagmiChainId : undefined;\n return await updateAccountState(walletAddress, false, false, undefined, chainOverride);\n } catch (err: unknown) {\n logger.warn('Public balance fetch failed', err);\n return false;\n }\n }, [walletAddress, updateAccountState, wagmiChainId, wagmiSyncRef]);\n\n const resolveSessionAesKey = useCallback((): string | undefined => {\n return sessionAesKey\n ?? (walletAddress ? getValidatedAesKeyForUnlock(walletAddress) ?? undefined : undefined);\n }, [sessionAesKey, walletAddress]);\n\n const resolveAesAccess = useCallback(async (overrideAesKeyChainId?: number) => {\n if (!walletAddress) {\n throw new Error('Wallet not connected');\n }\n\n const chainIdNum = Number(currentChainId);\n if (!Number.isFinite(chainIdNum) || chainIdNum <= 0) {\n throw new Error('Network not available');\n }\n\n const isMetaMask = walletTypeInfo.walletType === 'metamask';\n const snapInstalled = isMetaMask ? await checkSnapStatus() : false;\n\n return resolveAesAccessStrategy({\n address: walletAddress,\n chainId: chainIdNum,\n aesKeyChainId: overrideAesKeyChainId ?? aesKeyChainId,\n snapInstalled,\n sessionAesKey: resolveSessionAesKey(),\n hasAesKeyInSnap,\n confirmSnapInstalled: isMetaMask ? checkSnapStatus : undefined,\n });\n }, [\n currentChainId,\n aesKeyChainId,\n checkSnapStatus,\n hasAesKeyInSnap,\n resolveSessionAesKey,\n walletAddress,\n walletTypeInfo.walletType,\n ]);\n\n const resolveRestoreUnlockPlan = useCallback(async (\n aesKeyOptions?: AesKeyProviderOptions,\n ): Promise<AesUnlockPlan & { failed?: true }> => {\n if (!walletAddress) {\n return {\n unlockOptions: { validateOnUnlock: true as const, ...aesKeyOptions },\n checkSnap: true,\n keyForUnlock: undefined,\n failed: true as const,\n };\n }\n\n const unlockOptions = { validateOnUnlock: true as const, ...aesKeyOptions };\n if (aesKeyOptions?.forceContractOnboarding) {\n return {\n unlockOptions,\n checkSnap: true,\n keyForUnlock: undefined,\n accessMode: 'onboard' as const,\n };\n }\n\n const sessionKey = resolveSessionAesKey();\n\n const chainIdNum = Number(currentChainId);\n if (!Number.isFinite(chainIdNum) || chainIdNum <= 0) {\n return {\n unlockOptions,\n checkSnap: true,\n keyForUnlock: sessionKey,\n failed: true as const,\n };\n }\n\n const isMetaMask = walletTypeInfo.walletType === 'metamask';\n const strategy = aesKeyOptions?.restoreOnly\n ? await resolveRestoreAesAccessStrategy({\n address: walletAddress,\n chainId: chainIdNum,\n aesKeyChainId: aesKeyOptions?.aesKeyChainId ?? aesKeyChainId,\n snapInstalled: isMetaMask ? await checkSnapStatus() : false,\n sessionAesKey: resolveSessionAesKey(),\n hasAesKeyInSnap,\n confirmSnapInstalled: isMetaMask ? checkSnapStatus : undefined,\n })\n : await resolveAesAccess(aesKeyOptions?.aesKeyChainId);\n return buildUnlockPlanFromStrategy(strategy, unlockOptions, sessionKey);\n }, [resolveAesAccess, resolveSessionAesKey, walletAddress, aesKeyChainId, checkSnapStatus, hasAesKeyInSnap, walletTypeInfo.walletType, currentChainId]);\n\n const refreshPrivateBalances = useCallback(async (aesKeyOptions?: AesKeyProviderOptions) => {\n if (!walletAddress) return false;\n\n logger.log('Triggering private balance fetch...');\n try {\n const chainOverride = wagmiSyncRef.current ? wagmiChainId : undefined;\n const plan = await resolveRestoreUnlockPlan(aesKeyOptions);\n if (plan.failed === true) {\n return false;\n }\n const {\n unlockOptions,\n checkSnap,\n keyForUnlock: initialKeyForUnlock,\n accessMode,\n } = plan;\n let keyForUnlock = initialKeyForUnlock;\n\n if (\n aesKeyOptions?.restoreOnly\n && accessMode === 'onboard'\n && !keyForUnlock\n ) {\n logger.log('Restore-only probe: account needs onboarding — skipping balance fetch');\n return false;\n }\n\n let success = await updateAccountState(\n walletAddress,\n checkSnap,\n true,\n keyForUnlock,\n chainOverride,\n unlockOptions,\n );\n logger.log('Private balance fetch completed', { success });\n\n if (!success) {\n if (aesKeyOptions?.forceContractOnboarding) {\n logger.log('Forced contract onboarding did not complete — skipping interactive retry');\n return false;\n }\n\n if (aesKeyOptions?.restoreOnly) {\n logger.log('Restore-only unlock did not complete — skipping retry');\n return false;\n }\n\n keyForUnlock =\n keyForUnlock ?? getValidatedAesKeyForUnlock(walletAddress) ?? undefined;\n logger.log('First private balance fetch failed, retrying after 1.5s');\n await new Promise(resolve => setTimeout(resolve, 1500));\n success = await updateAccountState(\n walletAddress,\n false,\n true,\n keyForUnlock,\n chainOverride,\n unlockOptions,\n );\n logger.log('Retry private balance fetch completed', { success });\n }\n\n if (success) {\n setArePrivateBalancesHidden(false);\n setSnapError(null);\n }\n return success;\n } catch (err: unknown) {\n const errorInfo = err as { code?: number | string; name?: string; message?: string };\n logger.log('Unlock logic caught error', { code: errorInfo.code, name: errorInfo.name });\n\n if (\n err instanceof CotiPluginError\n && (err.code === CotiErrorCode.SNAP_CONNECT_FAILED\n || err.code === CotiErrorCode.SNAP_KEY_CHECK_FAILED)\n ) {\n throw err;\n }\n\n if (errorInfo.message === 'SNAP_CONNECT_FAILED' || errorInfo.message?.includes('SNAP_CONNECT_FAILED')) {\n throw new CotiPluginError(\n CotiErrorCode.SNAP_REQUIRED,\n 'Snap connection failed — install or reconnect the COTI Snap.',\n errorInfo.message,\n );\n }\n\n if (\n errorInfo.code === 4001 ||\n errorInfo.message?.includes('User rejected') ||\n errorInfo.message?.includes('rejected the request')\n ) {\n return false;\n }\n\n if (\n errorInfo.message === 'SNAP_DIALOG_REJECTED' ||\n (err instanceof CotiPluginError && err.code === CotiErrorCode.SNAP_DIALOG_REJECTED)\n ) {\n if (err instanceof CotiPluginError) throw err;\n throw new CotiPluginError(\n CotiErrorCode.SNAP_DIALOG_REJECTED,\n 'User dismissed the Snap dialog.',\n );\n }\n\n if (errorInfo.message?.includes('ACCOUNT_NOT_ONBOARDED')) {\n setSessionAesKey(null);\n clearAesKeyValidatedForUnlock(walletAddress);\n clearSnapCache();\n setArePrivateBalancesHidden(true);\n throw new CotiPluginError(\n CotiErrorCode.ACCOUNT_NOT_ONBOARDED,\n 'Account has not been onboarded to the COTI network.',\n errorInfo.message,\n );\n }\n\n if (\n err instanceof CotiPluginError && err.code === CotiErrorCode.AES_KEY_MISMATCH\n ) {\n setSessionAesKey(null);\n clearAesKeyValidatedForUnlock(walletAddress);\n clearSnapCache();\n setArePrivateBalancesHidden(true);\n throw err;\n }\n\n if (errorInfo.message?.includes('AES key') || errorInfo.message?.includes('onboarding')) {\n setSessionAesKey(null);\n clearAesKeyValidatedForUnlock(walletAddress);\n clearSnapCache();\n setArePrivateBalancesHidden(true);\n throw new CotiPluginError(\n CotiErrorCode.AES_KEY_MISMATCH,\n 'AES key mismatch or onboarding error.',\n errorInfo.message,\n );\n }\n return false;\n }\n }, [\n walletAddress,\n updateAccountState,\n wagmiChainId,\n clearSnapCache,\n setSessionAesKey,\n setArePrivateBalancesHidden,\n setSnapError,\n wagmiSyncRef,\n resolveRestoreUnlockPlan,\n ]);\n\n const sendPrivateToken = useCallback(async (params: {\n symbol: string;\n recipient: string;\n amount: string;\n }): Promise<ExecutePrivateTokenTransferResult> => {\n if (!walletAddress) {\n throw new Error('Wallet not connected');\n }\n if (arePrivateBalancesHidden) {\n throw new Error('Private balances are locked. Unlock to send tokens.');\n }\n\n const chainIdNum = Number(currentChainId);\n if (!Number.isFinite(chainIdNum) || chainIdNum <= 0) {\n throw new Error('Network not available');\n }\n\n const strategy = await resolveAesAccess();\n const sessionKey = resolveSessionAesKey();\n const provider = await resolveConnectedProvider(connector);\n\n const result = await sendPrivateTokenTransfer({\n chainId: chainIdNum,\n symbol: params.symbol,\n recipient: params.recipient,\n amount: params.amount,\n walletAddress,\n provider,\n sessionAesKey: sessionKey,\n hasSnap: strategy.snapInstalled,\n getAESKeyFromSnap: strategy.snapInstalled ? getAESKeyFromSnap : undefined,\n });\n\n await refreshPrivateBalances();\n return result;\n }, [\n walletAddress,\n arePrivateBalancesHidden,\n currentChainId,\n connector,\n getAESKeyFromSnap,\n refreshPrivateBalances,\n resolveAesAccess,\n resolveSessionAesKey,\n ]);\n\n const encryptPrivateValue = useCallback(async (params: {\n amount: string;\n decimals?: number;\n }): Promise<{ ciphertext: string }> => {\n if (arePrivateBalancesHidden) {\n throw new Error('Private balances are locked. Unlock to encrypt values.');\n }\n\n const strategy = await resolveAesAccess();\n const sessionKey = resolveSessionAesKey();\n\n if (strategy.mode === 'onboard') {\n throw new Error('Unlock private balances before encrypting values.');\n }\n\n const decimals = params.decimals ?? 18;\n const chainIdNum = Number(currentChainId);\n const wei = parsePrivateAmountToWei(params.amount, decimals);\n\n if (shouldUseSnapCrypto(strategy)) {\n const ciphertext = await encryptUint256ViaSnap(wei, chainIdNum, walletAddress);\n if (!ciphertext) {\n throw new Error('Snap encrypt was cancelled or failed.');\n }\n return { ciphertext: serializeCtUint256(ciphertext) };\n }\n\n const localAesKey = shouldUseLocalCrypto(strategy, sessionKey) ? sessionKey : undefined;\n if (!localAesKey) {\n throw new Error('Unlock private balances before encrypting values.');\n }\n\n const encrypted = encryptPrivateCtUint256({\n amount: params.amount,\n decimals,\n aesKey: localAesKey,\n });\n return { ciphertext: serializeCtUint256(encrypted) };\n }, [\n arePrivateBalancesHidden,\n encryptUint256ViaSnap,\n currentChainId,\n resolveAesAccess,\n resolveSessionAesKey,\n walletAddress,\n ]);\n\n const decryptPrivateValue = useCallback(async (params: {\n ciphertext: string;\n decimals?: number;\n }): Promise<{ amount: string }> => {\n if (arePrivateBalancesHidden) {\n throw new Error('Private balances are locked. Unlock to decrypt values.');\n }\n\n const strategy = await resolveAesAccess();\n const sessionKey = resolveSessionAesKey();\n\n if (strategy.mode === 'onboard') {\n throw new Error('Unlock private balances before decrypting values.');\n }\n\n const decimals = params.decimals ?? 18;\n const chainIdNum = Number(currentChainId);\n const parsed = parseCtUint256Json(params.ciphertext);\n\n if (shouldUseSnapCrypto(strategy)) {\n const wei = await decryptCtUint256ViaSnap(parsed, chainIdNum, walletAddress);\n if (wei === null) {\n throw new Error('Snap decrypt was cancelled or failed.');\n }\n return { amount: formatPrivateAmountFromWei(wei, decimals) };\n }\n\n const localAesKey = shouldUseLocalCrypto(strategy, sessionKey) ? sessionKey : undefined;\n if (!localAesKey) {\n throw new Error('Unlock private balances before decrypting values.');\n }\n\n return {\n amount: decryptPrivateCtUint256({\n ciphertext: parsed,\n decimals,\n aesKey: localAesKey,\n }),\n };\n }, [\n arePrivateBalancesHidden,\n decryptCtUint256ViaSnap,\n currentChainId,\n resolveAesAccess,\n resolveSessionAesKey,\n walletAddress,\n ]);\n\n const lockPrivateBalances = () => {\n logger.log('Locking private balances (clearing session AES key)');\n setArePrivateBalancesHidden(true);\n setSessionAesKey(null);\n if (walletAddress) clearAesKeyValidatedForUnlock(walletAddress);\n // Snap-stored key is left intact; unlock re-routes via Snap / backup / onboard.\n setPrivateTokens(getInitialPrivateTokens(currentChainId));\n };\n\n const isPrivateUnlocked = !arePrivateBalancesHidden;\n\n return {\n handleOnboard,\n saveManualAesKey,\n refreshPublicBalances,\n refreshPrivateBalances,\n lockPrivateBalances,\n sendPrivateToken,\n encryptPrivateValue,\n decryptPrivateValue,\n isPrivateUnlocked,\n handleVerifyKeys: handleKeyVerification,\n aesKeyChainId,\n setAesKeyChainId,\n };\n};\n\nexport type PrivacyBridgeUnlockSession = ReturnType<typeof usePrivacyBridgeUnlockSession>;\n","import { ethers } from 'ethers';\nimport { encryptUint256 } from '@coti-io/coti-sdk-typescript';\nimport { decryptCtUint256 } from '../../crypto/decryption';\nimport type { CtUint256 } from '../../types/ciphertext';\nimport { isCtUint256 } from '../../types/ciphertext';\nimport { normalizeAesKeyHex } from './executePrivateTokenTransfer';\n\nexport function parsePrivateAmountToWei(amount: string, decimals: number): bigint {\n const trimmed = amount.trim();\n if (!trimmed) {\n throw new Error('Amount is required.');\n }\n return ethers.parseUnits(trimmed, decimals);\n}\n\nexport function formatPrivateAmountFromWei(value: bigint, decimals: number): string {\n return ethers.formatUnits(value, decimals);\n}\n\nexport function serializeCtUint256(ciphertext: CtUint256): string {\n if ('ciphertextHigh' in ciphertext && 'ciphertextLow' in ciphertext) {\n return JSON.stringify({\n ciphertextHigh: ciphertext.ciphertextHigh.toString(),\n ciphertextLow: ciphertext.ciphertextLow.toString(),\n });\n }\n\n return JSON.stringify({\n high: {\n high: ciphertext.high.high.toString(),\n low: ciphertext.high.low.toString(),\n },\n low: {\n high: ciphertext.low.high.toString(),\n low: ciphertext.low.low.toString(),\n },\n });\n}\n\nexport function parseCtUint256Json(raw: string): CtUint256 {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error('Ciphertext must be valid JSON.');\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new Error('Ciphertext JSON must be an object.');\n }\n\n const value = parsed as Record<string, unknown>;\n\n if ('ciphertextHigh' in value && 'ciphertextLow' in value) {\n const ciphertext: CtUint256 = {\n ciphertextHigh: BigInt(String(value.ciphertextHigh)),\n ciphertextLow: BigInt(String(value.ciphertextLow)),\n };\n if (!isCtUint256(ciphertext)) {\n throw new Error('Invalid flat ctUint256 ciphertext.');\n }\n return ciphertext;\n }\n\n if ('high' in value && 'low' in value) {\n const high = value.high as Record<string, unknown>;\n const low = value.low as Record<string, unknown>;\n const ciphertext: CtUint256 = {\n high: {\n high: BigInt(String(high.high)),\n low: BigInt(String(high.low)),\n },\n low: {\n high: BigInt(String(low.high)),\n low: BigInt(String(low.low)),\n },\n };\n if (!isCtUint256(ciphertext)) {\n throw new Error('Invalid nested ctUint256 ciphertext.');\n }\n return ciphertext;\n }\n\n throw new Error('Ciphertext JSON must contain flat or nested ctUint256 fields.');\n}\n\nexport function encryptPrivateCtUint256(params: {\n amount: string;\n decimals: number;\n aesKey: string;\n}): CtUint256 {\n const wei = parsePrivateAmountToWei(params.amount, params.decimals);\n return encryptUint256(wei, normalizeAesKeyHex(params.aesKey));\n}\n\nexport function decryptPrivateCtUint256(params: {\n ciphertext: CtUint256;\n decimals: number;\n aesKey: string;\n}): string {\n const wei = decryptCtUint256(params.ciphertext, normalizeAesKeyHex(params.aesKey), {\n decimals: params.decimals,\n });\n if (wei === null) {\n throw new Error('AES key mismatch or invalid ciphertext.');\n }\n return formatPrivateAmountFromWei(wei, params.decimals);\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { loadPodRequests, savePodRequests } from '../../pod/podPortalRequestsStorage';\nimport { type PodPortalRequest } from '../../contracts/pod';\nimport { resolvePodRequestStatus } from '../../chains/portal/podRequestStatus';\nimport { CHAIN_CONFIGS } from '../../chains/index';\nimport { logger } from '../../lib/logger';\nimport type { PrivacyBridgePodContextValue } from './types';\n\nconst POD_PORTAL_CHAIN_IDS = new Set(\n Object.values(CHAIN_CONFIGS)\n .filter(c => c.portalStrategy === 'pod-privacy-portal')\n .map(c => c.id),\n);\n\nconst TERMINAL_POD_STATUSES = new Set<PodPortalRequest['status']>([\n 'failed',\n 'callback-errored',\n 'burn-debt',\n]);\n\ninterface UsePrivacyBridgePodOptions {\n walletAddress: string;\n refreshPrivateBalances: () => Promise<boolean>;\n}\n\n/** PoD portal request persistence and polling. */\nexport const usePrivacyBridgePodState = ({\n walletAddress,\n refreshPrivateBalances,\n}: UsePrivacyBridgePodOptions): PrivacyBridgePodContextValue & {\n upsertPodRequest: (request: PodPortalRequest) => void;\n} => {\n const [podRequests, setPodRequests] = useState<PodPortalRequest[]>(() => loadPodRequests(''));\n const completedPodRefreshesRef = useRef<Set<string>>(new Set());\n const inFlightRefreshRef = useRef<Set<string>>(new Set());\n const podRequestsRef = useRef(podRequests);\n podRequestsRef.current = podRequests;\n\n const persistPodRequests = useCallback(\n (updater: (prev: PodPortalRequest[]) => PodPortalRequest[]) => {\n setPodRequests(prev => {\n const next = updater(prev);\n savePodRequests(walletAddress, next);\n return next;\n });\n },\n [walletAddress],\n );\n\n useEffect(() => {\n setPodRequests(loadPodRequests(walletAddress));\n }, [walletAddress]);\n\n const upsertPodRequest = useCallback(\n (request: PodPortalRequest) => {\n persistPodRequests(prev => {\n const i = prev.findIndex(r => r.id === request.id);\n if (i === -1) return [request, ...prev].slice(0, 20);\n const current = prev[i];\n const unchanged =\n current.status === request.status &&\n current.message === request.message &&\n current.requestId === request.requestId &&\n current.balanceRefreshPending === request.balanceRefreshPending;\n if (unchanged) return prev;\n const next = [...prev];\n next[i] = { ...request, updatedAt: Date.now() };\n return next;\n });\n },\n [persistPodRequests],\n );\n\n const updatePodRequest = useCallback(\n (id: string, patch: Partial<PodPortalRequest>) => {\n persistPodRequests(prev => {\n const i = prev.findIndex(r => r.id === id);\n if (i === -1) return prev;\n const current = prev[i];\n const nextFields = { ...current, ...patch };\n const unchanged =\n current.status === nextFields.status &&\n current.message === nextFields.message &&\n current.balanceRefreshPending === nextFields.balanceRefreshPending;\n if (unchanged) return prev;\n const next = [...prev];\n next[i] = { ...nextFields, updatedAt: Date.now() };\n return next;\n });\n },\n [persistPodRequests],\n );\n\n const refreshBalancesAfterPodCompletion = useCallback(\n async (requestId: string) => {\n if (completedPodRefreshesRef.current.has(requestId)) return;\n\n const attemptRefresh = async () => refreshPrivateBalances();\n\n try {\n let success = await attemptRefresh();\n if (!success) {\n await new Promise(resolve => setTimeout(resolve, 1500));\n success = await attemptRefresh();\n }\n\n if (success) {\n completedPodRefreshesRef.current.add(requestId);\n updatePodRequest(requestId, { balanceRefreshPending: false });\n return;\n }\n\n logger.warn('PoD completion balance refresh failed — will retry on next poll', { requestId });\n updatePodRequest(requestId, { balanceRefreshPending: true });\n } catch (e) {\n logger.warn('refreshBalancesAfterPodCompletion', e);\n updatePodRequest(requestId, { balanceRefreshPending: true });\n }\n },\n [refreshPrivateBalances, updatePodRequest],\n );\n\n const refreshBalancesAfterPodCompletionRef = useRef(refreshBalancesAfterPodCompletion);\n refreshBalancesAfterPodCompletionRef.current = refreshBalancesAfterPodCompletion;\n\n const refreshPodRequest = useCallback(\n async (request: PodPortalRequest) => {\n if (inFlightRefreshRef.current.has(request.id)) return;\n\n inFlightRefreshRef.current.add(request.id);\n try {\n const latest =\n podRequestsRef.current.find(r => r.id === request.id) ?? request;\n\n if (\n latest.status === 'succeeded' &&\n latest.balanceRefreshPending &&\n !completedPodRefreshesRef.current.has(latest.id)\n ) {\n await refreshBalancesAfterPodCompletionRef.current(latest.id);\n return;\n }\n\n const resolved = await resolvePodRequestStatus(latest);\n if (!resolved) return;\n\n if (resolved.status === latest.status && resolved.message === latest.message) {\n logger.debug(\"[PoD][poll] status unchanged\", {\n id: latest.id,\n status: latest.status,\n requestId: latest.requestId,\n message: latest.message,\n });\n return;\n }\n\n logger.log(\"[PoD][poll] status change\", {\n id: latest.id,\n requestId: latest.requestId,\n from: latest.status,\n to: resolved.status,\n message: resolved.message,\n });\n\n const shouldRefreshBalances =\n resolved.refreshPrivateBalances && !completedPodRefreshesRef.current.has(latest.id);\n\n updatePodRequest(latest.id, {\n status: resolved.status,\n message: resolved.message,\n balanceRefreshPending: shouldRefreshBalances ? true : latest.balanceRefreshPending,\n });\n\n if (shouldRefreshBalances) {\n await refreshBalancesAfterPodCompletionRef.current(latest.id);\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n if (message.includes('not found')) {\n updatePodRequest(request.id, {\n status: 'pod-pending',\n message: 'PoD request is waiting to be indexed.',\n });\n return;\n }\n logger.warn('refreshPodRequest', e);\n } finally {\n inFlightRefreshRef.current.delete(request.id);\n }\n },\n [updatePodRequest],\n );\n\n const refreshPodRequestRef = useRef(refreshPodRequest);\n refreshPodRequestRef.current = refreshPodRequest;\n\n const pollActiveRequests = useCallback(() => {\n if (!walletAddress) return;\n const active = podRequestsRef.current.filter(\n r =>\n POD_PORTAL_CHAIN_IDS.has(r.chainId) &&\n r.wallet.toLowerCase() === walletAddress.toLowerCase() &&\n (r.balanceRefreshPending ||\n (!TERMINAL_POD_STATUSES.has(r.status) && r.status !== 'succeeded')),\n );\n if (active.length === 0) return;\n active.forEach(r => {\n refreshPodRequestRef.current(r).catch(err =>\n logger.warn('refreshPodRequest poll failed', err),\n );\n });\n }, [walletAddress]);\n\n const activeRequestIdsRef = useRef('');\n\n useEffect(() => {\n if (!walletAddress) return;\n\n const active = podRequests.filter(\n r =>\n POD_PORTAL_CHAIN_IDS.has(r.chainId) &&\n r.wallet.toLowerCase() === walletAddress.toLowerCase() &&\n (r.balanceRefreshPending ||\n (!TERMINAL_POD_STATUSES.has(r.status) && r.status !== 'succeeded')),\n );\n const ids = active\n .map(r => r.id)\n .sort()\n .join(',');\n if (ids !== activeRequestIdsRef.current) {\n activeRequestIdsRef.current = ids;\n if (active.length > 0) pollActiveRequests();\n }\n }, [podRequests, walletAddress, pollActiveRequests]);\n\n useEffect(() => {\n if (!walletAddress) return;\n\n pollActiveRequests();\n const intervalId = setInterval(pollActiveRequests, 10_000);\n return () => clearInterval(intervalId);\n }, [walletAddress, pollActiveRequests]);\n\n return { podRequests, refreshPodRequest, upsertPodRequest };\n};\n","import { createContext, useContext } from 'react';\nimport type {\n PrivacyBridgeContextType,\n PrivacyBridgeModalsContextValue,\n PrivacyBridgeNetworkContextValue,\n PrivacyBridgePodContextValue,\n PrivacyBridgeSwapContextValue,\n PrivacyBridgeTokensContextValue,\n PrivacyBridgeUnlockContextValue,\n PrivacyBridgeWalletContextValue,\n} from './types';\n\nconst missingProvider = (name: string): never => {\n throw new Error(`${name} must be used within a PrivacyBridgeProvider`);\n};\n\n/** @deprecated Prefer bounded hooks; kept for existing consumers. */\nexport const PrivacyBridgeContext = createContext<PrivacyBridgeContextType | undefined>(undefined);\n\nexport const PrivacyBridgeWalletContext = createContext<PrivacyBridgeWalletContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgeNetworkContext = createContext<PrivacyBridgeNetworkContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgeUnlockContext = createContext<PrivacyBridgeUnlockContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgeTokensContext = createContext<PrivacyBridgeTokensContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgeSwapContext = createContext<PrivacyBridgeSwapContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgePodContext = createContext<PrivacyBridgePodContextValue | undefined>(\n undefined,\n);\nexport const PrivacyBridgeModalsContext = createContext<PrivacyBridgeModalsContextValue | undefined>(\n undefined,\n);\n\n/** Legacy flat accessor — unchanged API for existing apps. */\nexport const usePrivacyBridgeContext = (): PrivacyBridgeContextType => {\n const context = useContext(PrivacyBridgeContext);\n if (context === undefined) missingProvider('usePrivacyBridgeContext');\n return context!;\n};\n\n/** Wallet connection (connect, disconnect, address). */\nexport const usePrivacyBridgeWallet = (): PrivacyBridgeWalletContextValue => {\n const context = useContext(PrivacyBridgeWalletContext);\n if (context === undefined) missingProvider('usePrivacyBridgeWallet');\n return context!;\n};\n\n/** Network switching and enforcer state. */\nexport const usePrivacyBridgeNetwork = (): PrivacyBridgeNetworkContextValue => {\n const context = useContext(PrivacyBridgeNetworkContext);\n if (context === undefined) missingProvider('usePrivacyBridgeNetwork');\n return context!;\n};\n\n/** Snap, AES key, and private balance unlock flows. */\nexport const usePrivacyBridgeUnlock = (): PrivacyBridgeUnlockContextValue => {\n const context = useContext(PrivacyBridgeUnlockContext);\n if (context === undefined) missingProvider('usePrivacyBridgeUnlock');\n return context!;\n};\n\n/** Public and private token lists. */\nexport const usePrivacyBridgeTokens = (): PrivacyBridgeTokensContextValue => {\n const context = useContext(PrivacyBridgeTokensContext);\n if (context === undefined) missingProvider('usePrivacyBridgeTokens');\n return context!;\n};\n\n/** Swap form, bridge execution, gas, and approvals. */\nexport const usePrivacyBridgeSwap = (): PrivacyBridgeSwapContextValue => {\n const context = useContext(PrivacyBridgeSwapContext);\n if (context === undefined) missingProvider('usePrivacyBridgeSwap');\n return context!;\n};\n\n/** Sepolia PoD portal request tracker. */\nexport const usePrivacyBridgePod = (): PrivacyBridgePodContextValue => {\n const context = useContext(PrivacyBridgePodContext);\n if (context === undefined) missingProvider('usePrivacyBridgePod');\n return context!;\n};\n\n/** MetaMask install and multi-wallet conflict modals. */\nexport const usePrivacyBridgeModals = (): PrivacyBridgeModalsContextValue => {\n const context = useContext(PrivacyBridgeModalsContext);\n if (context === undefined) missingProvider('usePrivacyBridgeModals');\n return context!;\n};\n","import type { SwapProgressStage, Token } from '../../hooks/usePrivacyBridge';\nimport type { AesKeyProviderOptions } from '../../hooks/useAesKeyProvider';\nimport type { PodPortalRequest } from '../../contracts/pod';\n\n/** Wallet connection slice — connect/disconnect and address. */\nexport interface PrivacyBridgeWalletContextValue {\n isConnected: boolean;\n walletAddress: string;\n handleConnect: () => Promise<void>;\n handleDisconnect: () => Promise<void>;\n metamaskDetected: boolean;\n}\n\n/** Network slice — chain id, switching, and enforcer state. */\nexport interface PrivacyBridgeNetworkContextValue {\n chainId: string | null;\n switchNetwork: (chainId: string) => Promise<boolean>;\n networkName: string;\n isUnsupportedNetwork: boolean;\n isOffTargetNetwork: boolean;\n /** @deprecated Use isUnsupportedNetwork */\n isWrongNetwork: boolean;\n networkMismatchWarning: string | null;\n enforceNetwork: () => Promise<void>;\n COTI_MAINNET_ID: string;\n COTI_TESTNET_ID: string;\n SEPOLIA_ID: string;\n}\n\n/** Snap / AES unlock slice. */\nexport interface PrivacyBridgeUnlockContextValue {\n hasSnap: boolean;\n snapError: string | null;\n /** True/false when check succeeds; null when Snap is unavailable. */\n hasAesKeyInSnap: (accountAddress?: string) => Promise<boolean | null>;\n connectToSnap: () => Promise<boolean>;\n requestSnapConnection: () => Promise<boolean>;\n /** Probes Snap via wallet_getSnaps, updates hasSnap, and returns the result. */\n checkSnapStatus: () => Promise<boolean>;\n /** Session-bound AES key. Locking hides balances but may keep this key in memory. */\n sessionAesKey: string | null;\n /** COTI Testnet/Mainnet chain used for AES onboarding, Snap, and backup state. */\n aesKeyChainId: number | undefined;\n /** Set a session/connection AES key chain. Only COTI Testnet/Mainnet are accepted. */\n setAesKeyChainId: (chainId: number | undefined) => void;\n /** True when private balances are visible. This is not the same as key existence. */\n isPrivateUnlocked: boolean;\n sendPrivateToken: (params: {\n symbol: string;\n recipient: string;\n amount: string;\n }) => Promise<{ txHash: string }>;\n /** Encrypt a human-readable amount into ctUint256 JSON without exposing the AES key. */\n encryptPrivateValue: (params: {\n amount: string;\n decimals?: number;\n }) => Promise<{ ciphertext: string }>;\n /** Decrypt ctUint256 JSON back to a human-readable amount without exposing the AES key. */\n decryptPrivateValue: (params: {\n ciphertext: string;\n decimals?: number;\n }) => Promise<{ amount: string }>;\n /** Low-level balance/key refresh primitive. App UI should not orchestrate unlock with this. */\n refreshPrivateBalances: (options?: AesKeyProviderOptions) => Promise<boolean>;\n /** Last contract-onboarding error produced by the AES provider. */\n onboardingError: string | null;\n /** Last non-blocking onboarding warning produced by restore/backup flows. */\n onboardingWarning: string | null;\n /** Hides private balances and clears plaintext AES session state. */\n lockPrivateBalances: () => void;\n handleOnboard: () => Promise<string | null>;\n saveManualAesKey: (\n aesKey: string,\n options?: Pick<AesKeyProviderOptions, 'saveBackup' | 'onProgress'>,\n ) => Promise<{ backupWarning?: string; backupCancelled?: boolean }>;\n handleVerifyKeys: () => Promise<void>;\n showSnapMissingModal: boolean;\n setShowSnapMissingModal: (show: boolean) => void;\n showCotiWalletAesKeyModal: boolean;\n setShowCotiWalletAesKeyModal: (show: boolean) => void;\n}\n\n/** Token balances exposed to the UI. */\nexport interface PrivacyBridgeTokensContextValue {\n publicTokens: Token[];\n privateTokens: Token[];\n}\n\n/** Bridge / swap form and transaction slice. */\nexport interface PrivacyBridgeSwapContextValue {\n amount: string;\n direction: 'to-private' | 'to-public';\n selectedTokenIndex: number;\n setAmount: (amount: string) => void;\n setDirection: (direction: 'to-private' | 'to-public') => void;\n setSelectedTokenIndex: (index: number) => void;\n handleSwap: (\n amount?: string,\n direction?: 'to-private' | 'to-public',\n tokenIndex?: number,\n onProgress?: (stage: SwapProgressStage, txHash?: string) => void\n ) => Promise<void>;\n isBridgingLoading: boolean;\n isApprovalNeeded: boolean;\n isApproving: boolean;\n handleApprove: () => Promise<void>;\n estimatedGasFee: string | null;\n updateGasFee: () => Promise<void>;\n isGasEstimating: boolean;\n /** COTI bridge portal fee (COTI-denominated). Null on PoD chains. */\n portalFeeCoti: string | null;\n /** PoD Privacy Portal fee in native token (ETH/AVAX). Null on COTI chains. */\n portalFee: string | null;\n /** Native symbol for {@link portalFee} (e.g. ETH, AVAX). */\n portalFeeSymbol: string;\n /** PoD inbox fee paid via msg.value. Null on COTI chains. */\n podInboxFee: string | null;\n /** L1 execution gas estimate (wallet-paid). Null on COTI chains. */\n l1GasFee: string | null;\n /** True when connected chain uses pod-privacy-portal strategy. */\n isPodChain: boolean;\n feeDebugInfo: { cotiLastUpdated: string; tokenLastUpdated: string; blockTimestamp: string } | null;\n}\n\n/** PoD portal request tracking (Sepolia). */\nexport interface PrivacyBridgePodContextValue {\n podRequests: PodPortalRequest[];\n refreshPodRequest: (request: PodPortalRequest) => Promise<void>;\n}\n\n/** Install / conflict modals not tied to unlock flow. */\nexport interface PrivacyBridgeModalsContextValue {\n showInstallModal: boolean;\n setShowInstallModal: (show: boolean) => void;\n showMultipleWalletsModal: boolean;\n setShowMultipleWalletsModal: (show: boolean) => void;\n}\n\n/**\n * Legacy flat context — union of all slices.\n * Existing consumers should keep using {@link usePrivacyBridgeContext}.\n */\nexport type PrivacyBridgeContextType = PrivacyBridgeWalletContextValue &\n PrivacyBridgeNetworkContextValue &\n PrivacyBridgeUnlockContextValue &\n PrivacyBridgeTokensContextValue &\n PrivacyBridgeSwapContextValue &\n PrivacyBridgePodContextValue &\n PrivacyBridgeModalsContextValue;\n\nexport interface PrivacyBridgeContextSlices {\n wallet: PrivacyBridgeWalletContextValue;\n network: PrivacyBridgeNetworkContextValue;\n unlock: PrivacyBridgeUnlockContextValue;\n tokens: PrivacyBridgeTokensContextValue;\n swap: PrivacyBridgeSwapContextValue;\n pod: PrivacyBridgePodContextValue;\n modals: PrivacyBridgeModalsContextValue;\n}\n\n/** Merges bounded slices into the legacy flat context shape. */\nexport const mergePrivacyBridgeSlices = (\n slices: PrivacyBridgeContextSlices,\n): PrivacyBridgeContextType => ({\n ...slices.wallet,\n ...slices.network,\n ...slices.unlock,\n ...slices.tokens,\n ...slices.swap,\n ...slices.pod,\n ...slices.modals,\n});\n","import React, { createContext, useContext, useMemo } from 'react';\nimport {\n usePrivateUnlockController,\n type PrivateUnlockControllerOptions,\n} from './usePrivateUnlockController';\n\nexport type PrivateUnlockProviderOptions = PrivateUnlockControllerOptions;\n\nexport interface PrivateUnlockControllerValue {\n isUnlocked: boolean;\n isUnlocking: boolean;\n unlock: () => Promise<void>;\n lock: () => void;\n toggleLock: () => void;\n requireUnlock: (pendingAction?: () => void | Promise<void>) => Promise<boolean>;\n reset: () => void;\n /** Non-blocking message after a cancelled unlock/onboarding attempt. */\n statusMessage: string | null;\n}\n\nconst PrivateUnlockContext = createContext<PrivateUnlockControllerValue | undefined>(undefined);\n\nexport interface PrivateUnlockProviderProps {\n children: React.ReactNode;\n options?: PrivateUnlockProviderOptions;\n}\n\nexport const PrivateUnlockProvider: React.FC<PrivateUnlockProviderProps> = ({\n children,\n options,\n}) => {\n const controller = usePrivateUnlockController(options);\n const {\n isPrivateUnlocked,\n isUnlocking,\n openUnlockFlow,\n lockPrivateBalances,\n handleToggleLock,\n ensurePrivateUnlocked,\n resetUnlockUi,\n onboardModal,\n walletSignPrompt,\n statusMessage,\n } = controller;\n\n const value = useMemo<PrivateUnlockControllerValue>(() => ({\n isUnlocked: isPrivateUnlocked,\n isUnlocking,\n unlock: openUnlockFlow,\n lock: lockPrivateBalances,\n toggleLock: handleToggleLock,\n requireUnlock: ensurePrivateUnlocked,\n reset: resetUnlockUi,\n statusMessage,\n }), [\n ensurePrivateUnlocked,\n handleToggleLock,\n isPrivateUnlocked,\n isUnlocking,\n lockPrivateBalances,\n openUnlockFlow,\n resetUnlockUi,\n statusMessage,\n ]);\n\n return (\n <PrivateUnlockContext.Provider value={value}>\n {children}\n {walletSignPrompt}\n {onboardModal}\n </PrivateUnlockContext.Provider>\n );\n};\n\nexport const usePrivateUnlock = (): PrivateUnlockControllerValue => {\n const context = useContext(PrivateUnlockContext);\n if (context === undefined) {\n throw new Error('usePrivateUnlock must be used within a PrivateUnlockProvider');\n }\n return context;\n};\n","import { useCallback, useEffect, useRef, useState, type ReactElement } from 'react';\nimport { OnboardModal, type OnboardModalTheme } from '../../components/OnboardModal';\nimport { WalletSignPrompt, type WalletSignPromptPurpose } from '../../components/WalletSignPrompt';\nimport { usePrivacyBridgeUnlock, usePrivacyBridgeWallet } from '../privacyBridge/contexts';\nimport { formatOnboardingError, isMetaMaskMobileBrowser } from '../../lib/metaMaskMobile';\nimport { isUserRejection } from '../../lib/walletErrors';\nimport type {\n OnboardingProgressDetails,\n OnboardingStep,\n} from '../../hooks/useAesKeyProvider';\nimport { isSnapInstallEnabled } from '../../config/plugin';\nimport { useWalletType } from '../../hooks/useWalletType';\nimport { logger } from '../../lib/logger';\n\nconst MIN_BACKUP_SAVE_PROGRESS_MS = 600;\n\nconst CONTRACT_PROGRESS_ORDER: Partial<Record<OnboardingStep, number>> = {\n idle: 0,\n 'preparing-onboard': 1,\n 'signing-transaction': 2,\n 'retrieving-key': 3,\n 'validating-key': 4,\n 'restoring-network': 4,\n 'persisting-key': 4,\n 'saving-backup': 4,\n complete: 5,\n};\n\nfunction keepForwardContractProgress(previous: OnboardingStep, next: OnboardingStep): OnboardingStep {\n const previousOrder = CONTRACT_PROGRESS_ORDER[previous] ?? 0;\n const nextOrder = CONTRACT_PROGRESS_ORDER[next] ?? previousOrder;\n return nextOrder >= previousOrder ? next : previous;\n}\n\nexport interface PrivateUnlockControllerOptions {\n theme?: OnboardModalTheme;\n warning?: string;\n /** Called after a successful unlock (restore, onboarding, or manual key). */\n onUnlocked?: () => void | Promise<void>;\n /** Called when the user cancels backup-restore signing — modal is not opened. */\n onRestoreCancelled?: () => void;\n /** Called when the user cancels contract onboarding signing — modal is dismissed. */\n onOnboardingCancelled?: () => void;\n}\n\nexport interface PrivateUnlockController {\n isPrivateUnlocked: boolean;\n isUnlocking: boolean;\n showOnboardModal: boolean;\n openUnlockFlow: () => Promise<void>;\n unlockPrivateBalances: () => Promise<boolean>;\n ensurePrivateUnlocked: (pendingAction?: () => void | Promise<void>) => Promise<boolean>;\n handleToggleLock: () => void;\n resetUnlockUi: () => void;\n lockPrivateBalances: () => void;\n onboardModal: ReactElement;\n walletSignPrompt: ReactElement;\n sendPrivateToken: ReturnType<typeof usePrivacyBridgeUnlock>['sendPrivateToken'];\n refreshPrivateBalances: ReturnType<typeof usePrivacyBridgeUnlock>['refreshPrivateBalances'];\n encryptPrivateValue: ReturnType<typeof usePrivacyBridgeUnlock>['encryptPrivateValue'];\n decryptPrivateValue: ReturnType<typeof usePrivacyBridgeUnlock>['decryptPrivateValue'];\n /** Non-blocking message shown below the unlock control after a cancelled attempt. */\n statusMessage: string | null;\n}\n\n/** Internal engine for private unlock orchestration. Public apps should use usePrivateUnlock(). */\nexport function usePrivateUnlockController(\n options: PrivateUnlockControllerOptions = {},\n): PrivateUnlockController {\n const { theme, warning, onUnlocked, onRestoreCancelled, onOnboardingCancelled } = options;\n const unlock = usePrivacyBridgeUnlock();\n const wallet = usePrivacyBridgeWallet();\n const walletTypeInfo = useWalletType();\n\n const [showOnboardModal, setShowOnboardModal] = useState(false);\n const [isUnlocking, setIsUnlocking] = useState(false);\n const [modalError, setModalError] = useState<string | null>(null);\n const [modalWarning, setModalWarning] = useState<string | null>(null);\n const [snapConnectedInModal, setSnapConnectedInModal] = useState(false);\n const [saveBackup, setSaveBackup] = useState(true);\n const [currentStep, setCurrentStep] = useState<OnboardingStep>('idle');\n const [walletSignPromptPurpose, setWalletSignPromptPurpose] =\n useState<WalletSignPromptPurpose>('decrypt-backup');\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [isUnlockInProgress, setIsUnlockInProgress] = useState(false);\n const [pendingUnlockAfterConnect, setPendingUnlockAfterConnect] = useState(false);\n\n const unlockRequestIdRef = useRef(0);\n const pendingActionRef = useRef<(() => void | Promise<void>) | null>(null);\n const pendingActionOwnerRef = useRef<number | null>(null);\n const prevWalletAddressRef = useRef(wallet.walletAddress);\n const snapConnectedInModalRef = useRef(false);\n const backupSaveProgressStartedAtRef = useRef<number | null>(null);\n const pendingCompleteRequestIdRef = useRef<number | null>(null);\n const contractOnboardingCancelledRef = useRef(false);\n const contractOnboardingFailureRef = useRef<string | null>(null);\n const inFlightRestoreRequestIdRef = useRef<number | null>(null);\n const unlockInProgressOwnerRef = useRef<number | null>(null);\n const isPrivateUnlockedRef = useRef(unlock.isPrivateUnlocked);\n isPrivateUnlockedRef.current = unlock.isPrivateUnlocked;\n\n const connectedAddress = wallet.walletAddress || '';\n const isMetaMaskWallet = walletTypeInfo.walletType === 'metamask';\n const canAttemptSnapInstall =\n isMetaMaskWallet && !isMetaMaskMobileBrowser() && isSnapInstallEnabled();\n const usesSnapStorage =\n canAttemptSnapInstall && (walletTypeInfo.isMetaMaskWithSnap || snapConnectedInModal);\n\n const isActiveUnlockRequest = useCallback(\n (requestId: number) => requestId === unlockRequestIdRef.current,\n [],\n );\n\n const beginUnlockRequest = useCallback(() => {\n const requestId = unlockRequestIdRef.current + 1;\n unlockRequestIdRef.current = requestId;\n unlockInProgressOwnerRef.current = requestId;\n pendingActionRef.current = null;\n pendingActionOwnerRef.current = null;\n setCurrentStep('idle');\n setModalError(null);\n setModalWarning(null);\n backupSaveProgressStartedAtRef.current = null;\n pendingCompleteRequestIdRef.current = null;\n contractOnboardingCancelledRef.current = false;\n contractOnboardingFailureRef.current = null;\n return requestId;\n }, []);\n\n const clearPendingActionForRequest = useCallback((requestId: number) => {\n if (pendingActionOwnerRef.current !== requestId) return;\n pendingActionRef.current = null;\n pendingActionOwnerRef.current = null;\n }, []);\n\n const setPendingActionForRequest = useCallback((\n requestId: number,\n pendingAction: () => void | Promise<void>,\n ) => {\n pendingActionRef.current = pendingAction;\n pendingActionOwnerRef.current = requestId;\n }, []);\n\n const releaseUnlockInProgress = useCallback((requestId: number) => {\n if (unlockInProgressOwnerRef.current !== requestId) return;\n unlockInProgressOwnerRef.current = null;\n setIsUnlockInProgress(false);\n }, []);\n\n const dismissOnboardModal = useCallback(() => {\n unlockRequestIdRef.current += 1;\n unlockInProgressOwnerRef.current = null;\n pendingActionRef.current = null;\n pendingActionOwnerRef.current = null;\n setShowOnboardModal(false);\n setCurrentStep('idle');\n setModalError(null);\n setModalWarning(null);\n setIsUnlockInProgress(false);\n setIsUnlocking(false);\n backupSaveProgressStartedAtRef.current = null;\n pendingCompleteRequestIdRef.current = null;\n contractOnboardingCancelledRef.current = false;\n contractOnboardingFailureRef.current = null;\n }, []);\n\n const runPendingAction = useCallback(async (requestId: number) => {\n if (pendingActionOwnerRef.current !== requestId) return;\n const action = pendingActionRef.current;\n pendingActionRef.current = null;\n pendingActionOwnerRef.current = null;\n if (!action) return;\n await action();\n }, []);\n\n const notifyUnlocked = useCallback(async () => {\n if (onUnlocked) {\n await onUnlocked();\n }\n }, [onUnlocked]);\n\n const finishSuccessfulOnboarding = useCallback(async () => {\n setShowOnboardModal(false);\n setCurrentStep('idle');\n setModalError(null);\n setModalWarning(null);\n unlockInProgressOwnerRef.current = null;\n setIsUnlockInProgress(false);\n setIsUnlocking(false);\n pendingCompleteRequestIdRef.current = null;\n await notifyUnlocked();\n await runPendingAction(unlockRequestIdRef.current);\n }, [notifyUnlocked, runPendingAction]);\n\n useEffect(() => {\n if (usesSnapStorage) {\n setSaveBackup(false);\n }\n }, [usesSnapStorage]);\n\n useEffect(() => {\n if (!wallet.isConnected) {\n setPendingUnlockAfterConnect(false);\n setSnapConnectedInModal(false);\n snapConnectedInModalRef.current = false;\n backupSaveProgressStartedAtRef.current = null;\n pendingCompleteRequestIdRef.current = null;\n }\n }, [wallet.isConnected]);\n\n useEffect(() => {\n const previousAddress = prevWalletAddressRef.current;\n prevWalletAddressRef.current = wallet.walletAddress;\n\n if (\n !previousAddress\n || !wallet.walletAddress\n || previousAddress.toLowerCase() === wallet.walletAddress.toLowerCase()\n ) {\n return;\n }\n\n dismissOnboardModal();\n }, [dismissOnboardModal, wallet.walletAddress]);\n\n const connectSnap = useCallback(async () => {\n if (!canAttemptSnapInstall) return false;\n\n setModalError(null);\n try {\n const connected = await unlock.requestSnapConnection();\n if (!connected) {\n setModalWarning('Snap connection was skipped or rejected. Continuing without Snap storage.');\n return false;\n }\n snapConnectedInModalRef.current = true;\n setSnapConnectedInModal(true);\n return true;\n } catch {\n setModalWarning('Snap connection failed. Continuing without Snap storage.');\n return false;\n }\n }, [canAttemptSnapInstall, unlock]);\n\n const handleRestoreUnlockProgress = useCallback((step: OnboardingStep) => {\n if (step === 'signing-backup') {\n setCurrentStep(step);\n return;\n }\n\n if (\n step === 'complete'\n || step === 'idle'\n || step === 'persisting-key'\n || step === 'error'\n ) {\n setCurrentStep((previous) => (previous === 'signing-backup' ? 'idle' : previous));\n }\n }, []);\n\n const completeUnlock = useCallback(async (requestId: number) => {\n if (!isActiveUnlockRequest(requestId)) return false;\n\n setShowOnboardModal(false);\n setCurrentStep('idle');\n releaseUnlockInProgress(requestId);\n await notifyUnlocked();\n await runPendingAction(requestId);\n return true;\n }, [isActiveUnlockRequest, notifyUnlocked, releaseUnlockInProgress, runPendingAction]);\n\n const handleOnboardingIncomplete = useCallback((\n requestId: number,\n ) => {\n if (!isActiveUnlockRequest(requestId)) return;\n\n if (contractOnboardingCancelledRef.current) {\n dismissOnboardModal();\n setStatusMessage('Signature cancelled.');\n onOnboardingCancelled?.();\n return;\n }\n\n const failureMessage = contractOnboardingFailureRef.current;\n if (failureMessage) {\n setCurrentStep('error');\n setModalError(failureMessage);\n setModalWarning(unlock.onboardingWarning ?? null);\n releaseUnlockInProgress(requestId);\n return;\n }\n\n setCurrentStep('error');\n setModalError('Onboarding did not complete. Please retry.');\n setModalWarning(unlock.onboardingWarning ?? null);\n releaseUnlockInProgress(requestId);\n }, [dismissOnboardModal, isActiveUnlockRequest, onOnboardingCancelled, releaseUnlockInProgress, unlock.onboardingWarning]);\n\n const handleStaleRestoreCompletion = useCallback((\n requestId: number,\n refreshSucceeded: boolean,\n ): boolean => {\n clearPendingActionForRequest(requestId);\n\n const unlocked = refreshSucceeded || isPrivateUnlockedRef.current;\n if (!unlocked) return false;\n\n // Stale request ids never match unlockInProgressOwnerRef after supersede/dismiss,\n // so releaseUnlockInProgress(staleId) is a no-op. Clear the gate only when:\n // - session is already unlocked (openUnlockFlow/ensure will early-return), or\n // - this restore is still the latest in-flight restore finishing successfully.\n if (\n isPrivateUnlockedRef.current\n || inFlightRestoreRequestIdRef.current === requestId\n ) {\n unlockInProgressOwnerRef.current = null;\n setIsUnlockInProgress(false);\n }\n return true;\n }, [clearPendingActionForRequest]);\n\n const restorePrivateUnlock = useCallback(async (\n requestId: number,\n pendingAction?: () => void | Promise<void>,\n ): Promise<boolean> => {\n if (pendingAction) {\n setPendingActionForRequest(requestId, pendingAction);\n }\n\n setModalError(null);\n setModalWarning(null);\n inFlightRestoreRequestIdRef.current = requestId;\n setIsUnlocking(true);\n\n try {\n let restoreCancelled = false;\n if (await unlock.refreshPrivateBalances({\n restoreOnly: true,\n onRestoreCancelled: () => {\n if (!isActiveUnlockRequest(requestId)) return;\n restoreCancelled = true;\n clearPendingActionForRequest(requestId);\n onRestoreCancelled?.();\n },\n onProgress: (step) => {\n if (!isActiveUnlockRequest(requestId)) return;\n if (step === 'signing-backup') {\n setWalletSignPromptPurpose('decrypt-backup');\n }\n handleRestoreUnlockProgress(step);\n },\n })) {\n if (!isActiveUnlockRequest(requestId)) {\n return handleStaleRestoreCompletion(requestId, true);\n }\n return completeUnlock(requestId);\n }\n\n if (!isActiveUnlockRequest(requestId)) {\n return handleStaleRestoreCompletion(requestId, false);\n }\n\n if (restoreCancelled) {\n releaseUnlockInProgress(requestId);\n return false;\n }\n\n setCurrentStep('idle');\n setModalWarning(unlock.onboardingWarning ?? null);\n setShowOnboardModal(true);\n return false;\n } catch (error) {\n if (!isActiveUnlockRequest(requestId)) {\n return handleStaleRestoreCompletion(requestId, false);\n }\n\n setCurrentStep('idle');\n setShowOnboardModal(true);\n const message = error instanceof Error ? error.message : 'Private unlock failed.';\n setModalError(message === 'SNAP_REQUIRED' ? null : message);\n return false;\n } finally {\n if (inFlightRestoreRequestIdRef.current === requestId) {\n inFlightRestoreRequestIdRef.current = null;\n setIsUnlocking(false);\n }\n }\n }, [clearPendingActionForRequest, completeUnlock, handleRestoreUnlockProgress, handleStaleRestoreCompletion, isActiveUnlockRequest, onRestoreCancelled, releaseUnlockInProgress, setPendingActionForRequest, unlock]);\n\n const unlockPrivateBalances = useCallback(async () => {\n if (!connectedAddress) return false;\n\n setStatusMessage(null);\n const requestId = beginUnlockRequest();\n return restorePrivateUnlock(requestId);\n }, [beginUnlockRequest, connectedAddress, restorePrivateUnlock]);\n\n const ensurePrivateUnlocked = useCallback(async (\n pendingAction?: () => void | Promise<void>,\n ): Promise<boolean> => {\n if (unlock.isPrivateUnlocked) {\n if (pendingAction) await pendingAction();\n return true;\n }\n if (!connectedAddress) return false;\n\n setStatusMessage(null);\n const requestId = beginUnlockRequest();\n return restorePrivateUnlock(requestId, pendingAction);\n }, [beginUnlockRequest, connectedAddress, restorePrivateUnlock, unlock.isPrivateUnlocked]);\n\n const handleContractOnboardingProgress = useCallback((\n step: OnboardingStep,\n details?: OnboardingProgressDetails,\n ) => {\n logger.debug('[PrivateUnlock] contract onboarding progress', {\n step,\n details,\n currentStep,\n showOnboardModal,\n });\n\n if (details?.cancelled) {\n contractOnboardingCancelledRef.current = true;\n }\n\n if (details?.error) {\n contractOnboardingFailureRef.current = details.error;\n }\n\n if (step === 'signing-backup') {\n backupSaveProgressStartedAtRef.current = Date.now();\n setCurrentStep('saving-backup');\n return;\n }\n\n if (step === 'complete') {\n return;\n }\n\n if (step === 'error') {\n const failureMessage = details?.error ?? contractOnboardingFailureRef.current;\n if (failureMessage) {\n contractOnboardingFailureRef.current = failureMessage;\n setCurrentStep('error');\n setModalError(failureMessage);\n setModalWarning(unlock.onboardingWarning ?? null);\n releaseUnlockInProgress(unlockRequestIdRef.current);\n }\n return;\n }\n\n if (contractOnboardingFailureRef.current) {\n return;\n }\n\n setCurrentStep((previous) => keepForwardContractProgress(previous, step));\n if (step === 'idle') {\n setModalError(null);\n }\n }, [currentStep, showOnboardModal, releaseUnlockInProgress, unlock.onboardingWarning]);\n\n const showOnboardingComplete = useCallback((requestId: number) => {\n if (!isActiveUnlockRequest(requestId)) return;\n\n pendingCompleteRequestIdRef.current = null;\n setShowOnboardModal(true);\n setCurrentStep('complete');\n releaseUnlockInProgress(requestId);\n setIsUnlocking(false);\n }, [isActiveUnlockRequest, releaseUnlockInProgress]);\n\n useEffect(() => {\n const requestId = pendingCompleteRequestIdRef.current;\n if (requestId === null || !unlock.sessionAesKey) return;\n\n showOnboardingComplete(requestId);\n }, [showOnboardingComplete, unlock.sessionAesKey]);\n\n const beginOnboarding = useCallback(async () => {\n if (!connectedAddress) return;\n\n const requestId = unlockRequestIdRef.current;\n setModalError(null);\n setModalWarning(null);\n setIsUnlocking(true);\n setShowOnboardModal(true);\n setCurrentStep('preparing-onboard');\n contractOnboardingCancelledRef.current = false;\n contractOnboardingFailureRef.current = null;\n try {\n let useSnapStorageForOnboarding =\n usesSnapStorage || snapConnectedInModalRef.current;\n\n if (!useSnapStorageForOnboarding && canAttemptSnapInstall) {\n useSnapStorageForOnboarding = await connectSnap();\n }\n\n if (!isActiveUnlockRequest(requestId)) {\n return;\n }\n\n const ok = await unlock.refreshPrivateBalances({\n forceContractOnboarding: true,\n saveBackup: useSnapStorageForOnboarding ? false : saveBackup,\n onProgress: (step, details) => {\n if (isActiveUnlockRequest(requestId)) {\n handleContractOnboardingProgress(step, details);\n }\n },\n });\n if (!ok) {\n handleOnboardingIncomplete(requestId);\n return;\n }\n\n if (!isActiveUnlockRequest(requestId)) {\n return;\n }\n\n logger.debug('[PrivateUnlock] contract onboarding result', {\n ok,\n currentStep,\n hasSessionAesKey: !!unlock.sessionAesKey,\n hasOnboardingError: !!unlock.onboardingError,\n hasOnboardingWarning: !!unlock.onboardingWarning,\n });\n\n const backupSaveProgressStartedAt = backupSaveProgressStartedAtRef.current;\n if (backupSaveProgressStartedAt !== null) {\n const elapsedMs = Date.now() - backupSaveProgressStartedAt;\n const remainingMs = MIN_BACKUP_SAVE_PROGRESS_MS - elapsedMs;\n if (remainingMs > 0) {\n await new Promise(resolve => setTimeout(resolve, remainingMs));\n }\n backupSaveProgressStartedAtRef.current = null;\n }\n\n if (!isActiveUnlockRequest(requestId)) {\n return;\n }\n\n if (unlock.sessionAesKey) {\n showOnboardingComplete(requestId);\n } else {\n pendingCompleteRequestIdRef.current = requestId;\n setShowOnboardModal(true);\n setCurrentStep('validating-key');\n }\n } catch (error) {\n if (!isActiveUnlockRequest(requestId)) return;\n\n if (isUserRejection(error)) {\n dismissOnboardModal();\n setStatusMessage('Signature cancelled.');\n onOnboardingCancelled?.();\n return;\n }\n\n setCurrentStep('error');\n setModalError(formatOnboardingError(error));\n } finally {\n if (!isActiveUnlockRequest(requestId)) return;\n if (pendingCompleteRequestIdRef.current === null) {\n setIsUnlocking(false);\n }\n }\n }, [canAttemptSnapInstall, connectSnap, connectedAddress, currentStep, dismissOnboardModal, handleContractOnboardingProgress, handleOnboardingIncomplete, isActiveUnlockRequest, onOnboardingCancelled, saveBackup, showOnboardingComplete, unlock, usesSnapStorage]);\n\n const handleOnboardModalClose = useCallback(() => {\n if (\n currentStep === 'complete'\n || (currentStep === 'validating-key' && pendingCompleteRequestIdRef.current !== null)\n ) {\n void finishSuccessfulOnboarding();\n return;\n }\n dismissOnboardModal();\n }, [currentStep, dismissOnboardModal, finishSuccessfulOnboarding]);\n\n const openUnlockFlow = useCallback(async () => {\n if (!wallet.isConnected) {\n setPendingUnlockAfterConnect(true);\n await wallet.handleConnect();\n return;\n }\n if (unlock.isPrivateUnlocked) {\n unlockInProgressOwnerRef.current = null;\n setIsUnlockInProgress(false);\n return;\n }\n if (isUnlockInProgress) return;\n\n setStatusMessage(null);\n setIsUnlockInProgress(true);\n await unlockPrivateBalances();\n }, [isUnlockInProgress, unlock.isPrivateUnlocked, unlockPrivateBalances, wallet]);\n\n useEffect(() => {\n if (wallet.isConnected && pendingUnlockAfterConnect) {\n setPendingUnlockAfterConnect(false);\n void openUnlockFlow();\n }\n }, [openUnlockFlow, pendingUnlockAfterConnect, wallet.isConnected]);\n\n const handleToggleLock = useCallback(() => {\n if (!wallet.isConnected) {\n setPendingUnlockAfterConnect(true);\n void wallet.handleConnect();\n return;\n }\n if (unlock.isPrivateUnlocked) {\n unlock.lockPrivateBalances();\n dismissOnboardModal();\n return;\n }\n void openUnlockFlow();\n }, [dismissOnboardModal, openUnlockFlow, unlock, wallet]);\n\n const resetUnlockUi = useCallback(() => {\n dismissOnboardModal();\n setStatusMessage(null);\n setPendingUnlockAfterConnect(false);\n }, [dismissOnboardModal]);\n\n const lockPrivateBalances = useCallback(() => {\n unlock.lockPrivateBalances();\n setPendingUnlockAfterConnect(false);\n dismissOnboardModal();\n }, [dismissOnboardModal, unlock]);\n\n const walletSignPrompt = (\n <WalletSignPrompt\n isOpen={currentStep === 'signing-backup'}\n walletType={walletTypeInfo.walletType}\n theme={theme}\n purpose={walletSignPromptPurpose}\n />\n );\n\n const visibleModalError = modalError;\n\n const onboardModal = (\n <OnboardModal\n isOpen={showOnboardModal && currentStep !== 'signing-backup'}\n onClose={handleOnboardModalClose}\n onConfirm={beginOnboarding}\n isLoading={isUnlocking}\n error={visibleModalError}\n walletType={walletTypeInfo.walletType}\n currentStep={currentStep}\n aesKey={currentStep === 'complete' ? unlock.sessionAesKey : null}\n saveBackup={saveBackup}\n showSaveBackupOption={!usesSnapStorage}\n onSaveBackupChange={setSaveBackup}\n onManualAesKeySubmit={async (aesKey, { saveBackup: shouldSaveBackup }) => {\n const requestId = unlockRequestIdRef.current;\n setModalWarning(null);\n const manualSaveResult = await unlock.saveManualAesKey(aesKey, {\n saveBackup: shouldSaveBackup,\n onProgress: (step) => {\n if (!isActiveUnlockRequest(requestId)) return;\n if (step === 'signing-backup') {\n setWalletSignPromptPurpose('save-backup');\n setShowOnboardModal(false);\n }\n handleRestoreUnlockProgress(step);\n },\n });\n if (!isActiveUnlockRequest(requestId)) {\n return;\n }\n if (manualSaveResult.backupCancelled) {\n setStatusMessage(manualSaveResult.backupWarning ?? 'Local save was cancelled.');\n await completeUnlock(requestId);\n return;\n }\n if (manualSaveResult.backupWarning) {\n setModalWarning(manualSaveResult.backupWarning);\n setShowOnboardModal(true);\n setCurrentStep('complete');\n releaseUnlockInProgress(requestId);\n return;\n }\n await completeUnlock(requestId);\n }}\n theme={theme}\n warning={modalWarning ?? unlock.onboardingWarning ?? warning ?? null}\n />\n );\n\n return {\n isPrivateUnlocked: unlock.isPrivateUnlocked,\n isUnlocking,\n showOnboardModal,\n openUnlockFlow,\n unlockPrivateBalances,\n ensurePrivateUnlocked,\n handleToggleLock,\n resetUnlockUi,\n lockPrivateBalances,\n onboardModal,\n walletSignPrompt,\n statusMessage,\n sendPrivateToken: unlock.sendPrivateToken,\n refreshPrivateBalances: unlock.refreshPrivateBalances,\n encryptPrivateValue: unlock.encryptPrivateValue,\n decryptPrivateValue: unlock.decryptPrivateValue,\n };\n}\n","import React, { useEffect, useState } from 'react';\nimport type { WalletType } from '../hooks/useWalletType';\nimport type { OnboardingStep } from '../hooks/useAesKeyProvider';\nimport { normalizeAesKey } from '../crypto/aesKey';\nimport { getWalletDisplayName } from '../lib/walletDisplayName';\nimport {\n getDisplayOnboardingSteps,\n getOnboardingStepStatus,\n getProgressTitle,\n} from '../lib/onboardingProgressDisplay';\nimport { deriveOnboardScreen } from './onboard/deriveOnboardScreen';\nimport { logger } from '../lib/logger';\n\n/**\n * Props for the OnboardModal component.\n */\nexport interface OnboardModalProps {\n /** Whether the modal is currently visible */\n isOpen: boolean;\n /** Callback to close the modal without completing onboarding */\n onClose: () => void;\n /** Callback to initiate or retry the onboarding signature flow */\n onConfirm: () => void;\n /** Whether the generateOrRecoverAes() call is in progress */\n isLoading: boolean;\n /** Error message from a failed onboarding attempt, or null */\n error: string | null;\n /** The type of wallet connected (for display purposes) */\n walletType: WalletType;\n /** Current onboarding step (for progress display) */\n currentStep?: OnboardingStep;\n /** Retrieved AES key (shown on success screen) */\n aesKey?: string | null;\n /** Whether encrypted AES backup should be saved after contract onboarding */\n saveBackup?: boolean;\n /** When false, hides the encrypted-backup checkbox (e.g. MetaMask Snap stores the key). */\n showSaveBackupOption?: boolean;\n /** Called when the encrypted-backup checkbox changes */\n onSaveBackupChange?: (saveBackup: boolean) => void;\n /** Called when the user manually submits an AES key instead of onboarding */\n onManualAesKeySubmit?: (\n aesKey: string,\n options: { saveBackup: boolean },\n ) => void | Promise<void>;\n /** Non-blocking warning from restore/backup flows */\n warning?: string | null;\n /** Optional theme overrides for customizing the modal appearance */\n theme?: OnboardModalTheme;\n}\n\n/**\n * Theme override for the OnboardModal.\n * Each key corresponds to a style target. Provide a partial CSSProperties object\n * to override specific CSS properties while keeping the rest as defaults.\n */\nexport type OnboardModalTheme = {\n [K in keyof typeof defaultStyles]?: React.CSSProperties;\n};\n\n/** Inline styles for the modal — keeps the component self-contained without external UI deps */\nconst defaultStyles = {\n backdrop: {\n position: 'fixed' as const,\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.6)',\n backdropFilter: 'blur(4px)',\n zIndex: 50,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '1rem',\n },\n modal: {\n backgroundColor: '#04133D',\n color: '#ffffff',\n borderRadius: '16px',\n padding: '28px',\n width: '360px',\n maxWidth: '100%',\n position: 'relative' as const,\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n textAlign: 'center' as const,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)',\n },\n closeButton: {\n position: 'absolute' as const,\n top: '12px',\n right: '12px',\n padding: '8px',\n background: 'none',\n border: 'none',\n color: 'rgba(255, 255, 255, 0.3)',\n cursor: 'pointer',\n borderRadius: '50%',\n fontSize: '14px',\n lineHeight: 1,\n transition: 'color 0.2s',\n },\n titleRow: {\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '12px',\n marginBottom: '16px',\n },\n iconContainer: {\n width: '40px',\n height: '40px',\n borderRadius: '12px',\n backgroundColor: 'rgba(30, 41, 246, 0.1)',\n border: '1px solid rgba(30, 41, 246, 0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n title: {\n fontSize: '20px',\n fontWeight: 700,\n lineHeight: 1.2,\n margin: 0,\n color: '#ffffff',\n textAlign: 'left' as const,\n },\n description: {\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '13px',\n lineHeight: 1.6,\n marginBottom: '16px',\n maxWidth: '90%',\n },\n infoBox: {\n width: '100%',\n backgroundColor: 'rgba(255, 255, 255, 0.05)',\n border: '1px solid rgba(255, 255, 255, 0.1)',\n borderRadius: '8px',\n padding: '12px',\n marginBottom: '16px',\n },\n infoText: {\n fontSize: '11px',\n color: 'rgba(255, 255, 255, 0.8)',\n lineHeight: 1.6,\n margin: 0,\n },\n errorBox: {\n width: '100%',\n boxSizing: 'border-box' as const,\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n border: '1px solid rgba(239, 68, 68, 0.3)',\n borderRadius: '8px',\n padding: '12px',\n marginBottom: '16px',\n },\n errorText: {\n fontSize: '12px',\n color: '#f87171',\n lineHeight: 1.5,\n margin: 0,\n },\n primaryButton: {\n width: '100%',\n boxSizing: 'border-box' as const,\n padding: '10px 16px',\n backgroundColor: '#1E29F6',\n color: '#ffffff',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: 'pointer',\n marginBottom: '10px',\n transition: 'background-color 0.2s',\n },\n primaryButtonDisabled: {\n width: '100%',\n boxSizing: 'border-box' as const,\n padding: '10px 16px',\n backgroundColor: 'rgba(30, 41, 246, 0.5)',\n color: 'rgba(255, 255, 255, 0.6)',\n border: 'none',\n borderRadius: '8px',\n fontSize: '14px',\n fontWeight: 500,\n cursor: 'not-allowed',\n marginBottom: '10px',\n },\n cancelButton: {\n background: 'none',\n border: 'none',\n fontSize: '12px',\n color: 'rgba(255, 255, 255, 0.4)',\n cursor: 'pointer',\n fontWeight: 500,\n transition: 'color 0.2s',\n },\n saveOptionCard: {\n width: '100%',\n boxSizing: 'border-box' as const,\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '10px 12px',\n marginBottom: '12px',\n borderRadius: '8px',\n border: '1px solid rgba(255, 255, 255, 0.12)',\n backgroundColor: 'rgba(255, 255, 255, 0.04)',\n textAlign: 'left' as const,\n },\n saveOptionCardActive: {\n border: '1px solid rgba(0, 229, 255, 0.35)',\n backgroundColor: 'rgba(0, 229, 255, 0.06)',\n },\n saveOptionIconWrap: {\n width: '32px',\n height: '32px',\n borderRadius: '8px',\n backgroundColor: 'rgba(0, 229, 255, 0.1)',\n border: '1px solid rgba(0, 229, 255, 0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n color: '#00E5FF',\n },\n saveOptionBody: {\n flex: 1,\n minWidth: 0,\n },\n saveOptionTitleRow: {\n display: 'flex',\n alignItems: 'center',\n gap: '5px',\n marginBottom: '2px',\n },\n saveOptionTitle: {\n fontSize: '13px',\n fontWeight: 600,\n lineHeight: 1.25,\n color: '#ffffff',\n },\n saveOptionDescription: {\n fontSize: '11px',\n lineHeight: 1.3,\n color: 'rgba(255, 255, 255, 0.55)',\n margin: 0,\n whiteSpace: 'nowrap' as const,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n saveOptionSwitchTrack: {\n position: 'relative' as const,\n width: '42px',\n height: '24px',\n boxSizing: 'border-box' as const,\n borderRadius: '999px',\n border: '1px solid transparent',\n padding: 0,\n flexShrink: 0,\n cursor: 'pointer',\n transition: 'background-color 0.2s, border-color 0.2s',\n },\n saveOptionSwitchTrackOn: {\n backgroundColor: '#00E5FF',\n borderColor: 'rgba(0, 229, 255, 0.45)',\n },\n saveOptionSwitchTrackOff: {\n backgroundColor: 'rgba(255, 255, 255, 0.18)',\n borderColor: 'rgba(255, 255, 255, 0.28)',\n },\n saveOptionSwitchKnob: {\n position: 'absolute' as const,\n top: '50%',\n left: '2px',\n width: '20px',\n height: '20px',\n borderRadius: '50%',\n backgroundColor: '#ffffff',\n transition: 'transform 0.2s',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.25)',\n },\n tooltipWrap: {\n position: 'relative' as const,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n tooltipButton: {\n width: '14px',\n height: '14px',\n borderRadius: '50%',\n border: '1px solid rgba(255, 255, 255, 0.25)',\n backgroundColor: 'rgba(255, 255, 255, 0.08)',\n color: 'rgba(255, 255, 255, 0.8)',\n fontSize: '9px',\n lineHeight: 1,\n padding: 0,\n cursor: 'help',\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontWeight: 700,\n },\n tooltipBubble: {\n position: 'absolute' as const,\n bottom: 'calc(100% + 8px)',\n left: '50%',\n transform: 'translateX(-50%)',\n width: '220px',\n boxSizing: 'border-box' as const,\n padding: '8px 10px',\n borderRadius: '8px',\n backgroundColor: 'rgba(0, 0, 0, 0.92)',\n border: '1px solid rgba(255, 255, 255, 0.14)',\n color: 'rgba(255, 255, 255, 0.86)',\n fontSize: '11px',\n lineHeight: 1.4,\n textAlign: 'left' as const,\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.35)',\n zIndex: 1,\n },\n actionRow: {\n width: '100%',\n display: 'flex',\n gap: '8px',\n alignItems: 'stretch',\n marginBottom: '10px',\n minHeight: '48px',\n },\n actionPrimary: {\n flex: 1,\n minWidth: 0,\n minHeight: '48px',\n boxSizing: 'border-box' as const,\n },\n actionFieldButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 16px',\n marginBottom: 0,\n },\n iconButton: {\n width: '48px',\n minWidth: '48px',\n height: '48px',\n minHeight: '48px',\n boxSizing: 'border-box' as const,\n padding: '0',\n backgroundColor: 'rgba(255, 255, 255, 0.06)',\n color: '#ffffff',\n border: '1px solid rgba(255, 255, 255, 0.14)',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n },\n iconButtonPressed: {\n width: '48px',\n minWidth: '48px',\n height: '48px',\n minHeight: '48px',\n boxSizing: 'border-box' as const,\n padding: '0',\n backgroundColor: 'rgba(30, 41, 246, 0.22)',\n color: '#00E5FF',\n border: '1px solid rgba(0, 229, 255, 0.45)',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n boxShadow: 'inset 0 2px 6px rgba(0, 0, 0, 0.35)',\n },\n iconButtonDisabled: {\n width: '48px',\n minWidth: '48px',\n height: '48px',\n minHeight: '48px',\n boxSizing: 'border-box' as const,\n padding: '0',\n backgroundColor: 'rgba(255, 255, 255, 0.04)',\n color: 'rgba(255, 255, 255, 0.35)',\n border: '1px solid rgba(255, 255, 255, 0.08)',\n borderRadius: '8px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'not-allowed',\n },\n manualKeyInput: {\n width: '100%',\n height: '48px',\n minHeight: '48px',\n boxSizing: 'border-box' as const,\n padding: '0 12px',\n backgroundColor: 'rgba(0, 0, 0, 0.25)',\n color: '#ffffff',\n border: '1px solid rgba(255, 255, 255, 0.16)',\n borderRadius: '8px',\n fontSize: '14px',\n fontFamily: 'monospace',\n outline: 'none',\n },\n manualKeyErrorRow: {\n width: '100%',\n display: 'flex',\n gap: '8px',\n alignItems: 'flex-start',\n margin: '0 0 10px',\n },\n manualKeyErrorColumn: {\n flex: 1,\n minWidth: 0,\n minHeight: '17px',\n },\n actionSideSpacer: {\n width: '48px',\n minWidth: '48px',\n flexShrink: 0,\n },\n manualKeyErrorText: {\n fontSize: '11px',\n color: '#b91c1c',\n lineHeight: 1.5,\n margin: 0,\n paddingLeft: '12px',\n textAlign: 'left' as const,\n },\n spinner: {\n display: 'inline-block',\n width: '20px',\n height: '20px',\n border: '2px solid rgba(255, 255, 255, 0.3)',\n borderTopColor: '#ffffff',\n borderRadius: '50%',\n animation: 'onboard-spin 0.8s linear infinite',\n },\n stepperContainer: {\n width: '100%',\n marginBottom: '16px',\n },\n stepItem: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '10px',\n marginBottom: '12px',\n textAlign: 'left' as const,\n },\n stepIconContainer: {\n width: '24px',\n height: '24px',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n stepIconPending: {\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n border: '2px solid rgba(255, 255, 255, 0.2)',\n },\n stepIconActive: {\n backgroundColor: 'rgba(0, 229, 255, 0.1)',\n border: '2px solid #00E5FF',\n },\n stepIconComplete: {\n backgroundColor: 'rgba(34, 197, 94, 0.1)',\n border: '2px solid #22c55e',\n },\n stepIconError: {\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n border: '2px solid #ef4444',\n },\n stepContent: {\n flex: 1,\n },\n stepLabel: {\n fontSize: '12px',\n fontWeight: 600,\n color: '#ffffff',\n marginBottom: '4px',\n },\n stepDescription: {\n fontSize: '11px',\n color: 'rgba(255, 255, 255, 0.5)',\n lineHeight: 1.4,\n },\n aesKeyBox: {\n width: '100%',\n boxSizing: 'border-box' as const,\n backgroundColor: 'rgba(0, 0, 0, 0.3)',\n border: '1px solid rgba(255, 255, 255, 0.1)',\n borderRadius: '8px',\n padding: '12px',\n marginBottom: '16px',\n fontFamily: 'monospace',\n fontSize: '11px',\n color: '#00E5FF',\n wordBreak: 'break-all' as const,\n textAlign: 'left' as const,\n },\n keyInputWrap: {\n width: '100%',\n boxSizing: 'border-box' as const,\n position: 'relative' as const,\n marginBottom: '16px',\n },\n keyInput: {\n width: '100%',\n boxSizing: 'border-box' as const,\n padding: '12px 82px 12px 12px',\n backgroundColor: 'rgba(0, 0, 0, 0.3)',\n color: '#00E5FF',\n border: '1px solid rgba(255, 255, 255, 0.1)',\n borderRadius: '8px',\n fontFamily: 'monospace',\n fontSize: '11px',\n outline: 'none',\n },\n keyInputActions: {\n position: 'absolute' as const,\n top: '50%',\n right: '8px',\n transform: 'translateY(-50%)',\n display: 'flex',\n gap: '4px',\n },\n inlineIconButton: {\n width: '30px',\n height: '30px',\n borderRadius: '6px',\n border: '1px solid rgba(0, 229, 255, 0.25)',\n backgroundColor: 'rgba(0, 229, 255, 0.08)',\n color: '#00E5FF',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n padding: 0,\n },\n warningBox: {\n width: '100%',\n boxSizing: 'border-box' as const,\n backgroundColor: 'rgba(251, 191, 36, 0.1)',\n border: '1px solid rgba(251, 191, 36, 0.3)',\n borderRadius: '8px',\n padding: '12px',\n marginBottom: '12px',\n },\n warningText: {\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '12px',\n lineHeight: 1.6,\n margin: 0,\n fontFamily: 'inherit',\n },\n calloutBox: {\n width: '100%',\n boxSizing: 'border-box' as const,\n backgroundColor: 'rgba(0, 229, 255, 0.1)',\n border: '1px solid rgba(0, 229, 255, 0.3)',\n borderRadius: '8px',\n padding: '8px 12px',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n progressCalloutSlot: {\n width: '100%',\n minHeight: '58px',\n marginTop: '10px',\n marginBottom: '4px',\n display: 'flex',\n alignItems: 'flex-start',\n },\n calloutText: {\n fontSize: '11px',\n color: '#00E5FF',\n lineHeight: 1.4,\n margin: 0,\n textAlign: 'left' as const,\n },\n} as const;\n\ntype OnboardStyleKey = keyof typeof defaultStyles;\n\n/** Style targets apps can override via `privateUnlock.theme`. */\nexport const ONBOARD_MODAL_STYLE_KEYS = Object.keys(defaultStyles) as OnboardStyleKey[];\n\nconst FOREGROUND_TEXT_KEYS: OnboardStyleKey[] = [\n 'infoText',\n 'stepLabel',\n 'manualKeyInput',\n 'iconButton',\n 'title',\n 'saveOptionTitle',\n];\nconst MUTED_TEXT_KEYS: OnboardStyleKey[] = [\n 'closeButton',\n 'tooltipButton',\n 'cancelButton',\n 'stepDescription',\n 'saveOptionDescription',\n];\nconst ACCENT_TEXT_KEYS: OnboardStyleKey[] = [\n 'keyInput',\n 'aesKeyBox',\n 'calloutText',\n 'inlineIconButton',\n 'iconButtonPressed',\n];\n\nfunction isDefaultDarkThemeTextColor(color?: string): boolean {\n if (!color) return true;\n const normalized = color.trim().toLowerCase();\n return (\n normalized === '#ffffff'\n || normalized === '#00e5ff'\n || normalized.startsWith('rgba(255, 255, 255')\n );\n}\n\n/**\n * When the host app passes a theme, fill unthemed text targets that still use\n * the plugin's dark-mode defaults so light palettes stay readable.\n */\nfunction applyThemePaletteGaps(\n merged: Record<OnboardStyleKey, React.CSSProperties>,\n theme: OnboardModalTheme,\n) {\n const foreground =\n theme.title?.color\n ?? theme.modal?.color\n ?? theme.infoText?.color;\n const muted = theme.description?.color ?? theme.cancelButton?.color;\n const accent =\n theme.primaryButton?.backgroundColor\n ?? theme.calloutText?.color\n ?? theme.aesKeyBox?.color\n ?? theme.keyInput?.color;\n\n const fillText = (keys: OnboardStyleKey[], color?: string) => {\n if (!color) return;\n for (const key of keys) {\n if (theme[key]) continue;\n const currentColor = merged[key]?.color;\n if (!isDefaultDarkThemeTextColor(\n typeof currentColor === 'string' ? currentColor : undefined,\n )) {\n continue;\n }\n merged[key] = { ...merged[key], color };\n }\n };\n\n fillText(FOREGROUND_TEXT_KEYS, foreground);\n fillText(MUTED_TEXT_KEYS, muted);\n fillText(ACCENT_TEXT_KEYS, accent);\n}\n\nconst LIGHT_INTERACTIVE_SURFACE_KEYS: OnboardStyleKey[] = [\n 'closeButton',\n 'cancelButton',\n 'iconButton',\n 'iconButtonPressed',\n 'iconButtonDisabled',\n 'inlineIconButton',\n 'manualKeyInput',\n 'keyInput',\n 'aesKeyBox',\n 'calloutBox',\n 'iconContainer',\n 'saveOptionCard',\n 'saveOptionIconWrap',\n 'saveOptionSwitchTrackOff',\n 'saveOptionSwitchTrackOn',\n];\n\nfunction isDefaultDarkSurfaceBackground(backgroundColor?: string): boolean {\n if (!backgroundColor) return true;\n const normalized = backgroundColor.trim().toLowerCase();\n return (\n normalized.includes('rgba(0, 0, 0')\n || normalized.includes('rgba(255, 255, 255, 0.0')\n || normalized.includes('rgba(255, 255, 255, 0.04')\n || normalized.includes('rgba(255, 255, 255, 0.06)')\n || normalized.includes('rgba(255, 255, 255, 0.18)')\n || normalized === 'rgba(0, 0, 0, 0.25)'\n || normalized === 'rgba(0, 0, 0, 0.3)'\n || normalized === '#00e5ff'\n );\n}\n\nfunction colorWithAlpha(color: string, alpha: number): string {\n const rgb = parseColorToRgb(color);\n if (!rgb) return color;\n return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;\n}\n\n/**\n * On light modal backgrounds, fill interactive surfaces that still use the\n * plugin's dark defaults so icon/cancel/close controls stay visible.\n */\nfunction applyLightInteractiveSurfaceGaps(\n merged: Record<OnboardStyleKey, React.CSSProperties>,\n theme: OnboardModalTheme,\n) {\n const modalBackground =\n typeof merged.modal.backgroundColor === 'string'\n ? merged.modal.backgroundColor\n : undefined;\n if (!isLightBackgroundColor(modalBackground)) return;\n\n const foreground =\n theme.title?.color\n ?? theme.modal?.color\n ?? '#0f172a';\n const muted =\n theme.description?.color\n ?? theme.cancelButton?.color\n ?? '#64748b';\n const primary =\n typeof theme.primaryButton?.backgroundColor === 'string'\n ? theme.primaryButton.backgroundColor\n : '#1E29F6';\n const inset =\n (typeof theme.manualKeyInput?.backgroundColor === 'string'\n ? theme.manualKeyInput.backgroundColor\n : undefined)\n ?? (typeof theme.keyInput?.backgroundColor === 'string'\n ? theme.keyInput.backgroundColor\n : undefined)\n ?? '#f1f5f9';\n const softBorder = `1px solid ${colorWithAlpha(foreground, 0.16)}`;\n const primaryBorder = `1px solid ${colorWithAlpha(primary, 0.3)}`;\n\n const surfaceDefaults: Partial<Record<OnboardStyleKey, React.CSSProperties>> = {\n closeButton: { color: muted },\n cancelButton: { color: foreground, fontWeight: 600 },\n iconButton: {\n backgroundColor: inset,\n color: foreground,\n border: softBorder,\n },\n iconButtonPressed: {\n backgroundColor: colorWithAlpha(primary, 0.12),\n color: primary,\n border: primaryBorder,\n boxShadow: 'none',\n },\n iconButtonDisabled: {\n backgroundColor: colorWithAlpha(foreground, 0.04),\n color: colorWithAlpha(foreground, 0.4),\n border: `1px solid ${colorWithAlpha(foreground, 0.1)}`,\n },\n inlineIconButton: {\n backgroundColor: colorWithAlpha(primary, 0.08),\n color: primary,\n border: `1px solid ${colorWithAlpha(primary, 0.28)}`,\n },\n manualKeyInput: {\n backgroundColor: inset,\n color: foreground,\n border: softBorder,\n },\n keyInput: {\n backgroundColor: inset,\n color: primary,\n border: softBorder,\n },\n aesKeyBox: {\n backgroundColor: inset,\n color: primary,\n border: softBorder,\n },\n calloutBox: {\n backgroundColor: colorWithAlpha(primary, 0.08),\n border: primaryBorder,\n },\n iconContainer: {\n backgroundColor: colorWithAlpha(primary, 0.08),\n border: `1px solid ${colorWithAlpha(primary, 0.2)}`,\n },\n saveOptionCard: {\n backgroundColor: colorWithAlpha(foreground, 0.04),\n border: softBorder,\n },\n saveOptionIconWrap: {\n backgroundColor: colorWithAlpha(primary, 0.1),\n border: `1px solid ${colorWithAlpha(primary, 0.22)}`,\n color: primary,\n },\n saveOptionSwitchTrackOff: {\n backgroundColor: colorWithAlpha(foreground, 0.2),\n borderColor: colorWithAlpha(foreground, 0.34),\n },\n saveOptionSwitchTrackOn: {\n backgroundColor: primary,\n borderColor: colorWithAlpha(primary, 0.45),\n },\n };\n\n for (const key of LIGHT_INTERACTIVE_SURFACE_KEYS) {\n if (theme[key]) continue;\n const defaults = surfaceDefaults[key];\n if (!defaults) continue;\n\n const currentBackground =\n typeof merged[key]?.backgroundColor === 'string'\n ? merged[key].backgroundColor\n : undefined;\n const shouldFillBackground = isDefaultDarkSurfaceBackground(currentBackground);\n const patch: React.CSSProperties = { ...defaults };\n if (!shouldFillBackground) {\n delete patch.backgroundColor;\n delete patch.border;\n delete patch.boxShadow;\n }\n merged[key] = { ...merged[key], ...patch };\n }\n}\n\n/** Merges default styles with optional theme overrides from the host app. */\nexport function mergeOnboardModalTheme(theme?: OnboardModalTheme) {\n if (!theme) return defaultStyles;\n const merged = { ...defaultStyles } as Record<OnboardStyleKey, React.CSSProperties>;\n for (const key of Object.keys(theme) as OnboardStyleKey[]) {\n if (theme[key]) {\n merged[key] = { ...defaultStyles[key], ...theme[key] } as React.CSSProperties;\n }\n }\n applyThemePaletteGaps(merged, theme);\n applyLightInteractiveSurfaceGaps(merged, theme);\n return merged as typeof defaultStyles;\n}\n\nfunction parseColorToRgb(\n color: string,\n): { r: number; g: number; b: number; alpha: number } | null {\n const normalized = color.trim();\n\n const hexMatch = normalized.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (hexMatch) {\n const hex = hexMatch[1];\n if (hex.length === 3) {\n return {\n r: Number.parseInt(hex[0] + hex[0], 16),\n g: Number.parseInt(hex[1] + hex[1], 16),\n b: Number.parseInt(hex[2] + hex[2], 16),\n alpha: 1,\n };\n }\n return {\n r: Number.parseInt(hex.slice(0, 2), 16),\n g: Number.parseInt(hex.slice(2, 4), 16),\n b: Number.parseInt(hex.slice(4, 6), 16),\n alpha: 1,\n };\n }\n\n const rgbMatch = normalized.match(\n /^rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})(?:\\s*,\\s*([0-9]*\\.?[0-9]+))?\\s*\\)$/i,\n );\n if (rgbMatch) {\n return {\n r: Number(rgbMatch[1]),\n g: Number(rgbMatch[2]),\n b: Number(rgbMatch[3]),\n alpha: rgbMatch[4] ? Number(rgbMatch[4]) : 1,\n };\n }\n\n const hslMatch = normalized.match(\n /^hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s+(\\d+(?:\\.\\d+)?)%\\s+(\\d+(?:\\.\\d+)?)%(?:\\s*\\/\\s*([0-9]*\\.?[0-9]+))?\\s*\\)$/i,\n );\n if (hslMatch) {\n const h = Number(hslMatch[1]) / 360;\n const s = Number(hslMatch[2]) / 100;\n const l = Number(hslMatch[3]) / 100;\n const alpha = hslMatch[4] ? Number(hslMatch[4]) : 1;\n const hue2rgb = (p: number, q: number, t: number) => {\n let value = t;\n if (value < 0) value += 1;\n if (value > 1) value -= 1;\n if (value < 1 / 6) return p + (q - p) * 6 * value;\n if (value < 1 / 2) return q;\n if (value < 2 / 3) return p + (q - p) * (2 / 3 - value) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n alpha,\n };\n }\n\n return null;\n}\n\nfunction isLightBackgroundColor(color: string | undefined): boolean {\n if (!color) return false;\n const rgb = parseColorToRgb(color);\n if (!rgb) return false;\n\n const { r, g, b, alpha } = rgb;\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) * alpha;\n return luminance >= 150;\n}\n\nfunction resolveWarningBoxStyle(box: React.CSSProperties): React.CSSProperties {\n const padding = box.padding;\n if (padding === undefined || padding === null || padding === 0 || padding === '0') {\n return { ...box, padding: defaultStyles.warningBox.padding };\n }\n return box;\n}\n\nfunction getWarningStyles(styles: typeof defaultStyles) {\n const lightTheme = isLightBackgroundColor(\n typeof styles.modal.backgroundColor === 'string'\n ? styles.modal.backgroundColor\n : undefined,\n );\n\n if (lightTheme) {\n return {\n box: resolveWarningBoxStyle({\n ...styles.warningBox,\n backgroundColor: 'rgba(245, 158, 11, 0.14)',\n border: '1px solid rgba(180, 83, 9, 0.35)',\n }),\n text: {\n ...styles.warningText,\n color: '#78350f',\n },\n };\n }\n\n return {\n box: resolveWarningBoxStyle(styles.warningBox),\n text: {\n ...styles.warningText,\n color: '#fef3c7',\n },\n };\n}\n\n/** CSS keyframes for the spinner animation, injected once */\nconst SPINNER_KEYFRAMES = `\n@keyframes onboard-spin {\n to { transform: rotate(360deg); }\n}\n`;\n\n/**\n * OnboardModal — Multi-step modal for AES key retrieval onboarding.\n *\n * Screens:\n * 1. Intro: Explains the process before starting\n * 2. Progress: Shows step-by-step progress (steps 3-9)\n * 3. Success: Displays retrieved AES key with copy button\n * 4. Error: Shows error message with retry button\n */\nexport const OnboardModal: React.FC<OnboardModalProps> = ({\n isOpen,\n onClose,\n onConfirm,\n isLoading,\n error,\n walletType,\n currentStep = 'idle',\n aesKey,\n saveBackup = true,\n showSaveBackupOption = true,\n onSaveBackupChange,\n onManualAesKeySubmit,\n warning,\n theme,\n}) => {\n const [copied, setCopied] = useState(false);\n const [isAesVisible, setIsAesVisible] = useState(false);\n const [showManualKeyInput, setShowManualKeyInput] = useState(false);\n const [manualAesKey, setManualAesKey] = useState('');\n const [manualAesKeyError, setManualAesKeyError] = useState<string | null>(null);\n const [isSubmittingManualKey, setIsSubmittingManualKey] = useState(false);\n const [showBackupTooltip, setShowBackupTooltip] = useState(false);\n const styles = mergeOnboardModalTheme(theme);\n const warningStyles = getWarningStyles(styles);\n\n // Reset local UI state when the modal closes\n useEffect(() => {\n if (!isOpen) {\n setCopied(false);\n setIsAesVisible(false);\n setShowManualKeyInput(false);\n setManualAesKey('');\n setManualAesKeyError(null);\n setIsSubmittingManualKey(false);\n setShowBackupTooltip(false);\n }\n }, [isOpen]);\n\n const screen = deriveOnboardScreen({ currentStep, isLoading, error, aesKey });\n const showIntro = screen === 'intro';\n const showProgress = screen === 'progress';\n const showSuccess = screen === 'success';\n const showError = screen === 'error';\n const hasDescription = showIntro || showSuccess || showError;\n\n useEffect(() => {\n logger.debug('[OnboardModal] screen', {\n screen,\n currentStep,\n isOpen,\n isLoading,\n hasError: !!error,\n hasAesKey: !!aesKey,\n });\n }, [screen, currentStep, isOpen, isLoading, error, aesKey]);\n\n const walletName = getWalletDisplayName(walletType);\n const includePersistStep = saveBackup || !showSaveBackupOption;\n const displaySteps = getDisplayOnboardingSteps(includePersistStep);\n\n const renderTitleRow = (icon: React.ReactNode, title: string) => (\n <div style={styles.titleRow}>\n <div style={styles.iconContainer}>{icon}</div>\n <h2 id=\"onboard-modal-title\" style={styles.title}>{title}</h2>\n </div>\n );\n\n const renderSaveLocallyOption = () => {\n if (!showSaveBackupOption) return null;\n\n return (\n <div\n style={{\n ...styles.saveOptionCard,\n ...(saveBackup ? styles.saveOptionCardActive : {}),\n }}\n >\n <div style={styles.saveOptionIconWrap} aria-hidden=\"true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4\" />\n </svg>\n </div>\n\n <div style={styles.saveOptionBody}>\n <div style={styles.saveOptionTitleRow}>\n <span style={styles.saveOptionTitle}>Save Locally</span>\n <span style={styles.tooltipWrap}>\n <button\n type=\"button\"\n aria-label=\"How local save works\"\n aria-describedby={showBackupTooltip ? 'backup-details-tooltip' : undefined}\n onMouseEnter={() => setShowBackupTooltip(true)}\n onMouseLeave={() => setShowBackupTooltip(false)}\n onFocus={() => setShowBackupTooltip(true)}\n onBlur={() => setShowBackupTooltip(false)}\n style={styles.tooltipButton}\n >\n ?\n </button>\n {showBackupTooltip && (\n <span id=\"backup-details-tooltip\" role=\"tooltip\" style={styles.tooltipBubble}>\n Only an encrypted blob is stored locally. Restoring it requires a wallet signature.\n </span>\n )}\n </span>\n </div>\n <p style={styles.saveOptionDescription}>\n Encrypted locally. Restore via wallet signature.\n </p>\n </div>\n\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={saveBackup}\n aria-label={saveBackup ? 'Disable local save' : 'Enable local save'}\n onClick={() => onSaveBackupChange?.(!saveBackup)}\n style={{\n ...styles.saveOptionSwitchTrack,\n ...(saveBackup ? styles.saveOptionSwitchTrackOn : styles.saveOptionSwitchTrackOff),\n }}\n >\n <span\n style={{\n ...styles.saveOptionSwitchKnob,\n transform: saveBackup ? 'translate(18px, -50%)' : 'translateY(-50%)',\n }}\n />\n </button>\n </div>\n );\n };\n\n const renderProgressCallout = (step: OnboardingStep) => {\n if (step === 'granting-funds') {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Funding in progress:</strong> Requesting native COTI from the grant service.\n </p>\n </div>\n );\n }\n\n if (step === 'waiting-for-funds') {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M4 12h4l2-4 4 8 2-4h4\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Grant submitted:</strong> Waiting for the funded balance to appear on COTI.\n </p>\n </div>\n );\n }\n\n if (step === 'preparing-onboard') {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Preparing onboarding:</strong> Checking wallet balance and contract state.\n Your wallet will prompt you to sign when ready.\n </p>\n </div>\n );\n }\n\n if (step === 'signing-transaction') {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Action Required:</strong> Please approve the transaction in {walletName}\n {walletType === 'metamask' && (\n <> — you may see two prompts (message signature, then on-chain transaction)</>\n )}\n </p>\n </div>\n );\n }\n\n if (step === 'retrieving-key') {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n <path d=\"M12 8l4 4-4 4\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Transaction submitted:</strong> Waiting for confirmation and retrieving your AES key.\n </p>\n </div>\n );\n }\n\n if (\n step === 'validating-key'\n || step === 'restoring-network'\n || step === 'persisting-key'\n || step === 'saving-backup'\n ) {\n return (\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Finalizing:</strong> Securing your AES key and refreshing private balances.\n </p>\n </div>\n );\n }\n\n return null;\n };\n // Handle copy to clipboard\n const handleCopy = async () => {\n if (!aesKey) return;\n try {\n await navigator.clipboard.writeText(aesKey);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n logger.error('Failed to copy AES key:', err);\n }\n };\n\n const handleManualAesKeySubmit = async () => {\n if (!onManualAesKeySubmit) return;\n\n const key = manualAesKey.trim();\n setManualAesKeyError(null);\n\n if (!key) {\n setManualAesKeyError('AES key is required.');\n return;\n }\n\n let normalizedKey: string;\n try {\n normalizedKey = normalizeAesKey(key);\n } catch {\n setManualAesKeyError('Wrong AES key');\n return;\n }\n\n setIsSubmittingManualKey(true);\n try {\n await onManualAesKeySubmit(normalizedKey, { saveBackup });\n setManualAesKey('');\n setShowManualKeyInput(false);\n } catch (err: unknown) {\n setManualAesKeyError(err instanceof Error ? err.message : 'Could not save AES key.');\n } finally {\n setIsSubmittingManualKey(false);\n }\n };\n\n if (!isOpen) {\n return null;\n }\n\n // Disable close button during signing-transaction step\n const canClose = currentStep !== 'signing-transaction';\n\n return (\n <>\n {/* Inject spinner keyframes */}\n <style>{SPINNER_KEYFRAMES}</style>\n\n {/* Backdrop */}\n <div\n style={styles.backdrop}\n onClick={canClose ? onClose : undefined}\n role=\"presentation\"\n >\n {/* Modal */}\n <div\n style={styles.modal}\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"onboard-modal-title\"\n {...(hasDescription ? { 'aria-describedby': 'onboard-modal-description' } : {})}\n >\n {/* Close Button */}\n {canClose && (\n <button\n onClick={onClose}\n style={styles.closeButton}\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n\n {/* INTRO SCREEN */}\n {showIntro && (\n <>\n {renderTitleRow(\n <svg\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#00E5FF\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>,\n 'Onboard User',\n )}\n\n <p id=\"onboard-modal-description\" style={styles.description}>\n This will execute a transaction on the COTI Network to retrieve your encryption key.\n </p>\n\n {warning && (\n <div style={warningStyles.box}>\n <p style={warningStyles.text}>{warning}</p>\n </div>\n )}\n\n {renderSaveLocallyOption()}\n\n <div\n style={{\n ...styles.actionRow,\n marginBottom: onManualAesKeySubmit ? 0 : styles.actionRow.marginBottom,\n }}\n >\n {showManualKeyInput ? (\n <>\n <input\n type=\"text\"\n value={manualAesKey}\n onChange={(event) => setManualAesKey(event.target.value)}\n placeholder=\"Paste AES key\"\n aria-label=\"Manual AES key\"\n disabled={isSubmittingManualKey}\n style={{ ...styles.manualKeyInput, ...styles.actionPrimary }}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <button\n type=\"button\"\n onClick={handleManualAesKeySubmit}\n disabled={isSubmittingManualKey || !manualAesKey.trim()}\n aria-label=\"Use AES key\"\n style={isSubmittingManualKey || !manualAesKey.trim() ? styles.iconButtonDisabled : styles.iconButton}\n >\n {isSubmittingManualKey ? (\n <div style={{ ...styles.spinner, width: '14px', height: '14px' }} />\n ) : (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={onConfirm}\n style={{\n ...styles.primaryButton,\n ...styles.actionPrimary,\n ...styles.actionFieldButton,\n }}\n >\n Onboard\n </button>\n )}\n\n {onManualAesKeySubmit && (\n <button\n type=\"button\"\n onClick={() => {\n setShowManualKeyInput((visible) => !visible);\n setManualAesKey('');\n setManualAesKeyError(null);\n }}\n disabled={isSubmittingManualKey}\n aria-label={showManualKeyInput ? 'Hide AES key input' : 'Input AES key'}\n aria-pressed={showManualKeyInput}\n title={showManualKeyInput ? 'Hide AES key input' : 'Input AES key'}\n style={showManualKeyInput ? styles.iconButtonPressed : styles.iconButton}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\" />\n <path d=\"M6 10h.01M10 10h.01M14 10h.01M18 10h.01M7 14h10\" />\n </svg>\n </button>\n )}\n </div>\n\n {onManualAesKeySubmit && (\n <div style={styles.manualKeyErrorRow}>\n <div style={styles.manualKeyErrorColumn}>\n {manualAesKeyError && (\n <p style={styles.manualKeyErrorText}>{manualAesKeyError}</p>\n )}\n </div>\n {showManualKeyInput && <div style={styles.actionSideSpacer} aria-hidden=\"true\" />}\n <div style={styles.actionSideSpacer} aria-hidden=\"true\" />\n </div>\n )}\n\n <button\n onClick={onClose}\n style={styles.cancelButton}\n >\n Cancel\n </button>\n </>\n )}\n\n {/* PROGRESS SCREEN */}\n {showProgress && (\n <>\n {renderTitleRow(\n <div style={styles.spinner} />,\n getProgressTitle(currentStep),\n )}\n\n {warning && (\n <div style={warningStyles.box}>\n <p style={warningStyles.text}>{warning}</p>\n </div>\n )}\n\n {/* Step Progress */}\n <div style={styles.stepperContainer}>\n {displaySteps.map((step) => {\n const status = getOnboardingStepStatus(step.id, currentStep, !!error, includePersistStep);\n const isActive = status === 'active';\n const isComplete = status === 'complete';\n const isError = status === 'error';\n\n let iconStyle: React.CSSProperties = { ...styles.stepIconContainer, ...styles.stepIconPending };\n if (isActive) iconStyle = { ...styles.stepIconContainer, ...styles.stepIconActive };\n if (isComplete) iconStyle = { ...styles.stepIconContainer, ...styles.stepIconComplete };\n if (isError) iconStyle = { ...styles.stepIconContainer, ...styles.stepIconError };\n\n return (\n <div key={step.id} style={styles.stepItem}>\n <div style={iconStyle}>\n {isComplete && (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" strokeWidth=\"3\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )}\n {isActive && <div style={{ ...styles.spinner, width: '12px', height: '12px' }} />}\n {isError && (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ef4444\" strokeWidth=\"3\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )}\n </div>\n <div style={styles.stepContent}>\n <div style={styles.stepLabel}>{step.label}</div>\n <div style={styles.stepDescription}>{step.description}</div>\n </div>\n </div>\n );\n })}\n </div>\n\n <div style={styles.progressCalloutSlot} aria-label=\"Progress action\">\n {renderProgressCallout(currentStep)}\n </div>\n </>\n )}\n\n {/* SUCCESS SCREEN */}\n {showSuccess && (\n <>\n {renderTitleRow(\n <svg\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#22c55e\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\" />\n <polyline points=\"22 4 12 14.01 9 11.01\" />\n </svg>,\n 'Onboarding Complete',\n )}\n\n <p id=\"onboard-modal-description\" style={styles.description}>\n Your encryption key has been successfully retrieved.\n </p>\n\n <div style={styles.keyInputWrap}>\n <input\n type={isAesVisible ? 'text' : 'password'}\n value={aesKey ?? ''}\n readOnly\n aria-label=\"Retrieved AES key\"\n style={styles.keyInput}\n autoComplete=\"off\"\n spellCheck={false}\n />\n <div style={styles.keyInputActions}>\n <button\n type=\"button\"\n onClick={() => setIsAesVisible((visible) => !visible)}\n aria-label={isAesVisible ? 'Hide AES key' : 'Show AES key'}\n title={isAesVisible ? 'Hide AES key' : 'Show AES key'}\n style={styles.inlineIconButton}\n >\n {isAesVisible ? (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M17.94 17.94A10.94 10.94 0 0 1 12 20C7 20 2.73 16.89 1 12a18.45 18.45 0 0 1 5.06-6.06\" />\n <path d=\"M9.9 4.24A10.45 10.45 0 0 1 12 4c5 0 9.27 3.11 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n <path d=\"M14.12 14.12A3 3 0 0 1 9.88 9.88\" />\n <path d=\"M1 1l22 22\" />\n </svg>\n ) : (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </button>\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy AES key\"\n title={copied ? 'Copied' : 'Copy AES key'}\n style={styles.inlineIconButton}\n >\n {copied ? (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n )}\n </button>\n </div>\n </div>\n\n <div style={warningStyles.box}>\n <p style={warningStyles.text}>\n <strong>Important:</strong> {saveBackup ? 'An encrypted backup can help restore this key later, but you should still store it safely.' : 'This key will be lost when you refresh the page. Store it in a secure location.'}\n </p>\n </div>\n\n {warning && (\n <div style={warningStyles.box}>\n <p style={warningStyles.text}>{warning}</p>\n </div>\n )}\n\n <button\n onClick={onClose}\n style={styles.primaryButton}\n >\n Done\n </button>\n </>\n )}\n\n {/* ERROR SCREEN */}\n {showError && (\n <>\n {renderTitleRow(\n <svg\n width=\"22\"\n height=\"22\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#f87171\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>,\n 'Onboarding Failed',\n )}\n\n <p id=\"onboard-modal-description\" style={styles.description}>\n The onboarding process encountered an error. You can retry the signature request.\n </p>\n\n <div style={styles.errorBox}>\n <p style={styles.errorText}>{error || 'An unknown error occurred'}</p>\n </div>\n\n <button\n onClick={onConfirm}\n style={styles.primaryButton}\n >\n Retry\n </button>\n\n <button\n onClick={onClose}\n style={styles.cancelButton}\n >\n Cancel\n </button>\n </>\n )}\n </div>\n </div>\n </>\n );\n};\n\n/** Default styles exported for reference when building custom themes */\nexport { defaultStyles as onboardModalDefaultStyles };\n\nexport default OnboardModal;\n","import type { WalletType } from '../hooks/useWalletType';\n\nexport function getWalletDisplayName(walletType: WalletType): string {\n switch (walletType) {\n case 'coinbase':\n return 'Coinbase Wallet';\n case 'walletconnect':\n return 'WalletConnect';\n case 'metamask':\n return 'MetaMask';\n case 'rainbow':\n return 'Rainbow Wallet';\n default:\n return 'your wallet';\n }\n}\n","import {\n ONBOARDING_STEPS,\n type OnboardingStep,\n} from '../hooks/useAesKeyProvider';\n\nexport type OnboardingStepStatus = 'pending' | 'active' | 'complete' | 'error';\n\nexport function getDisplayOnboardingSteps(includePersistStep = true) {\n if (includePersistStep) return ONBOARDING_STEPS;\n return ONBOARDING_STEPS.filter(step => step.id !== 'persisting-key');\n}\n\nexport function getVisibleOnboardingStep(\n stepId: OnboardingStep,\n includePersistStep = true,\n): OnboardingStep {\n switch (stepId) {\n case 'restoring-backup':\n case 'granting-funds':\n case 'waiting-for-funds':\n case 'switching-network':\n case 'creating-provider':\n case 'preparing-onboard':\n return 'preparing-onboard';\n case 'validating-key':\n case 'restoring-network':\n case 'persisting-key':\n case 'saving-backup':\n return includePersistStep ? 'persisting-key' : 'retrieving-key';\n default:\n return stepId;\n }\n}\n\nexport function getOnboardingStepStatus(\n stepId: OnboardingStep,\n currentStep: OnboardingStep,\n hasError: boolean,\n includePersistStep = true,\n): OnboardingStepStatus {\n const visibleCurrentStep = getVisibleOnboardingStep(currentStep, includePersistStep);\n\n if (hasError && (currentStep === 'error' || visibleCurrentStep === 'error')) {\n return 'error';\n }\n\n const displaySteps = getDisplayOnboardingSteps(includePersistStep);\n const stepIndex = displaySteps.findIndex(step => step.id === stepId);\n const currentIndex = displaySteps.findIndex(step => step.id === visibleCurrentStep);\n\n if (currentIndex === -1) return 'pending';\n if (visibleCurrentStep === 'complete') return 'complete';\n if (stepIndex < currentIndex) return 'complete';\n if (stepIndex === currentIndex) return 'active';\n return 'pending';\n}\n\nexport function getProgressTitle(currentStep: OnboardingStep): string {\n if (currentStep === 'granting-funds') return 'Requesting COTI Grant';\n if (currentStep === 'waiting-for-funds') return 'Waiting for Grant Funds';\n return 'Onboarding in Progress';\n}\n\nexport function getProgressDescription(currentStep: OnboardingStep): string {\n if (currentStep === 'granting-funds') {\n return 'Waiting for the grant service to fund your wallet before onboarding continues...';\n }\n if (currentStep === 'waiting-for-funds') {\n return 'The grant request was submitted. Waiting for the native COTI balance to update...';\n }\n return 'Please wait while we retrieve your AES encryption key...';\n}\n","import type { OnboardingStep } from '../../hooks/useAesKeyProvider';\n\nexport type OnboardScreen = 'intro' | 'progress' | 'success' | 'error' | 'none';\n\nexport interface DeriveOnboardScreenInput {\n currentStep: OnboardingStep;\n isLoading: boolean;\n error: string | null;\n aesKey?: string | null;\n}\n\nexport function deriveOnboardScreen({\n currentStep,\n isLoading,\n error,\n aesKey,\n}: DeriveOnboardScreenInput): OnboardScreen {\n if (error || currentStep === 'error') return 'error';\n if (currentStep === 'complete' && aesKey) return 'success';\n if (currentStep === 'idle' && !aesKey) return 'intro';\n\n if (\n isLoading\n || (\n currentStep !== 'idle'\n && currentStep !== 'complete'\n && currentStep !== 'signing-backup'\n && !aesKey\n )\n ) {\n return 'progress';\n }\n\n return 'none';\n}\n","import React from 'react';\nimport type { WalletType } from '../hooks/useWalletType';\nimport { mergeOnboardModalTheme, type OnboardModalTheme } from './OnboardModal';\nimport { getWalletDisplayName } from '../lib/walletDisplayName';\n\nconst SPINNER_KEYFRAMES = `\n@keyframes wallet-sign-spin {\n to { transform: rotate(360deg); }\n}\n`;\n\nexport type WalletSignPromptPurpose = 'decrypt-backup' | 'save-backup';\n\nexport interface WalletSignPromptProps {\n isOpen: boolean;\n walletType: WalletType;\n theme?: OnboardModalTheme;\n purpose?: WalletSignPromptPurpose;\n}\n\nfunction getPurposeDescription(purpose: WalletSignPromptPurpose, walletName: string): string {\n if (purpose === 'save-backup') {\n return `Approve the signature in ${walletName} to encrypt and save your AES key backup.`;\n }\n\n return `Approve the signature in ${walletName} to decrypt your encrypted backup and unlock private balances.`;\n}\n\nexport const WalletSignPrompt: React.FC<WalletSignPromptProps> = ({\n isOpen,\n walletType,\n theme,\n purpose = 'decrypt-backup',\n}) => {\n if (!isOpen) return null;\n\n const styles = mergeOnboardModalTheme(theme);\n const walletName = getWalletDisplayName(walletType);\n\n return (\n <>\n <style>{SPINNER_KEYFRAMES}</style>\n <div\n style={{ ...styles.backdrop, zIndex: 60 }}\n role=\"presentation\"\n data-testid=\"wallet-sign-prompt\"\n >\n <div\n style={{ ...styles.modal, width: '320px', padding: '24px' }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"wallet-sign-prompt-title\"\n aria-describedby=\"wallet-sign-prompt-description\"\n >\n <div style={styles.titleRow}>\n <div style={styles.iconContainer}>\n <div style={{ ...styles.spinner, animation: 'wallet-sign-spin 0.8s linear infinite' }} />\n </div>\n <h2 id=\"wallet-sign-prompt-title\" style={styles.title}>\n Sign in your wallet\n </h2>\n </div>\n\n <p id=\"wallet-sign-prompt-description\" style={styles.description}>\n {getPurposeDescription(purpose, walletName)}\n </p>\n\n <div style={styles.calloutBox}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00E5FF\" strokeWidth=\"2\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <p style={styles.calloutText}>\n <strong>Waiting for signature</strong> — this screen closes automatically after you sign.\n </p>\n </div>\n </div>\n </div>\n </>\n );\n};\n\nexport default WalletSignPrompt;\n","import React, { useMemo } from 'react';\nimport { type Chain } from 'viem';\nimport { createConfig, http, fallback, WagmiProvider, type Config } from 'wagmi';\nimport { connectorsForWallets } from '@rainbow-me/rainbowkit';\nimport { metaMaskWallet } from '@rainbow-me/rainbowkit/wallets';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { RainbowKitProvider } from '@rainbow-me/rainbowkit';\nimport {\n cotiMainnet,\n cotiTestnet,\n sepolia,\n avalancheFuji,\n COTI_MAINNET_RPC,\n COTI_TESTNET_RPC,\n SEPOLIA_RPC,\n SEPOLIA_RPC_FALLBACK,\n AVALANCHE_FUJI_RPC,\n AVALANCHE_FUJI_RPC_FALLBACK,\n} from '../config/chains';\nimport { getPluginConfig } from '../config/plugin';\nimport { resolveWalletConnectProjectId } from '../config/walletConnect';\nimport { eip6963MetaMaskWallet } from './eip6963MetaMaskWallet';\nimport { mobileMetaMaskWallet } from './mobileMetaMaskWallet';\nimport { mobileRabbyWallet } from './mobileRabbyWallet';\nimport { mobileOneKeyWallet } from './mobileOneKeyWallet';\nimport { mobileZerionWallet } from './mobileZerionWallet';\n\nexport interface WagmiConfigOptions {\n useEip6963MetaMask?: boolean;\n multiInjectedProviderDiscovery?: boolean;\n}\n\n/** RainbowKit-compatible mobile detection (iOS, Android, iPad). */\nconst isMobileBrowser = (): boolean => {\n if (typeof navigator === 'undefined') return false;\n return (\n /android|iphone|ipod/i.test(navigator.userAgent)\n || (/ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1))\n );\n};\n\nfunction getWalletGroups(\n projectId: string,\n useEip6963MetaMask = false,\n) {\n const metaMaskConnector = () => mobileMetaMaskWallet({ projectId });\n const rabbyConnector = () => mobileRabbyWallet({ projectId });\n const oneKeyConnector = () => mobileOneKeyWallet({ projectId });\n const zerionConnector = () => mobileZerionWallet({ projectId });\n\n if (isMobileBrowser()) {\n return [\n {\n groupName: 'Recommended',\n wallets: [metaMaskConnector],\n },\n {\n groupName: 'Other Wallets',\n wallets: [rabbyConnector, oneKeyConnector, zerionConnector],\n },\n ];\n }\n\n const desktopMetaMask = useEip6963MetaMask ? eip6963MetaMaskWallet : metaMaskWallet;\n\n return [\n {\n groupName: 'Recommended',\n wallets: [desktopMetaMask],\n },\n {\n groupName: 'Other Wallets',\n wallets: [rabbyConnector, oneKeyConnector, zerionConnector],\n },\n ];\n}\n\ninterface WagmiRainbowKitProviderProps {\n children: React.ReactNode;\n /** WalletConnect Cloud project ID (falls back to configureCotiPlugin or VITE_WALLETCONNECT_PROJECT_ID). */\n walletConnectProjectId?: string;\n /** Override the chain pre-selected in the RainbowKit connect modal. Defaults to cotiTestnet. */\n initialChain?: Chain;\n /** Override the app name shown in the RainbowKit modal. Defaults to 'COTI Wallet'. */\n appName?: string;\n /**\n * When true, replaces the standard metaMaskWallet connector with an EIP-6963\n * discovered provider connector, preventing window.ethereum hijacking by\n * other installed wallets (Rabby, Phantom, Trust).\n * Default: false (keeps existing behaviour).\n */\n useEip6963MetaMask?: boolean;\n}\n\nfunction createWagmiConfig(\n walletConnectProjectId?: string,\n options: WagmiConfigOptions = {},\n) {\n const {\n useEip6963MetaMask = false,\n multiInjectedProviderDiscovery = true,\n } = options;\n const projectId = resolveWalletConnectProjectId(walletConnectProjectId);\n\n const connectors = connectorsForWallets(\n getWalletGroups(projectId, useEip6963MetaMask),\n {\n appName: 'COTI Wallet Plugin',\n projectId,\n },\n );\n\n const pluginConfig = getPluginConfig();\n const sepoliaTransport = pluginConfig.sepoliaRpcUrl\n ? http(pluginConfig.sepoliaRpcUrl)\n : fallback([http(SEPOLIA_RPC), http(SEPOLIA_RPC_FALLBACK)]);\n\n return createConfig({\n chains: [sepolia, cotiTestnet, cotiMainnet, avalancheFuji],\n connectors,\n multiInjectedProviderDiscovery,\n ssr: false,\n transports: {\n [sepolia.id]: sepoliaTransport,\n [cotiMainnet.id]: http(COTI_MAINNET_RPC),\n [cotiTestnet.id]: http(COTI_TESTNET_RPC),\n [avalancheFuji.id]: fallback([http(AVALANCHE_FUJI_RPC), http(AVALANCHE_FUJI_RPC_FALLBACK)]),\n },\n });\n}\n\nconst queryClient = new QueryClient();\n\nfunction getWagmiConfigCacheKey(\n walletConnectProjectId?: string,\n options: WagmiConfigOptions = {},\n): string {\n const pluginConfig = getPluginConfig();\n const projectId = resolveWalletConnectProjectId(walletConnectProjectId);\n const sepoliaRpc = pluginConfig.sepoliaRpcUrl ?? `${SEPOLIA_RPC}|${SEPOLIA_RPC_FALLBACK}`;\n const mobile = isMobileBrowser();\n const eip6963 = options.useEip6963MetaMask ? '1' : '0';\n const mipd = options.multiInjectedProviderDiscovery === false ? '0' : '1';\n return `${projectId}|${sepoliaRpc}|${mobile ? 'mobile' : 'desktop'}|${eip6963}|${mipd}`;\n}\n\nlet cachedWagmiConfig: { key: string; config: Config } | undefined;\n\nfunction getCachedWagmiConfig(\n walletConnectProjectId?: string,\n options: WagmiConfigOptions = {},\n): Config {\n const key = getWagmiConfigCacheKey(walletConnectProjectId, options);\n if (cachedWagmiConfig?.key === key) {\n return cachedWagmiConfig.config;\n }\n const config = createWagmiConfig(walletConnectProjectId, options);\n cachedWagmiConfig = { key, config };\n return config;\n}\n\n/**\n * Builds wagmi config from current {@link getPluginConfig} and optional WalletConnect project ID.\n * Returns a stable instance for unchanged plugin settings (safe for `wagmiConfig` and render).\n * Prefer {@link WagmiRainbowKitProvider} in React apps; use this for non-React wagmi setup.\n */\nexport function getWagmiConfig(\n walletConnectProjectId?: string,\n options: WagmiConfigOptions = {},\n) {\n return getCachedWagmiConfig(walletConnectProjectId, options);\n}\n\n/**\n * Default wagmi config (backward-compatible export).\n * Lazily initialized on first property access — requires a configured WalletConnect project ID.\n * Rebuilt when {@link configureCotiPlugin} changes wagmi-relevant settings.\n */\nexport const wagmiConfig: Config = new Proxy({} as Config, {\n get(_target, prop, receiver) {\n const config = getCachedWagmiConfig();\n const value = Reflect.get(config as object, prop, receiver);\n return typeof value === 'function' ? (value as (...args: unknown[]) => unknown).bind(config) : value;\n },\n});\n\n/**\n * Wraps children with wagmi WagmiProvider, React Query QueryClientProvider,\n * and RainbowKitProvider. Single entry point for multi-wallet support.\n */\nexport function WagmiRainbowKitProvider({\n children,\n walletConnectProjectId,\n initialChain = cotiTestnet,\n appName = 'COTI Wallet',\n useEip6963MetaMask = false,\n}: WagmiRainbowKitProviderProps) {\n const pluginConfig = getPluginConfig();\n const config = useMemo(\n () => createWagmiConfig(walletConnectProjectId, {\n useEip6963MetaMask,\n }),\n [\n walletConnectProjectId,\n useEip6963MetaMask,\n pluginConfig.sepoliaRpcUrl,\n pluginConfig.walletConnectProjectId,\n ],\n );\n\n return (\n <WagmiProvider config={config} reconnectOnMount={false}>\n <QueryClientProvider client={queryClient}>\n <RainbowKitProvider\n initialChain={initialChain}\n modalSize=\"compact\"\n appInfo={{ appName }}\n >\n {children}\n </RainbowKitProvider>\n </QueryClientProvider>\n </WagmiProvider>\n );\n}\n","import { CotiPluginError, CotiErrorCode } from '../errors';\nimport { getPluginConfig } from '../config/plugin';\n\nconst MISSING_WC_MESSAGE =\n 'WalletConnect project ID is required. Pass walletConnectProjectId to WagmiRainbowKitProvider, ' +\n 'set configureCotiPlugin({ walletConnectProjectId }), or define VITE_WALLETCONNECT_PROJECT_ID.';\n\n/**\n * Resolves the WalletConnect Cloud project ID from prop, plugin config, or Vite env.\n * @throws {CotiPluginError} when no project ID is configured\n */\nexport function resolveWalletConnectProjectId(override?: string): string {\n const fromProp = override?.trim();\n if (fromProp) return fromProp;\n\n const fromPlugin = getPluginConfig().walletConnectProjectId?.trim();\n if (fromPlugin) return fromPlugin;\n\n const fromEnv = globalThis.process?.env?.VITE_WALLETCONNECT_PROJECT_ID?.trim();\n if (fromEnv) return fromEnv;\n\n throw new CotiPluginError(CotiErrorCode.WALLETCONNECT_PROJECT_ID_MISSING, MISSING_WC_MESSAGE);\n}\n","import { injected } from 'wagmi/connectors';\nimport type { Wallet } from '@rainbow-me/rainbowkit';\nimport { resolveMetaMaskInjectedTarget } from '../lib/ethereum';\nimport { asInjectedTarget } from './injectedTarget';\n\n/**\n * RainbowKit wallet factory that connects via EIP-6963-discovered MetaMask provider,\n * avoiding window.ethereum hijacking by other installed wallets.\n */\nexport const eip6963MetaMaskWallet = (): Wallet => ({\n id: 'io.metamask',\n name: 'MetaMask',\n rdns: 'io.metamask',\n iconUrl: 'https://raw.githubusercontent.com/MetaMask/brand-resources/master/SVG/metamask-fox.svg',\n iconBackground: '#fff',\n downloadUrls: {\n android: 'https://play.google.com/store/apps/details?id=io.metamask',\n ios: 'https://apps.apple.com/us/app/metamask/id1438144202',\n mobile: 'https://metamask.io/download',\n qrCode: 'https://metamask.io/download',\n chrome: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',\n edge: 'https://microsoftedge.microsoft.com/addons/detail/metamask/ejbalbakoplchlghecdalmeeeajnimhm',\n firefox: 'https://addons.mozilla.org/firefox/addon/ether-metamask',\n opera: 'https://addons.opera.com/extensions/details/metamask-10',\n browserExtension: 'https://metamask.io/download',\n },\n createConnector: (walletDetails) =>\n (config) => {\n const base = injected({\n target: asInjectedTarget(resolveMetaMaskInjectedTarget),\n })(config);\n return {\n ...base,\n ...walletDetails,\n connect: base.connect.bind(base),\n disconnect: base.disconnect.bind(base),\n getProvider: base.getProvider.bind(base),\n getAccounts: base.getAccounts.bind(base),\n getChainId: base.getChainId.bind(base),\n };\n },\n});\n","import { injected } from 'wagmi/connectors';\n\ntype InjectedOptions = NonNullable<Parameters<typeof injected>[0]>;\ntype InjectedTarget = NonNullable<InjectedOptions['target']>;\n\n/** Wagmi's injected target type is stricter than EIP-1193 provider discovery. */\nexport const asInjectedTarget = (target: unknown): InjectedTarget =>\n target as InjectedTarget;\n","import { createConnector } from 'wagmi';\nimport { injected, walletConnect } from 'wagmi/connectors';\nimport type { Wallet } from '@rainbow-me/rainbowkit';\nimport { asInjectedTarget } from './injectedTarget';\n\nfunction isMobileBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /android|iphone|ipod/i.test(navigator.userAgent)\n || /ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n}\n\nfunction isMetaMaskInjected(): boolean {\n if (typeof window === 'undefined') return false;\n const eth = window.ethereum as Record<string, unknown> | undefined;\n if (!eth) return false;\n if (eth.providers && Array.isArray(eth.providers)) {\n return eth.providers.some(\n (p: Record<string, unknown>) => p.isMetaMask && !p.isRabby && !p.isPhantom && !p.isTrust,\n );\n }\n return !!eth.isMetaMask && !eth.isRabby && !eth.isPhantom && !eth.isTrust;\n}\n\nfunction isMetaMaskMobileInAppBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /MetaMaskMobile/i.test(navigator.userAgent);\n}\n\n/**\n * RainbowKit wallet factory for MetaMask that works on both desktop (injected) and\n * mobile (WalletConnect deep link), ensuring it is always visible in the mobile\n * Recommended list even when the browser extension is not present.\n *\n * Mobile deep link: https://metamask.app.link/wc?uri=<encoded-wc-uri>\n */\nexport const mobileMetaMaskWallet = ({ projectId }: { projectId: string }): Wallet => {\n const mobile = isMobileBrowser();\n const insideMetaMaskInApp = isMetaMaskMobileInAppBrowser();\n const shouldUseWalletConnect = (mobile && !insideMetaMaskInApp) || (!insideMetaMaskInApp && !isMetaMaskInjected());\n\n return {\n id: 'metamask',\n name: 'MetaMask',\n rdns: 'io.metamask',\n iconUrl: 'https://raw.githubusercontent.com/MetaMask/brand-resources/master/SVG/metamask-fox.svg',\n iconBackground: '#fff',\n installed: isMetaMaskInjected() || undefined,\n downloadUrls: {\n android: 'https://play.google.com/store/apps/details?id=io.metamask',\n ios: 'https://apps.apple.com/us/app/metamask/id1438144202',\n mobile: 'https://metamask.io/download',\n qrCode: 'https://metamask.io/download/',\n chrome: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn',\n browserExtension: 'https://metamask.io/download/',\n },\n mobile: {\n getUri: shouldUseWalletConnect\n ? (uri: string) => `https://metamask.app.link/wc?uri=${encodeURIComponent(uri)}`\n : undefined,\n },\n qrCode: shouldUseWalletConnect\n ? {\n getUri: (uri: string) => uri,\n instructions: {\n learnMoreUrl: 'https://metamask.io/download/',\n steps: [\n {\n step: 'install',\n title: 'Open the MetaMask app',\n description: 'Download MetaMask on your mobile device from the App Store or Google Play.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet inside the MetaMask mobile app.',\n },\n {\n step: 'scan',\n title: 'Scan the QR code',\n description: 'Tap the scan icon in MetaMask and scan the QR code to connect.',\n },\n ],\n },\n }\n : undefined,\n extension: {\n instructions: {\n learnMoreUrl: 'https://metamask.io/download/',\n steps: [\n {\n step: 'install',\n title: 'Install the MetaMask extension',\n description: 'Install MetaMask from the Chrome Web Store.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet in the MetaMask browser extension.',\n },\n {\n step: 'refresh',\n title: 'Refresh this page',\n description: 'Refresh the page to connect with MetaMask.',\n },\n ],\n },\n },\n createConnector: (walletDetails) =>\n shouldUseWalletConnect\n ? createConnector((config) => ({\n ...walletConnect({ projectId, showQrModal: false })(config),\n ...walletDetails,\n }))\n : createConnector((config) => ({\n ...injected({\n target: asInjectedTarget(() => {\n const eth = (window as unknown as { ethereum?: Record<string, unknown> }).ethereum;\n if (eth?.providers && Array.isArray(eth.providers)) {\n const mm = eth.providers.find(\n (p: Record<string, unknown>) =>\n p.isMetaMask && !p.isRabby && !p.isPhantom && !p.isTrust,\n );\n if (mm) return { id: 'metamask', name: 'MetaMask', provider: mm };\n }\n return { id: 'metamask', name: 'MetaMask', provider: eth };\n }),\n })(config),\n ...walletDetails,\n })),\n };\n};\n","import { createConnector } from 'wagmi';\nimport { injected, walletConnect } from 'wagmi/connectors';\nimport type { Wallet } from '@rainbow-me/rainbowkit';\nimport { asInjectedTarget } from './injectedTarget';\n\n/**\n * Returns true when running in a mobile browser (iOS or Android).\n * Mirrors RainbowKit's internal isMobile() utility.\n */\nfunction isMobileBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /android|iphone|ipod/i.test(navigator.userAgent)\n || /ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n}\n\n/**\n * RainbowKit wallet factory for Rabby that works on both desktop (injected) and\n * mobile (WalletConnect deep link), ensuring it is always visible in the mobile\n * Recommended list even when the browser extension is not present.\n *\n * Mobile deep link: rabby://wc?uri=<encoded-wc-uri>\n * Fallback QR: https://rabby.io/download\n */\nexport const mobileRabbyWallet = ({ projectId }: { projectId: string }): Wallet => {\n const isRabbyInjected = typeof window !== 'undefined'\n && !!(window.ethereum as Record<string, unknown> | undefined)?.['isRabby'];\n\n // On mobile the extension is never injected — always use WalletConnect.\n const mobile = isMobileBrowser();\n const shouldUseWalletConnect = mobile || !isRabbyInjected;\n\n return {\n id: 'rabby',\n name: 'Rabby Wallet',\n rdns: 'io.rabby',\n iconUrl: 'https://rabby.io/favicon.png',\n iconBackground: '#8697FF',\n // Never set installed:false — that causes RainbowKit to hide the wallet.\n // Leaving it undefined defaults to \"ready\" (shown).\n installed: isRabbyInjected || undefined,\n downloadUrls: {\n android: 'https://play.google.com/store/apps/details?id=com.debank.rabbymobile',\n ios: 'https://apps.apple.com/us/app/rabby-wallet-crypto-evm/id6474381673',\n mobile: 'https://rabby.io/download',\n qrCode: 'https://rabby.io/download',\n chrome: 'https://chrome.google.com/webstore/detail/rabby-wallet/acmacodkjbdgmoleebolmdjonilkdbch',\n browserExtension: 'https://rabby.io',\n },\n // Mobile deep link — opens the Rabby app directly via WalletConnect URI.\n mobile: {\n getUri: shouldUseWalletConnect\n ? (uri: string) => `rabby://wc?uri=${encodeURIComponent(uri)}`\n : undefined,\n },\n // QR code for scanning from desktop.\n qrCode: shouldUseWalletConnect\n ? {\n getUri: (uri: string) => uri,\n instructions: {\n learnMoreUrl: 'https://rabby.io/',\n steps: [\n {\n step: 'install',\n title: 'Open the Rabby app',\n description: 'Download Rabby Wallet on your mobile device from the App Store or Google Play.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet inside the Rabby mobile app.',\n },\n {\n step: 'scan',\n title: 'Scan the QR code',\n description: 'Tap the scan icon in Rabby and scan the QR code to connect.',\n },\n ],\n },\n }\n : undefined,\n extension: {\n instructions: {\n learnMoreUrl: 'https://rabby.io/',\n steps: [\n {\n step: 'install',\n title: 'Install the Rabby extension',\n description: 'Install Rabby Wallet from the Chrome Web Store.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet in the Rabby browser extension.',\n },\n {\n step: 'refresh',\n title: 'Refresh this page',\n description: 'Refresh the page to connect with Rabby Wallet.',\n },\n ],\n },\n },\n createConnector: (walletDetails) =>\n shouldUseWalletConnect\n ? createConnector((config) => ({\n ...walletConnect({ projectId, showQrModal: false })(config),\n ...walletDetails,\n }))\n : createConnector((config) => ({\n ...injected({\n target: asInjectedTarget({\n id: 'rabby',\n name: 'Rabby Wallet',\n provider: (window as unknown as { ethereum?: unknown }).ethereum,\n }),\n })(config),\n ...walletDetails,\n })),\n };\n};\n","import { createConnector } from 'wagmi';\nimport { injected, walletConnect } from 'wagmi/connectors';\nimport type { Wallet } from '@rainbow-me/rainbowkit';\nimport { asInjectedTarget } from './injectedTarget';\n\n/**\n * Returns true when running in a mobile browser (iOS or Android).\n * Mirrors RainbowKit's internal isMobile() utility.\n */\nfunction isMobileBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /android|iphone|ipod/i.test(navigator.userAgent)\n || /ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n}\n\n/**\n * RainbowKit wallet factory for OneKey that works on both desktop (injected via\n * $onekey.ethereum) and mobile (WalletConnect deep link), ensuring it is always\n * visible in the mobile Recommended list even when the extension is not present.\n *\n * Mobile universal link: https://onekeywallet.app.link/wc?uri=<encoded-wc-uri>\n */\nexport const mobileOneKeyWallet = ({ projectId }: { projectId: string }): Wallet => {\n const isOneKeyInjected = typeof window !== 'undefined'\n && !!(window as unknown as Record<string, unknown>)['$onekey'];\n\n // On mobile the extension is never injected — always use WalletConnect.\n const mobile = isMobileBrowser();\n const shouldUseWalletConnect = mobile || !isOneKeyInjected;\n\n return {\n id: 'onekey',\n name: 'OneKey',\n rdns: 'so.onekey.app.wallet',\n iconUrl: 'https://common.onekey-asset.com/logo/onekey-x256.png',\n iconBackground: '#44D62C',\n // Never set installed:false — that causes RainbowKit to hide the wallet.\n installed: isOneKeyInjected || undefined,\n downloadUrls: {\n android: 'https://play.google.com/store/apps/details?id=so.onekey.app.wallet',\n ios: 'https://apps.apple.com/us/app/onekey-open-source-wallet/id1609559473',\n mobile: 'https://www.onekey.so/download/',\n qrCode: 'https://www.onekey.so/download/',\n chrome: 'https://chrome.google.com/webstore/detail/onekey/jnmbobjmhlngoefaiojfljckilhhlhcj',\n edge: 'https://microsoftedge.microsoft.com/addons/detail/onekey/obffkkagpmohennipjokmpllocnlndac',\n browserExtension: 'https://www.onekey.so/download/',\n },\n // Mobile deep link — opens the OneKey app directly via WalletConnect URI.\n // OneKey uses a universal link (https://onekeywallet.app.link/wc) which\n // works reliably across iOS and Android without custom URI scheme issues.\n mobile: {\n getUri: shouldUseWalletConnect\n ? (uri: string) => `https://onekeywallet.app.link/wc?uri=${encodeURIComponent(uri)}`\n : undefined,\n },\n // QR code for scanning from desktop.\n qrCode: shouldUseWalletConnect\n ? {\n getUri: (uri: string) => uri,\n instructions: {\n learnMoreUrl: 'https://help.onekey.so/hc/en-us/categories/360000170236',\n steps: [\n {\n step: 'install',\n title: 'Open the OneKey app',\n description: 'Download OneKey on your mobile device from the App Store or Google Play.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet inside the OneKey mobile app.',\n },\n {\n step: 'scan',\n title: 'Scan the QR code',\n description: 'Tap the scan icon in OneKey and scan the QR code to connect.',\n },\n ],\n },\n }\n : undefined,\n extension: {\n instructions: {\n learnMoreUrl: 'https://help.onekey.so/hc/en-us/categories/360000170236',\n steps: [\n {\n step: 'install',\n title: 'Install the OneKey extension',\n description: 'Install OneKey from the Chrome Web Store or Edge Add-ons.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet in the OneKey browser extension.',\n },\n {\n step: 'refresh',\n title: 'Refresh this page',\n description: 'Refresh the page to connect with OneKey.',\n },\n ],\n },\n },\n createConnector: (walletDetails) =>\n shouldUseWalletConnect\n ? createConnector((config) => ({\n ...walletConnect({ projectId, showQrModal: false })(config),\n ...walletDetails,\n }))\n : createConnector((config) => ({\n ...injected({\n target: asInjectedTarget({\n id: 'onekey',\n name: 'OneKey',\n provider: (window as unknown as { $onekey?: { ethereum?: unknown } }).$onekey?.ethereum,\n }),\n })(config),\n ...walletDetails,\n })),\n };\n};\n","import { createConnector } from 'wagmi';\nimport { injected, walletConnect } from 'wagmi/connectors';\nimport type { Wallet } from '@rainbow-me/rainbowkit';\n\nfunction isMobileBrowser(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /android|iphone|ipod/i.test(navigator.userAgent)\n || /ipad/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n}\n\nfunction isIOS(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /iphone|ipad|ipod/i.test(navigator.userAgent)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);\n}\n\n/**\n * Window CustomEvent fired when a Zerion WalletConnect connection attempt fails\n * for a reason other than the user cancelling. Zerion only approves sessions for\n * networks it already knows, so a host app should listen for this event and show\n * instructions for adding the COTI network manually in Zerion before retrying.\n */\nexport const WALLET_CONNECT_FAILURE_EVENT = 'coti-wallet-plugin:wallet-connect-failure';\n\nexport interface WalletConnectFailureDetail {\n walletId: string;\n message: string;\n}\n\nconst isUserCancellation = (message: string): boolean =>\n /user rejected|user disconnected|connection request reset/i.test(message);\n\nconst dispatchConnectFailure = (walletId: string, error: unknown): void => {\n if (typeof window === 'undefined') return;\n const message = error instanceof Error ? error.message : String(error);\n if (isUserCancellation(message)) return;\n window.dispatchEvent(\n new CustomEvent<WalletConnectFailureDetail>(WALLET_CONNECT_FAILURE_EVENT, {\n detail: { walletId, message },\n }),\n );\n};\n\nconst ZERION_ICON_URL =\n 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cpath%20fill%3D%22%232962EF%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M6.073%207c-.48%200-.665.593-.262.841l10.073%206.074a.577.577%200%200%200%20.758-.139l4.43-5.814c.3-.404-.004-.962-.525-.962H6.073ZM21.904%2021c.48%200%20.67-.596.267-.844l-10.075-6.073a.569.569%200%200%200-.751.146l-4.437%205.813c-.301.404.012.958.534.958h14.462Z%22%2F%3E%3C%2Fsvg%3E';\n\n/**\n * RainbowKit wallet factory for Zerion that works on both desktop (injected via\n * window.zerionWallet) and mobile (WalletConnect deep link), ensuring it is always\n * visible in the Recommended list even when the browser extension is not present.\n *\n * Mobile deep link (iOS): zerion://wc?uri=<encoded-wc-uri>\n */\nexport const mobileZerionWallet = ({ projectId }: { projectId: string }): Wallet => {\n const isZerionInjected = typeof window !== 'undefined'\n && !!(window as unknown as Record<string, unknown>)['zerionWallet'];\n\n const mobile = isMobileBrowser();\n const shouldUseWalletConnect = mobile || !isZerionInjected;\n\n const getUri = (uri: string) =>\n isIOS() ? `zerion://wc?uri=${encodeURIComponent(uri)}` : uri;\n\n return {\n id: 'zerion',\n name: 'Zerion',\n rdns: 'io.zerion.wallet',\n iconUrl: ZERION_ICON_URL,\n iconBackground: '#2962EF',\n installed: isZerionInjected || undefined,\n downloadUrls: {\n android: 'https://play.google.com/store/apps/details?id=io.zerion.android',\n ios: 'https://apps.apple.com/app/apple-store/id1456732565',\n mobile: 'https://link.zerion.io/pt3gdRP0njb',\n qrCode: 'https://link.zerion.io/pt3gdRP0njb',\n chrome: 'https://chrome.google.com/webstore/detail/klghhnkeealcohjjanjjdaeeggmfmlpl',\n browserExtension: 'https://zerion.io/extension',\n },\n mobile: {\n getUri: shouldUseWalletConnect ? getUri : undefined,\n },\n qrCode: shouldUseWalletConnect\n ? {\n getUri,\n instructions: {\n learnMoreUrl: 'https://zerion.io/blog/announcing-the-zerion-smart-wallet/',\n steps: [\n {\n step: 'install',\n title: 'Open the Zerion app',\n description: 'Download Zerion on your mobile device from the App Store or Google Play.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet inside the Zerion mobile app.',\n },\n {\n step: 'scan',\n title: 'Scan the QR code',\n description: 'Tap the scan icon in Zerion and scan the QR code to connect.',\n },\n ],\n },\n }\n : undefined,\n extension: {\n instructions: {\n learnMoreUrl: 'https://help.zerion.io/en/',\n steps: [\n {\n step: 'install',\n title: 'Install the Zerion extension',\n description: 'Install Zerion from the Chrome Web Store.',\n },\n {\n step: 'create',\n title: 'Create or import a wallet',\n description: 'Set up your wallet in the Zerion browser extension.',\n },\n {\n step: 'refresh',\n title: 'Refresh this page',\n description: 'Refresh the page to connect with Zerion.',\n },\n ],\n },\n },\n createConnector: (walletDetails) =>\n shouldUseWalletConnect\n ? createConnector((config) => {\n const wcConnector = walletConnect({ projectId, showQrModal: false })(config);\n return {\n ...wcConnector,\n ...walletDetails,\n // Zerion only approves WalletConnect sessions for chains it already\n // knows. RainbowKit connects with chainId = the COTI initial chain,\n // and wagmi's in-connect switchChain then aborts the freshly approved\n // session when Zerion rejects the resulting wallet_addEthereumChain.\n // Connect chain-agnostic instead; NetworkGuard pushes the COTI chain\n // once the session is established.\n connect: (async function (\n this: unknown,\n parameters: Parameters<typeof wcConnector.connect>[0] = {},\n ) {\n try {\n return await wcConnector.connect.call(this, { ...parameters, chainId: undefined });\n } catch (error) {\n dispatchConnectFailure('zerion', error);\n throw error;\n }\n }) as unknown as typeof wcConnector.connect,\n };\n })\n : createConnector((config) => ({\n ...injected({\n target: {\n id: 'zerion',\n name: 'Zerion',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provider: (window as any).zerionWallet,\n },\n })(config),\n ...walletDetails,\n })),\n };\n};\n","import React, { useState, useCallback } from 'react';\nimport { usePrivacyBridgeContext } from '../context/PrivacyBridgeContext';\n\nexport interface NetworkGuardProps {\n /** App content to render behind the guard when the wallet needs a network switch */\n children?: React.ReactNode;\n}\n\nconst styles = {\n overlay: {\n position: 'fixed' as const,\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.6)',\n backdropFilter: 'blur(4px)',\n zIndex: 50,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '1rem',\n },\n panel: {\n backgroundColor: '#04133D',\n borderRadius: '24px',\n padding: '40px',\n width: '440px',\n maxWidth: '100%',\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n textAlign: 'center' as const,\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)',\n },\n title: {\n fontSize: '24px',\n fontWeight: 700,\n lineHeight: 1.2,\n marginBottom: '12px',\n color: '#ffffff',\n },\n description: {\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '15px',\n lineHeight: 1.6,\n marginBottom: '24px',\n },\n warningBox: {\n width: '100%',\n backgroundColor: 'rgba(239, 68, 68, 0.1)',\n border: '1px solid rgba(239, 68, 68, 0.3)',\n borderRadius: '12px',\n padding: '12px 16px',\n marginBottom: '24px',\n },\n warningText: {\n fontSize: '13px',\n color: '#f87171',\n lineHeight: 1.5,\n margin: 0,\n },\n button: {\n width: '100%',\n padding: '14px 24px',\n backgroundColor: '#1E29F6',\n color: '#ffffff',\n border: 'none',\n borderRadius: '12px',\n fontSize: '16px',\n fontWeight: 500,\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n },\n buttonDisabled: {\n width: '100%',\n padding: '14px 24px',\n backgroundColor: 'rgba(30, 41, 246, 0.5)',\n color: 'rgba(255, 255, 255, 0.6)',\n border: 'none',\n borderRadius: '12px',\n fontSize: '16px',\n fontWeight: 500,\n cursor: 'not-allowed',\n },\n} as const;\n\n/**\n * Blocks the UI when the connected wallet is unsupported or off the configured target network.\n * Uses {@link usePrivacyBridgeContext} fields wired from {@link useNetworkEnforcer}.\n *\n * Place inside {@link PrivacyBridgeProvider}:\n *\n * ```tsx\n * <PrivacyBridgeProvider>\n * <NetworkGuard>\n * <App />\n * </NetworkGuard>\n * </PrivacyBridgeProvider>\n * ```\n */\nexport const NetworkGuard: React.FC<NetworkGuardProps> = ({ children }) => {\n const {\n isConnected,\n isUnsupportedNetwork,\n isOffTargetNetwork,\n networkMismatchWarning,\n enforceNetwork,\n networkName,\n } = usePrivacyBridgeContext();\n const [isSwitching, setIsSwitching] = useState(false);\n const needsNetworkSwitch = isUnsupportedNetwork || isOffTargetNetwork;\n\n const handleSwitch = useCallback(async () => {\n setIsSwitching(true);\n try {\n await enforceNetwork();\n } finally {\n setIsSwitching(false);\n }\n }, [enforceNetwork]);\n\n if (!isConnected || !needsNetworkSwitch) {\n return <>{children}</>;\n }\n\n const title = isUnsupportedNetwork ? 'Unsupported Network' : 'Switch Network';\n const description = isUnsupportedNetwork\n ? `Your wallet is connected to ${networkName}. Switch to a supported COTI network to continue.`\n : `Your wallet is connected to ${networkName}. Switch to the required network to continue.`;\n\n return (\n <>\n {children}\n <div\n style={styles.overlay}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"network-guard-title\"\n aria-describedby=\"network-guard-description\"\n >\n <div style={styles.panel}>\n <h2 id=\"network-guard-title\" style={styles.title}>\n {title}\n </h2>\n <p id=\"network-guard-description\" style={styles.description}>\n {description}\n </p>\n {networkMismatchWarning && (\n <div style={styles.warningBox}>\n <p style={styles.warningText}>{networkMismatchWarning}</p>\n </div>\n )}\n <button\n type=\"button\"\n onClick={handleSwitch}\n style={isSwitching ? styles.buttonDisabled : styles.button}\n disabled={isSwitching}\n >\n {isSwitching ? 'Switching network…' : 'Switch Network'}\n </button>\n </div>\n </div>\n </>\n );\n};\n\nexport default NetworkGuard;\n"],"mappings":"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","names":["MTT","USDC","P_USDC","PORTAL_USDC","SEPOLIA_CHAIN_ID","COTI_TESTNET_CHAIN_ID","SEPOLIA_CHAIN_ID","COTI_TESTNET_CHAIN_ID","ethers","ethers","portalFee","usedDynamicPricing","quote","gasLimit","quotePodPortalTransactionFees","CotiErrorCode","ethers","ethers","estimatedFeeWei","ethers","ethers","ethers","ethers","ethers","ethers","PodRequest","ethers","chainIdToExplorerSlug","SEPOLIA_CHAIN_ID","COTI_TESTNET_CHAIN_ID","getPodSdkConfig","PodRequest","ethers","SEPOLIA_CHAIN_ID","portalIface","method","portalQuote","podArgs","podFee","gasLimit","tx","receipt","event","ethers","ethers","ethers","fee","ethers","ethers","useCallback","ethers","ethers","useCallback","runner","high","low","ethers","encryptedBalance","useCallback","useRef","ethers","decryptUint","ethers","FLAT_BALANCE_ABI","decryptUint","ethers","FLAT_BALANCE_ABI","validateMetaMaskAesKeyOnUnlock","useRef","useCallback","ethers","useState","useEffect","useCallback","ethers","ethers","ethers","FEE_DIVISOR","useState","useCallback","useEffect","ethers","ethers","ethers","ethers","useState","useCallback","useEffect","useRef","useAccount","ethers","useCallback","useRef","getErrorMessage","COTI_MAINNET_ID","COTI_TESTNET_ID","useRef","useCallback","useState","useRef","useCallback","useEffect","ethers","useAccount","currentAllowance","amountToApprove","useState","useCallback","useAccount","ethers","useState","useAccount","useCallback","ethers","walletAddress","bridgeAbi","network","useMemo","useState","useCallback","useEffect","useRef","useState","useRef","useCallback","useEffect","useState","useCallback","useEffect","useRef","useAccount","ethers","useAccount","useState","useRef","useCallback","injected","ethers","useEffect","useMemo","useEffect","useCallback","useState","useAccount","useState","useEffect","useMemo","useAccount","useAccount","useState","useEffect","useMemo","useAccount","useState","useCallback","useEffect","useMemo","useState","useCallback","useCallback","useEffect","useState","useState","useEffect","useRef","useCallback","useEffect","useRef","useState","useState","useCallback","useRef","useAccount","BrowserProvider","JsonRpcSigner","ethers","ethers","getErrorMessage","result","fallback","sleep","useState","useRef","useAccount","useCallback","provider","BrowserProvider","signer","JsonRpcSigner","errorMessage","useCallback","useMemo","useState","useState","useRef","useCallback","useEffect","useCallback","useMemo","wagmiConfig","useCallback","COTI_MAINNET_ID","COTI_TESTNET_ID","SEPOLIA_ID","useMemo","useCallback","useEffect","useRef","useAccount","useAccount","validateMetaMaskAesKeyOnUnlock","useCallback","useEffect","useRef","useEffect","useRef","useEffect","useRef","useRef","connections","connector","wagmiConfig","useRef","useCallback","useAccount","ethers","ethers","useAccount","useCallback","useRef","useCallback","useEffect","useRef","useState","useState","useRef","useCallback","useEffect","createContext","useContext","useMemo","useCallback","useEffect","useRef","useState","useEffect","useState","muted","p","q","styles","useState","useEffect","Fragment","jsx","jsxs","SPINNER_KEYFRAMES","styles","jsx","useState","useRef","useCallback","useEffect","jsxs","createContext","useMemo","useContext","jsx","useState","useMemo","useMemo","http","injected","isMobileBrowser","injected","createConnector","injected","walletConnect","isMobileBrowser","createConnector","walletConnect","injected","createConnector","injected","walletConnect","isMobileBrowser","createConnector","walletConnect","injected","createConnector","injected","walletConnect","isMobileBrowser","jsx","isMobileBrowser","http","useMemo","useState","useCallback","Fragment","jsx","jsxs","useState","useCallback"]}
|